@@ -12,7 +12,7 @@ use anvil_polkadot::{
1212 api_server:: revive_conversions:: ReviveAddress ,
1313 config:: { AnvilNodeConfig , ForkChoice , SubstrateNodeConfig } ,
1414} ;
15- use polkadot_sdk:: pallet_revive:: evm:: Account ;
15+ use polkadot_sdk:: { pallet_revive:: evm:: Account , sp_blockchain :: HeaderBackend , sp_core :: H256 } ;
1616
1717/// Tests that forking preserves state from the source chain and allows local modifications
1818#[ tokio:: test( flavor = "multi_thread" ) ]
@@ -413,6 +413,64 @@ async fn test_fork_from_negative_block_number() {
413413 assert_eq ! ( fork_new_block, 4 , "Forked node should be at block 4" ) ;
414414}
415415
416+ #[ tokio:: test( flavor = "multi_thread" ) ]
417+ async fn test_fork_from_westend_assethub ( ) {
418+ // Step 1: Set a specific block height to fork from
419+ let fork_block_number = 13268000 ;
420+ let assethub_rpc_url = "https://westend-asset-hub-rpc.polkadot.io" . to_string ( ) ;
421+
422+ // Step 2: Create a forked node from Westend AssetHub at the specific block
423+ let fork_config = AnvilNodeConfig :: test_config ( )
424+ . with_port ( 0 )
425+ . with_eth_rpc_url ( Some ( assethub_rpc_url. clone ( ) ) )
426+ . with_fork_block_number ( Some ( fork_block_number as u64 ) ) ;
427+
428+ let fork_substrate_config = SubstrateNodeConfig :: new ( & fork_config) ;
429+
430+ // Step 3: Verify the forked node can start successfully
431+ let mut fork_node = match TestNode :: new ( fork_config. clone ( ) , fork_substrate_config) . await {
432+ Ok ( node) => node,
433+ Err ( e) => {
434+ panic ! ( "Failed to start forked node from AssetHub: {e}" ) ;
435+ }
436+ } ;
437+
438+ // Step 4: Get the initial block number from the fork
439+ let fork_initial_block = fork_node. best_block_number ( ) . await ;
440+
441+ // Verify the fork started at the expected block number
442+ assert_eq ! (
443+ fork_initial_block, fork_block_number,
444+ "Fork should start from block {fork_block_number}"
445+ ) ;
446+
447+ // Step 5: Query AssetHub to get expected block hash
448+ let rpc_client = fork_node
449+ . service
450+ . backend
451+ . rpc ( )
452+ . expect ( "Fork mode should have RPC client configured" ) ;
453+
454+ let expected_block_hash: H256 = rpc_client
455+ . block_hash ( Some ( fork_block_number) )
456+ . expect ( "Failed to get block hash from AssetHub RPC" )
457+ . expect ( "Block not found on AssetHub" ) ;
458+
459+ // Step 6: Get the Substrate block hash from the forked node's client
460+ let fork_substrate_hash = fork_node
461+ . service
462+ . client
463+ . hash ( fork_initial_block)
464+ . expect ( "Failed to get block hash" )
465+ . expect ( "Block should exist" ) ;
466+
467+ // Step 7: Verify the fork's Substrate block hash matches the expected hash from AssetHub
468+ assert_eq ! (
469+ fork_substrate_hash, expected_block_hash,
470+ "Fork Substrate block hash should match AssetHub block hash at block {fork_block_number}"
471+ ) ;
472+ }
473+
416474/// Tests that forking preserves contract state from source chain and that multiple contract
417475/// instances maintain independent storage
418476#[ tokio:: test( flavor = "multi_thread" ) ]
0 commit comments