From 92542ec499171b8b24501a72e2ecd4bde7647ad2 Mon Sep 17 00:00:00 2001 From: Herman Obst Demaestri <70286869+HermanObst@users.noreply.github.com> Date: Wed, 25 Sep 2024 15:02:19 -0300 Subject: [PATCH 1/2] Test: add pie validity check to prove block (#383) * add pie validity check to prove block * use expect instead of assert * fix error msg * add pie validity check to all integration tests * fix clippy --- Cargo.toml | 2 +- crates/bin/prove_block/tests/prove_block.rs | 6 ++++-- tests/integration/common/transaction_utils.rs | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eec0b155..5ab27df0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ cairo-lang-starknet-classes = { version = "=2.7.1" } cairo-lang-utils = { version = "=2.7.1" } cairo-lang-casm = { version = "=2.7.1" } cairo-type-derive = { version = "0.1.0", path = "crates/cairo-type-derive" } -cairo-vm = { git = "https://github.com/Moonsong-Labs/cairo-vm", branch = "notlesh/segment-arena-relocation-fix", features = ["cairo-1-hints", "extensive_hints", "mod_builtin"] } +cairo-vm = { git = "https://github.com/Moonsong-Labs/cairo-vm", rev = "56b68b50944ecb3123a168218ea7b8b8e23f9be8", features = ["cairo-1-hints", "extensive_hints", "mod_builtin"] } clap = { version = "4.5.4", features = ["derive"] } c-kzg = { version = "1.0.3" } env_logger = "0.11.3" diff --git a/crates/bin/prove_block/tests/prove_block.rs b/crates/bin/prove_block/tests/prove_block.rs index 0e3e483b..112db50c 100644 --- a/crates/bin/prove_block/tests/prove_block.rs +++ b/crates/bin/prove_block/tests/prove_block.rs @@ -47,8 +47,10 @@ use rstest::rstest; #[tokio::test(flavor = "multi_thread")] async fn test_prove_selected_blocks(#[case] block_number: u64) { let endpoint = std::env::var("PATHFINDER_RPC_URL").expect("Missing PATHFINDER_RPC_URL in env"); - prove_block(block_number, &endpoint, LayoutName::all_cairo) + let (pie, _output) = prove_block(block_number, &endpoint, LayoutName::all_cairo) .await .map_err(debug_prove_error) - .expect("Block could not be proven"); + .expect("OS failed to generate Cairo Pie"); + + pie.run_validity_checks().expect("Cairo Pie run validity checks failed"); } diff --git a/tests/integration/common/transaction_utils.rs b/tests/integration/common/transaction_utils.rs index c3bf1766..f4ad6de7 100644 --- a/tests/integration/common/transaction_utils.rs +++ b/tests/integration/common/transaction_utils.rs @@ -920,7 +920,9 @@ where Err(_) => { println!("exception:\n{:#?}", result); } - _ => {} + Ok((pie, _output)) => { + pie.run_validity_checks().expect("Validity check failed"); + } } result From 6d85daa2ed9c2664df1c31c359cde7f385d9105a Mon Sep 17 00:00:00 2001 From: ftheirs Date: Thu, 26 Sep 2024 18:34:05 -0300 Subject: [PATCH 2/2] Fix inconsistent class hash (#385) * add test for class_hash recomputation * class hash test with Pathfinder classes WIP * class hash test with Pathfinder classes * fix(hash_tests): fix constructor ABI entry conversion * fix(hash_tests): entry point offsets use decimal representation in ABI * chore(pyproject.toml): force use of sympy 1.12 The compiler does not work with sympy 1.13. * add blocks with cairo0 contracts to CI * fix: LegacyContractClass decompression * clean up * add recompute class hash to CI * remove unnecesary deps --------- Co-authored-by: Krisztian Kovacs --- .github/workflows/prove_blocks.yml | 6 +++ crates/bin/prove_block/tests/hash_tests.rs | 37 +++++++++++++++++++ crates/bin/prove_block/tests/prove_block.rs | 2 + .../src/starknet_core_addons.rs | 25 +++++++------ pyproject.toml | 2 +- 5 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 crates/bin/prove_block/tests/hash_tests.rs diff --git a/.github/workflows/prove_blocks.yml b/.github/workflows/prove_blocks.yml index 5b423885..55401a2a 100644 --- a/.github/workflows/prove_blocks.yml +++ b/.github/workflows/prove_blocks.yml @@ -51,3 +51,9 @@ jobs: PATHFINDER_RPC_URL: ${{ secrets.PATHFINDER_RPC_URL }} run: | cargo test --release --package prove_block --test prove_block -- test_prove_selected_blocks --show-output --ignored + + - name: Class hashes + env: + PATHFINDER_RPC_URL: ${{ secrets.PATHFINDER_RPC_URL }} + run: | + cargo test --release --package prove_block --test hash_tests -- test_recompute_class_hash --show-output --ignored diff --git a/crates/bin/prove_block/tests/hash_tests.rs b/crates/bin/prove_block/tests/hash_tests.rs new file mode 100644 index 00000000..faab40f4 --- /dev/null +++ b/crates/bin/prove_block/tests/hash_tests.rs @@ -0,0 +1,37 @@ +use rpc_client::RpcClient; +use rstest::rstest; +use starknet::core::types::BlockId; +use starknet::providers::Provider; +use starknet_os_types::compiled_class::GenericCompiledClass; +use starknet_os_types::deprecated_compiled_class::GenericDeprecatedCompiledClass; +use starknet_types_core::felt::Felt; + +#[rstest] +// Contract address 0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf +#[case::correct_hash_computation_0("0x07b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69", 78720)] +// Contract address 0x7a3c142b1ef242f093642604c2ac2259da0efa3a0517715c34a722ba2ecd048 +#[case::correct_hash_computation_1("0x5c478ee27f2112411f86f207605b2e2c58cdb647bac0df27f660ef2252359c6", 30000)] +#[ignore = "Requires a running Pathfinder node"] +#[tokio::test(flavor = "multi_thread")] +async fn test_recompute_class_hash(#[case] class_hash_str: String, #[case] block_number: u64) { + let endpoint = std::env::var("PATHFINDER_RPC_URL").expect("Missing PATHFINDER_RPC_URL in env"); + let class_hash = Felt::from_hex(&class_hash_str).unwrap(); + let block_id = BlockId::Number(block_number); + + let rpc_client = RpcClient::new(&endpoint); + let contract_class = rpc_client.starknet_rpc().get_class(block_id, class_hash).await.unwrap(); + + let compiled_class = if let starknet::core::types::ContractClass::Legacy(legacy_cc) = contract_class { + let compiled_class = GenericDeprecatedCompiledClass::try_from(legacy_cc).unwrap(); + GenericCompiledClass::Cairo0(compiled_class) + } else { + panic!("Test intended to test Legacy contracts"); + }; + + let recomputed_class_hash = Felt::from(compiled_class.class_hash().unwrap()); + + println!("Class hash: {:#x}", class_hash); + println!("Recomputed class hash: {:#x}", recomputed_class_hash); + + assert_eq!(class_hash, recomputed_class_hash); +} diff --git a/crates/bin/prove_block/tests/prove_block.rs b/crates/bin/prove_block/tests/prove_block.rs index 112db50c..db2b3a16 100644 --- a/crates/bin/prove_block/tests/prove_block.rs +++ b/crates/bin/prove_block/tests/prove_block.rs @@ -43,6 +43,8 @@ use rstest::rstest; #[case::declare_and_deploy_in_same_block(169206)] #[case::dest_ptr_not_a_relocatable(155140)] #[case::dest_ptr_not_a_relocatable_2(155830)] +#[case::inconsistent_cairo0_class_hash_0(30000)] +#[case::inconsistent_cairo0_class_hash_1(204936)] #[ignore = "Requires a running Pathfinder node"] #[tokio::test(flavor = "multi_thread")] async fn test_prove_selected_blocks(#[case] block_number: u64) { diff --git a/crates/starknet-os-types/src/starknet_core_addons.rs b/crates/starknet-os-types/src/starknet_core_addons.rs index 20e2b1ac..1029f3d3 100644 --- a/crates/starknet-os-types/src/starknet_core_addons.rs +++ b/crates/starknet-os-types/src/starknet_core_addons.rs @@ -3,8 +3,8 @@ use std::io::Read; use flate2::read::GzDecoder; use starknet_core::types::contract::legacy::{ - LegacyContractClass, LegacyEntrypointOffset, RawLegacyAbiEntry, RawLegacyEntryPoint, RawLegacyEntryPoints, - RawLegacyEvent, RawLegacyFunction, RawLegacyL1Handler, RawLegacyMember, RawLegacyStruct, + LegacyContractClass, LegacyEntrypointOffset, RawLegacyAbiEntry, RawLegacyConstructor, RawLegacyEntryPoint, + RawLegacyEntryPoints, RawLegacyEvent, RawLegacyFunction, RawLegacyL1Handler, RawLegacyMember, RawLegacyStruct, }; use starknet_core::types::{ CompressedLegacyContractClass, LegacyContractAbiEntry, LegacyContractEntryPoint, LegacyEntryPointsByType, @@ -13,14 +13,17 @@ use starknet_core::types::{ fn raw_abi_entry_from_legacy_function_abi_entry(entry: LegacyFunctionAbiEntry) -> RawLegacyAbiEntry { match entry.r#type { - LegacyFunctionAbiType::Function | LegacyFunctionAbiType::Constructor => { - RawLegacyAbiEntry::Function(RawLegacyFunction { - inputs: entry.inputs, - name: entry.name, - outputs: entry.outputs, - state_mutability: entry.state_mutability, - }) - } + LegacyFunctionAbiType::Function => RawLegacyAbiEntry::Function(RawLegacyFunction { + inputs: entry.inputs, + name: entry.name, + outputs: entry.outputs, + state_mutability: entry.state_mutability, + }), + LegacyFunctionAbiType::Constructor => RawLegacyAbiEntry::Constructor(RawLegacyConstructor { + inputs: entry.inputs, + name: entry.name, + outputs: entry.outputs, + }), LegacyFunctionAbiType::L1Handler => RawLegacyAbiEntry::L1Handler(RawLegacyL1Handler { inputs: entry.inputs, name: entry.name, @@ -53,7 +56,7 @@ fn raw_legacy_abi_entry_from_legacy_contract_abi_entry( fn raw_legacy_entrypoint_from_legacy_entrypoint(legacy_entry_point: LegacyContractEntryPoint) -> RawLegacyEntryPoint { RawLegacyEntryPoint { - offset: LegacyEntrypointOffset::U64AsHex(legacy_entry_point.offset), + offset: LegacyEntrypointOffset::U64AsInt(legacy_entry_point.offset), selector: legacy_entry_point.selector, } } diff --git a/pyproject.toml b/pyproject.toml index 22f0774e..b297a586 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ readme = "README.md" python = "^3.9" ecdsa = "^0.18.0" fastecdsa = "^2.3.0" -sympy = "^1.12" +sympy = "~1.12" cairo-lang = "0.13.1" [build-system]