diff --git a/Cargo.lock b/Cargo.lock index 0b1a618..6df7a92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2815,6 +2815,7 @@ name = "unit_tests" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.13.1", "colored", "env_logger", "flate2", diff --git a/unit_tests/tests/test_get_class_hash_at.rs b/unit_tests/tests/test_get_class_hash_at.rs index 4437eee..a1c98c1 100644 --- a/unit_tests/tests/test_get_class_hash_at.rs +++ b/unit_tests/tests/test_get_class_hash_at.rs @@ -85,21 +85,20 @@ async fn fail_non_existing_contract(clients: HashMap>) { let deoxys = &clients[DEOXYS]; let pathfinder = &clients[PATHFINDER]; let class_hash_deoxys = deoxys .get_class_hash_at( - BlockId::Tag(BlockTag::Latest), + BlockId::Number(200000), FieldElement::from_hex_be(STARKGATE_ETH_CONTRACT_ADDR).unwrap(), ) .await .expect("Error waiting for response from Deoxys node"); let class_hash_pathfinder = pathfinder .get_class_hash_at( - BlockId::Tag(BlockTag::Latest), + BlockId::Number(200000), FieldElement::from_hex_be(STARKGATE_ETH_CONTRACT_ADDR).unwrap(), ) .await diff --git a/unit_tests/tests/test_get_state_update.rs b/unit_tests/tests/test_get_state_update.rs index b1a6768..cd46deb 100644 --- a/unit_tests/tests/test_get_state_update.rs +++ b/unit_tests/tests/test_get_state_update.rs @@ -3,10 +3,36 @@ mod common; use common::*; -use starknet_core::types::{BlockId, StarknetError}; +use starknet_core::types::{BlockId, BlockTag, MaybePendingStateUpdate, StarknetError, StateUpdate}; use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use std::collections::HashMap; +pub fn extract_and_sort_state_update(maybe_update: MaybePendingStateUpdate) -> Option { + match maybe_update { + MaybePendingStateUpdate::Update(state_update) => Some(sort_state_update(state_update)), + MaybePendingStateUpdate::PendingUpdate(_) => None, // or handle pending update if necessary + } +} + +pub fn sort_state_update(state_update: StateUpdate) -> StateUpdate { + let mut sorted_state_update = state_update.clone(); + let state_diff = &mut sorted_state_update.state_diff; + let storage_diffs = &mut state_diff.storage_diffs; + + for storage_diff in storage_diffs.iter_mut() { + storage_diff.storage_entries.sort_by_key(|x| x.key); + } + + storage_diffs.sort_by_key(|x| x.address); + state_diff.deprecated_declared_classes.sort(); + state_diff.declared_classes.sort_by_key(|x| x.class_hash); + state_diff.deployed_contracts.sort_by_key(|x| x.address); + state_diff.replaced_classes.sort_by_key(|x| x.contract_address); + state_diff.nonces.sort_by_key(|x| x.contract_address); + + sorted_state_update +} + /// Test for the `get_state_update` Deoxys RPC method /// # Arguments // * `block_id` - The block id to get the state update from @@ -41,14 +67,142 @@ async fn fail_non_existing_block(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + let juno = &clients[JUNO]; + + let block_number = BlockId::Number(0); + + let response_deoxys = deoxys + .get_state_update(block_number) + .await + .expect("Deoxys : Error while getting the state update"); + let response_pathfinder = pathfinder + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + let response_juno = juno + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + + let sorted_deoxys = extract_and_sort_state_update(response_deoxys); + let sorted_pathfinder = extract_and_sort_state_update(response_pathfinder); + let sorted_juno = extract_and_sort_state_update(response_juno); + + assert_eq!(sorted_deoxys, sorted_pathfinder, "The sorted responses do not match"); + assert_eq!(sorted_deoxys, sorted_juno, "The sorted responses do not match"); + assert_eq!(sorted_juno, sorted_pathfinder, "The sorted responses do not match"); +} + #[rstest] #[tokio::test] async fn work_existing_block(clients: HashMap>) { let deoxys = &clients[DEOXYS]; let pathfinder = &clients[PATHFINDER]; + let juno = &clients[JUNO]; + + let block_number = BlockId::Number(250000); + + let response_deoxys = deoxys + .get_state_update(block_number) + .await + .expect("Deoxys : Error while getting the state update"); + let response_pathfinder = pathfinder + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + let response_juno = juno + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + + // Extract and sort the updates + let sorted_deoxys = extract_and_sort_state_update(response_deoxys); + let sorted_pathfinder = extract_and_sort_state_update(response_pathfinder); + let sorted_juno = extract_and_sort_state_update(response_juno); + + assert_eq!(sorted_deoxys, sorted_pathfinder, "The sorted responses do not match"); + assert_eq!(sorted_deoxys, sorted_juno, "The sorted responses do not match"); + assert_eq!(sorted_juno, sorted_pathfinder, "The sorted responses do not match"); +} + +#[rstest] +#[tokio::test] +async fn work_loop_existing_block(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + let juno = &clients[JUNO]; + + for i in 0..5 { + let block_number = BlockId::Number(i * 10000); + let response_deoxys = deoxys + .get_state_update(block_number) + .await + .expect("Deoxys : Error while getting the state update"); + let response_pathfinder = pathfinder + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + let response_juno = juno + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + + // Extract and sort the updates + let sorted_deoxys = extract_and_sort_state_update(response_deoxys); + let sorted_pathfinder = extract_and_sort_state_update(response_pathfinder); + let sorted_juno = extract_and_sort_state_update(response_juno); + + assert_eq!(sorted_deoxys, sorted_pathfinder, "The sorted responses do not match"); + assert_eq!(sorted_deoxys, sorted_juno, "The sorted responses do not match"); + assert_eq!(sorted_juno, sorted_pathfinder, "The sorted responses do not match"); + } +} + +#[rstest] +#[tokio::test] +#[ignore = "Pending data is not supported yet"] +async fn work_block_pending(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + let juno = &clients[JUNO]; + + let block_number = BlockId::Tag(BlockTag::Pending); + let response_deoxys = deoxys + .get_state_update(block_number) + .await + .expect("Deoxys : Error while getting the state update"); + let response_pathfinder = pathfinder + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); + let response_juno = juno + .get_state_update(block_number) + .await + .expect("RPC : Error while getting the state update"); - let block_number = BlockId::Number(100); + // Extract and sort the updates + let sorted_deoxys = extract_and_sort_state_update(response_deoxys); + let sorted_pathfinder = extract_and_sort_state_update(response_pathfinder); + let sorted_juno = extract_and_sort_state_update(response_juno); + assert_eq!(sorted_deoxys, sorted_pathfinder, "The sorted responses do not match"); + assert_eq!(sorted_deoxys, sorted_juno, "The sorted responses do not match"); + assert_eq!(sorted_juno, sorted_pathfinder, "The sorted responses do not match"); +} + +#[rstest] +#[tokio::test] +async fn work_block_latest(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + let juno = &clients[JUNO]; + + let block_number = BlockId::Tag(BlockTag::Latest); let response_deoxys = deoxys .get_state_update(block_number) .await @@ -57,6 +211,17 @@ async fn work_existing_block(clients: HashMap