|
| 1 | + |
| 2 | +# This file is part of the Maker Keeper Framework. |
| 3 | + |
| 4 | +# It contains utility functions to handle the initialization and connection |
| 5 | +# to an Ethereum blockchain node. The functions include methods for connecting |
| 6 | +# to primary and backup nodes, and configuring the Web3 connection. |
| 7 | +# |
| 8 | +# Functions: |
| 9 | +# - initialize_blockchain_connection: Initializes the blockchain connection using primary and backup nodes. |
| 10 | +# - connect_to_primary_node: Connects to the primary Ethereum node. |
| 11 | +# - connect_to_backup_node: Connects to the backup Ethereum node. |
| 12 | +# - connect_to_node: Connects to an Ethereum node given its URL and timeout settings. |
| 13 | +# - configure_web3: Configures the Web3 connection with a private key and logs the connection status. |
| 14 | +# |
| 15 | +# Usage: |
| 16 | +# Call the initialize function: initialize_blockchain_connection(self) |
| 17 | +# |
| 18 | +# Dependencies: |
| 19 | +# - web3: Web3.py library to interact with Ethereum. |
| 20 | +# - web3.exceptions: Exceptions raised by the Web3.py library. |
| 21 | +# - urllib.parse: Used to parse the URL of the Ethereum node. |
| 22 | +# - logging: Standard Python logging library. |
| 23 | +# - .register_keys: Custom function to register Ethereum keys with Web3. |
| 24 | + |
| 25 | + |
| 26 | +import logging |
| 27 | +from urllib.parse import urlparse |
| 28 | +from web3 import Web3, HTTPProvider |
| 29 | +from web3.exceptions import TimeExhausted |
| 30 | +from .register_keys import register_keys |
| 31 | + |
| 32 | +logger = logging.getLogger() |
| 33 | + |
| 34 | +def initialize_blockchain_connection(keeper): |
| 35 | + """Initialize connection with Ethereum node.""" |
| 36 | + if not connect_to_primary_node(keeper): |
| 37 | + logger.info("Switching to backup node.") |
| 38 | + if not connect_to_backup_node(keeper): |
| 39 | + logger.critical( |
| 40 | + "Error: Couldn't connect to the primary and backup Ethereum nodes." |
| 41 | + ) |
| 42 | + |
| 43 | +def connect_to_primary_node(keeper): |
| 44 | + """Connect to the primary Ethereum node""" |
| 45 | + return connect_to_node( |
| 46 | + keeper, keeper.arguments.rpc_primary_url, keeper.arguments.rpc_primary_timeout, "primary" |
| 47 | + ) |
| 48 | + |
| 49 | +def connect_to_backup_node(keeper): |
| 50 | + """Connect to the backup Ethereum node""" |
| 51 | + return connect_to_node( |
| 52 | + keeper, keeper.arguments.rpc_backup_url, keeper.arguments.rpc_backup_timeout, "backup" |
| 53 | + ) |
| 54 | + |
| 55 | +def connect_to_node(keeper, rpc_url, rpc_timeout, node_type): |
| 56 | + """Connect to an Ethereum node""" |
| 57 | + try: |
| 58 | + _web3 = Web3(HTTPProvider(rpc_url, {"timeout": rpc_timeout})) |
| 59 | + except (TimeExhausted, Exception) as e: |
| 60 | + logger.error(f"Error connecting to Ethereum node: {e}") |
| 61 | + return False |
| 62 | + else: |
| 63 | + if _web3.is_connected(): |
| 64 | + keeper.web3 = _web3 |
| 65 | + keeper.node_type = node_type |
| 66 | + return configure_web3(keeper) |
| 67 | + return False |
| 68 | + |
| 69 | +def configure_web3(keeper): |
| 70 | + """Configure Web3 connection with private key""" |
| 71 | + try: |
| 72 | + keeper.web3.eth.defaultAccount = keeper.arguments.eth_from |
| 73 | + register_keys(keeper.web3, keeper.arguments.eth_key) |
| 74 | + except Exception as e: |
| 75 | + logger.error(f"Error configuring Web3: {e}") |
| 76 | + return False |
| 77 | + else: |
| 78 | + node_hostname = urlparse(keeper.web3.provider.endpoint_uri).hostname |
| 79 | + logger.info(f"Connected to Ethereum node at {node_hostname}") |
| 80 | + return True |
0 commit comments