Skip to content

Commit 20d1fcc

Browse files
committed
add test for fork roots
1 parent 8dd9059 commit 20d1fcc

File tree

1 file changed

+146
-0
lines changed
  • crates/storage/provider/provider/tests

1 file changed

+146
-0
lines changed

crates/storage/provider/provider/tests/fork.rs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,149 @@ async fn post_fork_state_proof_should_not_be_supported() {
398398
let result = state.contract_multiproof(vec![address]);
399399
assert_matches!(result, Err(ProviderError::StateProofNotSupported));
400400
}
401+
402+
#[tokio::test(flavor = "multi_thread")]
403+
async fn pre_fork_state_root() {
404+
let starknet_client = StarknetClient::new(SEPOLIA_RPC_URL.try_into().unwrap());
405+
406+
// always use the latest block number of the forked chain because most nodes may not support
407+
// proofs for too old blocks
408+
//
409+
// we take the previous block because there were some instances where the latest block was not
410+
// available or supported by the node.
411+
let latest_block_number = starknet_client.block_number().await.unwrap().block_number - 1;
412+
let provider_factory =
413+
ForkProviderFactory::new_in_memory(latest_block_number, starknet_client.clone());
414+
let provider = provider_factory.provider();
415+
416+
//////////////////////////////////////////////////////////////////////////////
417+
// latest state
418+
//////////////////////////////////////////////////////////////////////////////
419+
420+
// this will return the latest state exactly at the forked block
421+
let state = provider.latest().unwrap();
422+
423+
//--------------------------------------------------------
424+
// classes root
425+
426+
let actual_classes_root = state.classes_root().unwrap();
427+
let expected_classes_root = starknet_client
428+
.get_storage_proof(latest_block_number.into(), None, None, None)
429+
.await
430+
.map(|res| res.global_roots.classes_tree_root)
431+
.unwrap();
432+
433+
assert_eq!(actual_classes_root, expected_classes_root);
434+
435+
//--------------------------------------------------------
436+
// contracts root
437+
438+
let actual_contracts_root = state.contracts_root().unwrap();
439+
let expected_contracts_root = starknet_client
440+
.get_storage_proof(latest_block_number.into(), None, None, None)
441+
.await
442+
.map(|res| res.global_roots.contracts_tree_root)
443+
.unwrap();
444+
445+
assert_eq!(actual_contracts_root, expected_contracts_root);
446+
447+
//--------------------------------------------------------
448+
// contract storage root
449+
450+
let contract1 = address!("0x049D36570D4e46f48e99674bd3fcc84644DdD6b96F7C741B1562B82f9e004dC7"); // Ether Token
451+
let contract2 = address!("0x04718f5a0Fc34cC1AF16A1cdee98fFB20C31f5cD61D6Ab07201858f4287c938D"); // Starknet Token
452+
let contract3 = address!("0x053C91253BC9682c04929cA02ED00b3E423f6710D2ee7e0D5EBB06F3eCF368A8"); // USDC Token
453+
454+
let actual_contract1_root = state.storage_root(contract1).unwrap().unwrap();
455+
let actual_contract2_root = state.storage_root(contract2).unwrap().unwrap();
456+
let actual_contract3_root = state.storage_root(contract3).unwrap().unwrap();
457+
458+
let (expected_contract1_root, expected_contract2_root, expected_contract3_root) =
459+
starknet_client
460+
.get_storage_proof(
461+
latest_block_number.into(),
462+
None,
463+
Some(vec![contract1, contract2, contract3]),
464+
None,
465+
)
466+
.await
467+
.map(|res| {
468+
(
469+
// the leave must be ordered based on the order of the contracts in the request
470+
res.contracts_proof.contract_leaves_data[0].storage_root,
471+
res.contracts_proof.contract_leaves_data[1].storage_root,
472+
res.contracts_proof.contract_leaves_data[2].storage_root,
473+
)
474+
})
475+
.unwrap();
476+
477+
assert_eq!(actual_contract1_root, expected_contract1_root);
478+
assert_eq!(actual_contract2_root, expected_contract2_root);
479+
assert_eq!(actual_contract3_root, expected_contract3_root);
480+
481+
//////////////////////////////////////////////////////////////////////////////
482+
// historical state
483+
//////////////////////////////////////////////////////////////////////////////
484+
485+
// this will return the latest state exactly at the forked block
486+
let historical_block = latest_block_number - 5;
487+
let state = provider.historical(historical_block.into()).unwrap().unwrap();
488+
489+
//--------------------------------------------------------
490+
// classes root
491+
492+
let actual_classes_root = state.classes_root().unwrap();
493+
let expected_classes_root = starknet_client
494+
.get_storage_proof(historical_block.into(), None, None, None)
495+
.await
496+
.map(|res| res.global_roots.classes_tree_root)
497+
.unwrap();
498+
499+
assert_eq!(actual_classes_root, expected_classes_root);
500+
501+
//--------------------------------------------------------
502+
// contracts root
503+
504+
let actual_contracts_root = state.contracts_root().unwrap();
505+
let expected_contracts_root = starknet_client
506+
.get_storage_proof(historical_block.into(), None, None, None)
507+
.await
508+
.map(|res| res.global_roots.contracts_tree_root)
509+
.unwrap();
510+
511+
assert_eq!(actual_contracts_root, expected_contracts_root);
512+
513+
//--------------------------------------------------------
514+
// contract storage root
515+
516+
let contract1 = address!("0x049D36570D4e46f48e99674bd3fcc84644DdD6b96F7C741B1562B82f9e004dC7"); // Ether Token
517+
let contract2 = address!("0x04718f5a0Fc34cC1AF16A1cdee98fFB20C31f5cD61D6Ab07201858f4287c938D"); // Starknet Token
518+
let contract3 = address!("0x053C91253BC9682c04929cA02ED00b3E423f6710D2ee7e0D5EBB06F3eCF368A8"); // USDC Token
519+
520+
let actual_contract1_root = state.storage_root(contract1).unwrap().unwrap();
521+
let actual_contract2_root = state.storage_root(contract2).unwrap().unwrap();
522+
let actual_contract3_root = state.storage_root(contract3).unwrap().unwrap();
523+
524+
let (expected_contract1_root, expected_contract2_root, expected_contract3_root) =
525+
starknet_client
526+
.get_storage_proof(
527+
historical_block.into(),
528+
None,
529+
Some(vec![contract1, contract2, contract3]),
530+
None,
531+
)
532+
.await
533+
.map(|res| {
534+
(
535+
// the leave must be ordered based on the order of the contracts in the request
536+
res.contracts_proof.contract_leaves_data[0].storage_root,
537+
res.contracts_proof.contract_leaves_data[1].storage_root,
538+
res.contracts_proof.contract_leaves_data[2].storage_root,
539+
)
540+
})
541+
.unwrap();
542+
543+
assert_eq!(actual_contract1_root, expected_contract1_root);
544+
assert_eq!(actual_contract2_root, expected_contract2_root);
545+
assert_eq!(actual_contract3_root, expected_contract3_root);
546+
}

0 commit comments

Comments
 (0)