This repository contains a Python script that simulates the behavior of a validator or oracle node for a cross-chain bridge. It listens for specific events on a source blockchain, waits for transaction finality, and then simulates the corresponding action on a destination blockchain.
This project is designed as an architectural showcase, demonstrating principles of modular design, error handling, and state management in a decentralized context. It is not a production-ready bridge component but a comprehensive simulation.
A cross-chain bridge allows users to transfer assets or data from one blockchain (e.g., Ethereum) to another (e.g., Polygon). A common mechanism for this is "lock-and-mint":
- Lock/Deposit: A user deposits tokens into a smart contract on the source chain. This action emits an event (e.g.,
TokensDeposited). - Validation: A network of off-chain nodes (listeners, validators, or oracles) listens for this event.
- Confirmation: The nodes wait for several blocks to be mined on top of the transaction block to ensure it's final and not part of a chain reorganization (re-org).
- Mint/Release: Once confirmed, the nodes submit a transaction to a smart contract on the destination chain, authorizing the minting or release of equivalent wrapped tokens to the user's address.
This script simulates the role of one such off-chain validator node (Step 2, 3, and 4).
The script is structured into several distinct classes, each with a clear responsibility, to ensure modularity and maintainability.
-
BlockchainConnector:- Responsibility: Manages the connection to a single blockchain via a Web3 RPC endpoint.
- Key Methods:
connect(),is_connected(),get_latest_block(). - Purpose: Abstracts away the low-level connection logic, making it reusable for both the source and destination chains.
-
CrossChainTransaction:- Responsibility: Acts as a data container for a single cross-chain transfer.
- Attributes: Stores all relevant information from the deposit event, such as sender, recipient, amount, and its current
status(e.g.,PENDING_CONFIRMATION,COMPLETED,FAILED). - Purpose: Provides a structured way to manage the state of each transfer as it moves through the pipeline.
-
BridgeListenerService(main class, inherits fromthreading.Thread):- Responsibility: The core orchestrator of the application.
- Key Logic: Contains the main processing loop that:
- Fetches new deposit events from the source chain.
- Manages a queue of
CrossChainTransactionobjects. - Processes pending transactions by checking for finality.
- Triggers the simulated minting process on the destination chain.
- Purpose: Acts as the entry point and control center, tying all other components together.
The listener operates in a continuous cycle, orchestrated by the BridgeListenerService:
-
Initialization: Upon starting, the service initializes
BlockchainConnectorinstances for both the source and destination chains. It uses RPC URLs provided in a.envfile. -
Event Polling: In its main loop, the service uses a Web3 filter to poll the source chain's bridge contract for new
TokensDepositedevents. To prevent duplicate processing, it keeps track of processed transaction nonces. -
State Management: When a new event is detected, it is encapsulated in a
CrossChainTransactionobject with an initial status ofPENDING_CONFIRMATION. This object is added to a pending transactions dictionary. -
Confirmation Check: For each pending transaction, the service compares the transaction's block number with the latest block number on the source chain. If the difference is greater than or equal to a configured threshold (
confirmation_blocks), the transaction is considered final, and its status is updated toCONFIRMED_SOURCE. -
Simulated Submission: Once a transaction is confirmed, the service calls the
_simulate_mint_on_destinationmethod. This method does not send a real transaction but logs the actions that a real validator would take. It includes logic to simulate network failures and retries, demonstrating resilience. -
Lifecycle Completion: After a successful simulated submission, the transaction's status is set to
COMPLETED. If it fails after multiple retries, it is marked asFAILED. Completed and failed transactions are then removed from the pending queue to free up memory. -
Graceful Shutdown: The service can be stopped gracefully, allowing the main loop to finish its current cycle before exiting.
Follow these steps to run the simulation.
Clone the repository and navigate into the project directory.
git clone https://github.com/your-username/basegame.git
cd basegameCreate a .env file in the root of the project. This file will store your blockchain RPC URLs. You can get these from services like Infura, Alchemy, or public providers.
File: .env
# RPC URL for the source chain (e.g., Ethereum Sepolia Testnet)
SOURCE_CHAIN_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_PROJECT_ID
# RPC URL for the destination chain (e.g., Polygon Mumbai Testnet)
DESTINATION_CHAIN_RPC_URL=https://polygon-mumbai.infura.io/v3/YOUR_INFURA_PROJECT_ID
Install the required Python libraries using the requirements.txt file.
pip install -r requirements.txtExecute the main Python script from your terminal.
python bridge_listener.pyThe script will start, connect to the specified chains, and begin polling for events. Since the contract addresses are placeholders, it will not find any real events. However, it will continuously log its status, demonstrating that the polling mechanism is active.
Example Output:
2023-10-27 10:30:00,123 - INFO - [MainThread] - Successfully connected to SourceChain (Sepolia) at https://rpc.sepolia.org
2023-10-27 10:30:01,456 - INFO - [MainThread] - Successfully connected to DestinationChain (Mumbai) at https://rpc-mumbai.maticvigil.com
2023-10-27 10:30:01,457 - INFO - [BridgeListenerThread] - Starting Bridge Listener Service. Polling every 15 seconds.
2023-10-27 10:30:01,457 - DEBUG - [BridgeListenerThread] - Starting new processing cycle...
2023-10-27 10:30:03,812 - DEBUG - [BridgeListenerThread] - Processing cycle finished.
2023-10-27 10:30:18,815 - DEBUG - [BridgeListenerThread] - Starting new processing cycle...
2023-10-27 10:30:20,111 - DEBUG - [BridgeListenerThread] - Processing cycle finished.
...