Skip to content

Conversation

@dimartiro
Copy link

Description

This PR enables forking from production chains like Westend Asset Hub by implementing dynamic transaction building and batch storage prefetching to address pallet index mismatches and reduce RPC latency.

Changes

Dynamic Transaction Building

When forking from a chain with a different runtime configuration, the hardcoded pallet index used by subxt_client::tx().revive().eth_transact() may not match the forked chain's pallet ordering, causing transaction failures. This PR introduces dynamic transaction building using subxt's dynamic_tx() which reads pallet indices from the runtime metadata at execution time, ensuring correct encoding regardless of the forked chain's configuration.

Batch Storage Prefetching

Each storage read from a remote chain requires an individual RPC call, causing significant latency during transaction validation. This PR implements batch prefetching using state_queryStorageAt to fetch multiple storage keys in a single RPC call. Before validating an Ethereum transaction, the sender's account info is prefetched to avoid sequential RPC round-trips.

Tests

  • Updated test URL from local zombienet to real Westend Asset Hub RPC endpoint
  • Added send_transaction_and_wait() and deploy_contract_and_wait() helpers that poll for transaction receipts with configurable timeouts, essential for reliable testing against remote networks with variable block times
  • Removed forking-tests feature flag - forking tests now run without special configuration

All forking tests pass against real Westend Asset Hub

@alindima
Copy link

how big of a difference are we talking for this batched prefetch?

btw, I ran into this warn when trying to view past blocks in polkadot.js (blocks built locally after forking)

Expected block 0x1799f073ea35caec8c1cf5c81bc0965d94f2e2b920e83d2cb2ff6c946058d59e to exist

and the block explorer hangs

@dimartiro
Copy link
Author

dimartiro commented Jan 22, 2026

how big of a difference are we talking for this batched prefetch?

Let me execute a small benchmark

btw, I ran into this warn when trying to view past blocks in polkadot.js (blocks built locally after forking)

Expected block 0x1799f073ea35caec8c1cf5c81bc0965d94f2e2b920e83d2cb2ff6c946058d59e to exist

and the block explorer hangs

I'll take a look

* reset

* override slot in inherent

* create digest provider from client

* encode vs to_vec, clean

* refactor timestamp, remove unused fork args

* remove comments from substrate runtime

* use next timestamp

* allow for flexible block times

* clean up

* remove consensus file

* support no mine mode

* clean up and testing

* update backend errors

* improved error messages

* add error handling to inherent data providers

* update slot

* rebase wip/fix build

* temp/fix build

* fmt

* fix non forking

* query runtime if chain_id not found

* lock

* get eth chain id rather than parachain id

* cache chain id rather than write to backend

* clean chain_id naming

* consistancy with fork checkpoint

* fix chain id method naming

* support local nodes for subxt

* Initial integration tests using zombienet

* Add more integration tests using zombienet

* Fix clippy

* Fix fmt

* Put forking tests under a feature

* Fmt

* Fix clippy

* fix: convert https URLs to wss instead of ws for fork RPC

* refactor: remove unnecessary thread spawn in service::new

* Improve forking tests comments

* use e notation for ether amounts in tests

* remove unnecesary test

* Merge test_fork_can_deploy_contract_from_westend into test_fork_eth_get_code_from_westend test

* Add assert to check block number is increased

* Remove unnecesary sleep

---------

Co-authored-by: Jimmy Johnson <[email protected]>
Co-authored-by: Diego <[email protected]>
@alindima
Copy link

btw, I ran into this warn when trying to view past blocks in polkadot.js (blocks built locally after forking)

Expected block 0x1799f073ea35caec8c1cf5c81bc0965d94f2e2b920e83d2cb2ff6c946058d59e to exist
and the block explorer hangs

I wonder if this was just a hiccup of the RPC provider

@dimartiro
Copy link
Author

@alindima

regarding:

how big of a difference are we talking for this batched prefetch?

Each batched call eliminates some network round-trips, so for 2 keys it's ~2x faster. It's not a big deal for only 2 keys, but the infrastructure is ready to scale to more keys in the future. It helps run tests faster against real Asset Hub and saves time when using it as a development tool

@dimartiro
Copy link
Author

btw, I ran into this warn when trying to view past blocks in polkadot.js (blocks built locally after forking)

Regarding this, I pushed a commit a few minutes ago that I think fixes the issue. At least I can’t reproduce it locally anymore, and polkadot.js is working fine when I navigate through blocks.

@dimartiro dimartiro force-pushed the fix-westend_assethub-forking branch from 30f64b1 to 67a4103 Compare January 27, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants