fork_network
Documentation for eth_defi.provider.ganache.fork_network function.
- fork_network(json_rpc_url, unlocked_addresses=[], cmd='ganache-cli', port=19999, evm_version='london', block_time=0, quiet=False, launch_wait_seconds=20.0)[source]
Creates the ganache “fork” of given JSON-RPC endpoint.
Warning
This function is not recommended due to stability issues with Ganache. Use
eth_defi.anvil.fork_network_anvil()
instead.Forking a mainnet is common way to test against live deployments. This function invokes ganache-cli command and tells it to fork a given JSON-RPC endpoint.
A subprocess is started on the background. To stop this process, call
eth_defi.ganache.GanacheLaunch.close()
. This function waits launch_wait_seconds in order to ganache-cli process to start and complete the chain fork.Note
Currently only supports HTTP JSON-RPC connections.
Warning
Forking a network with ganache-cli is a slow process. It is recommended that you use fast Ethereum Tester based testing if possible.
Here is an example that forks BNB chain mainnet and transfer 500 BUSD stablecoin to a test account we control:
@pytest.fixture() def large_busd_holder() -> HexAddress: # A random account picked from BNB Smart chain that holds a lot of BUSD. # Binance Hot Wallet 6 return HexAddress(HexStr("0x8894E0a0c962CB723c1976a4421c95949bE2D4E3")) @pytest.fixture() def ganache_bnb_chain_fork(large_busd_holder) -> str: # Create a testable fork of live BNB chain. mainnet_rpc = os.environ["BNB_CHAIN_JSON_RPC"] launch = fork_network( mainnet_rpc, unlocked_addresses=[large_busd_holder]) yield launch.json_rpc_url # Wind down Ganache process after the test is complete launch.close() @pytest.fixture def web3(ganache_bnb_chain_fork: str): # Set up a local unit testing blockchain return Web3(HTTPProvider(ganache_bnb_chain_fork)) def test_mainnet_fork_transfer_busd(web3: Web3, large_busd_holder: HexAddress, user_1: LocalAccount): # BUSD deployment on BNB chain # https://bscscan.com/token/0xe9e7cea3dedca5984780bafc599bd69add087d56 busd_details = fetch_erc20_details(web3, "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56") busd = busd_details.contract # Transfer 500 BUSD to the user 1 tx_hash = busd.functions.transfer(user_1.address, 500*10**18).transact({"from": large_busd_holder}) # Because Ganache has instamine turned on by default, we do not need to wait for the transaction receipt = web3.eth.get_transaction_receipt(tx_hash) assert receipt.status == 1, "BUSD transfer reverted" assert busd.functions.balanceOf(user_1.address).call() == 500*10**18
See the full example in tests source code.
Polygon needs to set a specific EVM version:
mainnet_rpc = os.environ["POLYGON_JSON_RPC"] launch = fork_network(mainnet_rpc, evm_version="istanbul")
If ganache-cli refuses to terminate properly, you can kill a process by a port with:
# Kill any process listening to localhost:19999 kill -SIGKILL $(lsof -ti:19999)
This function uses Python logging subsystem. If you want to see error/info/debug logs with pytest you can do:
pytest --log-cli-level=debug
For public JSON-RPC endpoints check
- Parameters
cmd – Override ganache-cli command. If not given we look up from PATH.
json_rpc_url (str) – HTTP JSON-RPC URL of the network we want to fork
unlocked_addresses (List[Union[eth_typing.evm.HexAddress, str]]) – List of addresses of which ownership we take to allow test code to transact as them
port – Localhost port we bind for Ganache JSON-RPC
launch_wait_seconds – How long we wait ganache-cli to start until giving up
evm_version – “london” for the default hard fork
block_time – How long Ganache takes to mine a block. Default is zero and any RPC transaction will immediately return with the transaction inclusion. Set to 1 so that you can poll the transaction as you would do with a live JSON-RPC node.
quiet – Disable extensive logging. If there is a lot of Ganache logging it seems to crash on Github CI.
- Return type