From 60768ccff64588fb3bf4c828f96cfc0cc0f1b4d4 Mon Sep 17 00:00:00 2001 From: Mehul Chauhan Date: Sat, 5 Oct 2024 15:40:17 +0530 Subject: [PATCH] move starknet settlement to zaun (#125) * update dependencies * update imports * updated changelog * added testcase for bytes conversion * fix clippy error * use zaun for starknet * add simple test for settlement * add sepolia issue * to be fixed: validation error * add madara update state test * use relative path * add ci for settlement client * fix workflow debug * fix workflow debug * add scarb build * ignore flaky test * fix threads issue * add scarb build for madara * check if tool version present * fix workflow debug * fix workflwo * fix directory * should fix it * fix bash command * fix bash command * make scarb installation separate step * use swm action * fix ci path * lint fixed * fix env path for tests * fix lint * remove extra path * try checking structure * check * fix env path * fix the directory * try go into * fix path * remove working directory * final fix * fix: gets triggered multiple times * fix path * fix prettier * change calldata type to (#133) * update workflow * fix lints * Update crates/settlement-clients/starknet/src/tests/test.rs Co-authored-by: Apoorv Sadana <95699312+apoorvsadana@users.noreply.github.com> * resolve comments * fix e2e test flow * fix toml lint * Update crates/settlement-clients/starknet/src/tests/test.rs Co-authored-by: Apoorv Sadana <95699312+apoorvsadana@users.noreply.github.com> * changed envs * add conversion function and test * remove redundant test * update workflow commit hash * change commit and add prettierignore * nonce implementaion and optimise code * remove coverage bin env * changed to logs * added preset file * update versioned constants path * fix current_path * should do inplace replacement * fix base path * fix final coverage workflow * update preset * change runner * install dependencies * run linter * remove path * reword * change default rust * rerun * install libclang * install more dependencies * install yq * install via snap * install snap first * add y flag * no y flag * enable snapd service * use gh action for yq * yq action * remove working-directory * check env variable * fix ci * remove override in e2e * dotenvy::from_filename * should also build * env override * ignore flaky test * restart ci * enable cargo build * override in starknet client * only starknet * retry running * test settle should work * remove fail fast * update blocktime * change commit * run all tests * resolve comments * added test for get nonce * remove log --------- Co-authored-by: Apoorv Sadana <95699312+apoorvsadana@users.noreply.github.com> --- .env.example | 6 +- .env.test | 8 +- .github/workflows/coverage.yml | 38 +- .gitignore | 3 +- .prettierignore | 3 +- CHANGELOG.md | 1 + Cargo.lock | 288 ++++++--- Cargo.toml | 9 +- .../da-clients/da-client-interface/src/lib.rs | 8 - crates/orchestrator/src/jobs/da_job/mod.rs | 37 +- crates/orchestrator/src/tests/config.rs | 2 +- .../src/tests/data_storage/mod.rs | 7 +- .../orchestrator/src/tests/jobs/da_job/mod.rs | 4 +- .../src/tests/jobs/state_update_job/mod.rs | 10 +- .../gps-fact-checker/src/fact_info.rs | 9 +- .../sharp-service/tests/lib.rs | 1 + .../settlement-clients/ethereum/src/config.rs | 5 +- crates/settlement-clients/ethereum/src/lib.rs | 9 +- .../settlement-client-interface/src/lib.rs | 9 +- crates/settlement-clients/starknet/Cargo.toml | 8 + .../settlement-clients/starknet/src/config.rs | 5 +- .../starknet/src/conversion.rs | 37 +- crates/settlement-clients/starknet/src/lib.rs | 121 ++-- .../src/tests/mock_contracts/.gitignore | 2 + .../src/tests/mock_contracts/.tool-versions | 2 + .../src/tests/mock_contracts/Scarb.lock | 22 + .../src/tests/mock_contracts/Scarb.toml | 19 + .../src/tests/mock_contracts/src/lib.cairo | 36 ++ .../starknet/src/tests/mod.rs | 2 + .../starknet/src/tests/preset.yml | 34 ++ .../resources/versioned_constants_13_0.json | 509 ++++++++++++++++ .../resources/versioned_constants_13_1.json | 555 +++++++++++++++++ .../resources/versioned_constants_13_1_1.json | 554 +++++++++++++++++ .../resources/versioned_constants_13_2.json | 563 ++++++++++++++++++ .../starknet/src/tests/setup.rs | 176 ++++++ .../starknet/src/tests/test.rs | 185 ++++++ docker-compose.yml | 16 + e2e-tests/tests.rs | 5 +- 38 files changed, 3098 insertions(+), 210 deletions(-) create mode 100644 crates/settlement-clients/starknet/src/tests/mock_contracts/.gitignore create mode 100644 crates/settlement-clients/starknet/src/tests/mock_contracts/.tool-versions create mode 100644 crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.lock create mode 100644 crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.toml create mode 100644 crates/settlement-clients/starknet/src/tests/mock_contracts/src/lib.cairo create mode 100644 crates/settlement-clients/starknet/src/tests/mod.rs create mode 100644 crates/settlement-clients/starknet/src/tests/preset.yml create mode 100644 crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_0.json create mode 100644 crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1.json create mode 100644 crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1_1.json create mode 100644 crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_2.json create mode 100644 crates/settlement-clients/starknet/src/tests/setup.rs create mode 100644 crates/settlement-clients/starknet/src/tests/test.rs create mode 100644 docker-compose.yml diff --git a/.env.example b/.env.example index 4e696edd..c70993de 100644 --- a/.env.example +++ b/.env.example @@ -49,7 +49,11 @@ PRIVATE_KEY= ETHEREUM_PRIVATE_KEY= STARKNET_SOLIDITY_CORE_CONTRACT_ADDRESS= +##### STARKNET SETTLEMENT (L3s) ##### +STARKNET_PRIVATE_KEY= +STARKNET_ACCOUNT_ADDRESS= + ##### Instrumentation ##### OTEL_SERVICE_NAME= OTEL_COLLECTOR_ENDPOINT= -TRACING_LEVEL= \ No newline at end of file +TRACING_LEVEL= diff --git a/.env.test b/.env.test index 63bc6d6f..72ce7542 100644 --- a/.env.test +++ b/.env.test @@ -63,7 +63,13 @@ TEST_DUMMY_CONTRACT_ADDRESS="0xE5b6F5e695BA6E4aeD92B68c4CC8Df1160D69A81" STARKNET_OPERATOR_ADDRESS="0x2C169DFe5fBbA12957Bdd0Ba47d9CEDbFE260CA7" ETHEREUM_BLAST_RPC_URL="https://eth-mainnet.public.blastapi.io" + +##### STARKNET SETTLEMENT TEST ##### +STARKNET_PRIVATE_KEY=0x76f2ccdb23f29bc7b69278e947c01c6160a31cf02c19d06d0f6e5ab1d768b86 +STARKNET_ACCOUNT_ADDRESS=0x3bb306a004034dba19e6cf7b161e7a4fef64bc1078419e8ad1876192f0b8cd1 +MADARA_BINARY_PATH="/path/to/madara" + ## Instrumentation OTEL_SERVICE_NAME="madara_orchestrator" OTEL_COLLECTOR_ENDPOINT="" -TRACING_LEVEL="info" \ No newline at end of file +TRACING_LEVEL="info" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 63e0adb5..e6c2ec01 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -8,7 +8,7 @@ on: jobs: coverage: - runs-on: ubuntu-latest + runs-on: karnot-arc-runner-set services: localstack: @@ -30,7 +30,10 @@ jobs: # selecting a toolchain either by action or manual `rustup` calls should happen # before the plugin, as the cache uses the current rustc version as its cache key - - run: rustup show + - name: Install necessary dependencies + run: | + sudo apt update + sudo apt-get install -y clang llvm libudev-dev protobuf-compiler gcc g++ build-essential libssl-dev pkg-config curl wget git libclang-dev - name: Install Rust toolchain uses: actions-rs/toolchain@v1 @@ -38,6 +41,7 @@ jobs: profile: minimal toolchain: stable override: true + default: true - name: Rust Cache uses: Swatinem/rust-cache@v2 @@ -62,6 +66,34 @@ jobs: - name: Install nextest uses: taiki-e/install-action@nextest + - name: Setup scarb + uses: software-mansion/setup-scarb@v1 + with: + scarb-version: "2.8.2" + + - name: Build Mock Contracts using Scarb + run: | + cd crates/settlement-clients/starknet/src/tests/mock_contracts + scarb fmt --check + scarb build + + - name: Checkout Madara + uses: actions/checkout@v4 + with: + repository: madara-alliance/madara + ref: "0c821aecd1cafc516d00548473fcaddaa4dc0ce4" + path: madara + + - name: Build Madara + working-directory: madara + run: | + cargo build + mv target/debug/madara ../madara-binary + cd .. + echo -e " + MADARA_BINARY_PATH=\"$(pwd)/madara-binary\"" >> .env.test + cat .env.test + - name: Getting neccesary files for testing run: | wget -P ./crates/prover-services/sharp-service/tests/artifacts https://madara-orchestrator-sharp-pie.s3.amazonaws.com/238996-SN.zip @@ -69,7 +101,7 @@ jobs: - name: Run llvm-cov tests env: ETHEREUM_BLAST_RPC_URL: ${{ secrets.ETHEREUM_BLAST_RPC_URL }} - run: RUST_LOG=debug RUST_BACKTRACE=1 cargo llvm-cov nextest --release --features testing --lcov --output-path lcov.info --test-threads=1 --workspace --exclude=e2e-tests + run: RUST_LOG=debug RUST_BACKTRACE=1 cargo llvm-cov nextest --release --features testing --lcov --output-path lcov.info --test-threads=1 --workspace --exclude=e2e-tests --no-fail-fast - name: Coveralls uses: coverallsapp/github-action@v2 diff --git a/.gitignore b/.gitignore index 12b6524c..f0cfd7ce 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.code-workspace .vscode + lcov.info -**/*-SN.zip \ No newline at end of file +**/*-SN.zip diff --git a/.prettierignore b/.prettierignore index 16add554..46d7d371 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,2 @@ -dashboards \ No newline at end of file +target/ +dashboards diff --git a/CHANGELOG.md b/CHANGELOG.md index 059914ee..d8ea1cce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## Changed +- Bumped dependencies, and associated api changes done - ethereum DA client builder - AWS config built from TestConfigBuilder. - Better TestConfigBuilder, with sync config clients. diff --git a/Cargo.lock b/Cargo.lock index 29782240..96a4da2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1086,9 +1086,51 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "appchain-core-contract-client" +version = "0.1.0" +source = "git+https://github.com/byteZorvin/zaun?branch=type-update#36dc1fc5b2affaee69c669aac97a5062622b43b5" +dependencies = [ + "appchain-utils", + "async-trait", + "color-eyre", + "dirs", + "hex", + "log", + "num-traits 0.2.19", + "serde_json", + "starknet", + "starknet-accounts", + "starknet-core 0.11.1", + "starknet-ff", + "starknet-providers", +] + +[[package]] +name = "appchain-utils" +version = "0.1.0" +source = "git+https://github.com/byteZorvin/zaun?branch=type-update#36dc1fc5b2affaee69c669aac97a5062622b43b5" +dependencies = [ + "async-trait", + "color-eyre", + "hex", + "log", + "num-traits 0.2.19", + "serde_json", + "starknet", + "starknet-accounts", + "starknet-contract", + "starknet-core 0.11.1", + "starknet-ff", + "starknet-providers", + "starknet-signers", + "thiserror", + "url", +] [[package]] name = "ark-ec" @@ -1490,19 +1532,21 @@ dependencies = [ [[package]] name = "async-process" -version = "1.8.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel 2.3.1", + "async-io 2.3.3", + "async-lock 3.4.0", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", + "event-listener 5.3.1", + "futures-lite 2.3.0", "rustix 0.38.34", - "windows-sys 0.48.0", + "tracing", ] [[package]] @@ -1537,21 +1581,21 @@ dependencies = [ [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" dependencies = [ "async-attributes", "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", + "futures-lite 2.3.0", "gloo-timers", "kv-log-macro", "log", @@ -2546,7 +2590,7 @@ checksum = "709d9aa1c37abb89d40f19f5d0ad6f0d88cb1581264e571c9350fc5bb89cf1c5" dependencies = [ "serde", "serde_repr", - "serde_with 3.8.1", + "serde_with 3.9.0", ] [[package]] @@ -3977,7 +4021,7 @@ dependencies = [ "mongodb", "orchestrator", "reqwest 0.12.7", - "rstest 0.18.2", + "rstest 0.22.0", "serde", "serde_json", "starknet", @@ -4093,11 +4137,11 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.66", @@ -4115,9 +4159,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -4194,7 +4238,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "reqwest 0.12.7", - "rstest 0.18.2", + "rstest 0.22.0", "serde", "starknet", "tokio", @@ -4226,7 +4270,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "reqwest 0.12.7", - "rstest 0.18.2", + "rstest 0.22.0", "serde", "settlement-client-interface", "snos", @@ -4260,17 +4304,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - [[package]] name = "event-listener" version = "5.3.1" @@ -4652,9 +4685,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gloo-timers" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -4928,7 +4961,7 @@ dependencies = [ "async-trait", "cfg-if", "data-encoding", - "enum-as-inner 0.6.0", + "enum-as-inner 0.6.1", "futures-channel", "futures-io", "futures-util", @@ -6600,7 +6633,7 @@ dependencies = [ "opentelemetry-stdout", "opentelemetry_sdk", "prover-client-interface", - "rstest 0.18.2", + "rstest 0.22.0", "serde", "serde_json", "settlement-client-interface", @@ -6825,7 +6858,7 @@ dependencies = [ "rand", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.9.0", "sha3", "thiserror", "vergen", @@ -6854,7 +6887,7 @@ dependencies = [ "primitive-types", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.9.0", ] [[package]] @@ -7783,6 +7816,18 @@ dependencies = [ "rustc_version 0.4.0", ] +[[package]] +name = "rstest" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b423f0e62bdd61734b67cd21ff50871dfaeb9cc74f869dcd6af974fbcb19936" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros 0.22.0", + "rustc_version 0.4.0", +] + [[package]] name = "rstest_macros" version = "0.17.0" @@ -7831,6 +7876,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "rstest_macros" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e1711e7d14f74b12a58411c542185ef7fb7f2e7f8ee6e2940a883628522b42" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version 0.4.0", + "syn 2.0.66", + "unicode-ident", +] + [[package]] name = "ruint" version = "1.12.3" @@ -8478,9 +8541,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ "base64 0.22.1", "chrono", @@ -8490,7 +8553,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "serde_with_macros 3.8.1", + "serde_with_macros 3.9.0", "time", ] @@ -8520,9 +8583,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling 0.20.9", "proc-macro2", @@ -8646,7 +8709,7 @@ dependencies = [ "opentelemetry_sdk", "prover-client-interface", "reqwest 0.12.7", - "rstest 0.18.2", + "rstest 0.22.0", "serde", "serde_json", "snos", @@ -8788,7 +8851,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.9.0", "serde_yaml", "starknet-crypto 0.6.2", "starknet-gateway-types", @@ -8867,15 +8930,14 @@ dependencies = [ [[package]] name = "starknet" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f8002bf3d750dd2c0434aca8b5e88e2438cd6c452f4c18f34d0a8a9f42cb1a" +checksum = "1e633a772f59214c296d5037c95c36b72792c9360323818da2b625c7b4ec4b49" dependencies = [ "starknet-accounts", "starknet-contract", - "starknet-core 0.9.0", - "starknet-crypto 0.6.2", - "starknet-ff", + "starknet-core 0.11.1", + "starknet-crypto 0.7.2", "starknet-macros", "starknet-providers", "starknet-signers", @@ -8883,13 +8945,14 @@ dependencies = [ [[package]] name = "starknet-accounts" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e39a5807a735343493781dd5e640c4af838de470b0a73f420bed642fdc2ff1" +checksum = "eee8a6b588a22c7e79f5d8d4e33413387db63a8beb98be8610138541794cc0a5" dependencies = [ "async-trait", "auto_impl", - "starknet-core 0.9.0", + "starknet-core 0.11.1", + "starknet-crypto 0.7.2", "starknet-providers", "starknet-signers", "thiserror", @@ -8897,15 +8960,15 @@ dependencies = [ [[package]] name = "starknet-contract" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4996991356cd0e9499c663680eba7e77de4109e4995f652c1608899a65c09ee" +checksum = "a5f91344f1e0b81873b6dc235c50ae4d084c6ea4dd4a1e3e27ad895803adb610" dependencies = [ "serde", "serde_json", "serde_with 2.3.3", "starknet-accounts", - "starknet-core 0.9.0", + "starknet-core 0.11.1", "starknet-providers", "thiserror", ] @@ -8930,11 +8993,12 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ed286d637e34fb8ae1cd2f9615120ec8ff38d1cffd311ed7fdd497cdd2bd01f" +checksum = "d506e02a4083290d13b427dfe437fd95aa8b56315c455bb2f9cdeca76620d457" dependencies = [ "base64 0.21.7", + "crypto-bigint 0.5.5", "flate2", "hex", "serde", @@ -8942,8 +9006,27 @@ dependencies = [ "serde_json_pythonic", "serde_with 2.3.3", "sha3", - "starknet-crypto 0.6.2", - "starknet-ff", + "starknet-crypto 0.7.2", + "starknet-types-core", +] + +[[package]] +name = "starknet-core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538240cbe6663c673fe77465f294da707080f39678dd7066761554899e46100" +dependencies = [ + "base64 0.21.7", + "crypto-bigint 0.5.5", + "flate2", + "hex", + "serde", + "serde_json", + "serde_json_pythonic", + "serde_with 3.9.0", + "sha3", + "starknet-crypto 0.7.2", + "starknet-types-core", ] [[package]] @@ -8986,6 +9069,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "starknet-crypto" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a5064173a8e8d2675e67744fd07f310de44573924b6b7af225a6bdd8102913" +dependencies = [ + "crypto-bigint 0.5.5", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits 0.2.19", + "rfc6979 0.4.0", + "sha2", + "starknet-curve 0.5.1", + "starknet-types-core", + "zeroize", +] + [[package]] name = "starknet-crypto-codegen" version = "0.3.3" @@ -9015,6 +9117,15 @@ dependencies = [ "starknet-ff", ] +[[package]] +name = "starknet-curve" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" +dependencies = [ + "starknet-types-core", +] + [[package]] name = "starknet-ff" version = "0.3.7" @@ -9026,7 +9137,6 @@ dependencies = [ "crypto-bigint 0.5.5", "getrandom", "hex", - "num-bigint", "serde", ] @@ -9047,7 +9157,7 @@ dependencies = [ "rstest 0.18.2", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.9.0", "sha3", "thiserror", "tokio", @@ -9055,30 +9165,31 @@ dependencies = [ [[package]] name = "starknet-macros" -version = "0.1.7" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d549d3078bdbe775d0deaa8ddb57a19942989ce7c1f2dfd60beeb322bb4945" +checksum = "8986a940af916fc0a034f4e42c6ba76d94f1e97216d75447693dfd7aefaf3ef2" dependencies = [ - "starknet-core 0.10.0", + "starknet-core 0.12.0", "syn 2.0.66", ] [[package]] name = "starknet-providers" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4bd1c262936543d6d14d299f476585e8c9625a4e284d9255b54f1c2e68e64a" +checksum = "59c85e0a0f4563ae95dfeae14ea0f0c70610efc0ec2462505c64eff5765e7b97" dependencies = [ "async-trait", "auto_impl", "ethereum-types", "flate2", + "getrandom", "log", "reqwest 0.11.27", "serde", "serde_json", "serde_with 2.3.3", - "starknet-core 0.9.0", + "starknet-core 0.11.1", "thiserror", "url", ] @@ -9087,10 +9198,16 @@ dependencies = [ name = "starknet-settlement-client" version = "0.1.0" dependencies = [ + "anyhow", + "appchain-core-contract-client", + "async-std", "async-trait", "c-kzg", "color-eyre", + "crypto-bigint 0.5.5", + "dotenvy", "lazy_static", + "log", "mockall", "opentelemetry", "opentelemetry-appender-tracing", @@ -9098,10 +9215,12 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "reqwest 0.12.7", - "rstest 0.18.2", + "rstest 0.22.0", "serde", + "serde_json", "settlement-client-interface", "starknet", + "tempfile", "tokio", "tokio-test", "tracing", @@ -9114,17 +9233,18 @@ dependencies = [ [[package]] name = "starknet-signers" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c5eb659e66b56ceafb9025cd601226d8f34d273f1b826cd4053ab6333ff0898" +checksum = "c17da2139119dbe3aacf1d5d4338798a5c489d17f424916ceb9d2efd83554f87" dependencies = [ "async-trait", "auto_impl", "crypto-bigint 0.5.5", "eth-keystore", + "getrandom", "rand", - "starknet-core 0.9.0", - "starknet-crypto 0.6.2", + "starknet-core 0.11.1", + "starknet-crypto 0.7.2", "thiserror", ] @@ -9426,14 +9546,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand 2.1.0", + "once_cell", "rustix 0.38.34", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -9473,7 +9594,7 @@ dependencies = [ "reqwest 0.12.7", "serde", "serde_json", - "serde_with 3.8.1", + "serde_with 3.9.0", "thiserror", "tokio", "tokio-stream", @@ -10514,6 +10635,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" diff --git a/Cargo.toml b/Cargo.toml index a7b3cdbf..d6be4da1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,11 +55,11 @@ reqwest = { version = "0.12.7", features = [ "native-tls", "json", ] } -rstest = "0.18.2" +rstest = "0.22.0" serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.114" -starknet = "0.9.0" -tempfile = "3.8.1" +starknet = "0.11.0" +tempfile = "3.12.0" thiserror = "1.0.57" tokio = { version = "1.37.0" } tokio-stream = "0.1.15" @@ -75,6 +75,8 @@ hex = "0.4" itertools = "0.13.0" mockall = "0.13.0" testcontainers = "0.18.0" +appchain-core-contract-client = { git = "https://github.com/byteZorvin/zaun", branch = "type-update" } +crypto-bigint = { version = "0.5.5" } # Instrumentation @@ -108,6 +110,7 @@ cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", features = [ # TODO: update back to the main repo once it's merged # Sharp (Starkware) snos = { git = "https://github.com/keep-starknet-strange/snos" } +starknet-os = { git = "https://github.com/keep-starknet-strange/snos" } # Madara prover API madara-prover-common = { git = "https://github.com/Moonsong-Labs/madara-prover-api", branch = "od/use-latest-cairo-vm" } diff --git a/crates/da-clients/da-client-interface/src/lib.rs b/crates/da-clients/da-client-interface/src/lib.rs index f6158e17..572af75f 100644 --- a/crates/da-clients/da-client-interface/src/lib.rs +++ b/crates/da-clients/da-client-interface/src/lib.rs @@ -27,11 +27,3 @@ pub trait DaClient: Send + Sync { /// Should return the max bytes per blob async fn max_bytes_per_blob(&self) -> u64; } - -/// Trait for every new DaConfig to implement -#[async_trait] -pub trait DaConfig { - /// Should create a new instance of the DaConfig from the environment variables - fn new_from_env() -> Self; - async fn build_client(&self) -> T; -} diff --git a/crates/orchestrator/src/jobs/da_job/mod.rs b/crates/orchestrator/src/jobs/da_job/mod.rs index 2cb1a782..8195de61 100644 --- a/crates/orchestrator/src/jobs/da_job/mod.rs +++ b/crates/orchestrator/src/jobs/da_job/mod.rs @@ -9,9 +9,10 @@ use color_eyre::eyre::WrapErr; use lazy_static::lazy_static; use num_bigint::{BigUint, ToBigUint}; use num_traits::{Num, Zero}; -use starknet::core::types::{BlockId, FieldElement, MaybePendingStateUpdate, StateUpdate}; +use starknet::core::types::{ + BlockId, ContractStorageDiffItem, DeclaredClassItem, Felt, MaybePendingStateUpdate, StateUpdate, +}; use starknet::providers::Provider; -use starknet_core::types::{ContractStorageDiffItem, DeclaredClassItem}; use thiserror::Error; use tracing::log; use uuid::Uuid; @@ -193,7 +194,7 @@ pub fn fft_transformation(elements: Vec) -> Vec { transform } -pub fn convert_to_biguint(elements: Vec) -> Vec { +pub fn convert_to_biguint(elements: Vec) -> Vec { // Initialize the vector with 4096 BigUint zeros let mut biguint_vec = vec![BigUint::zero(); 4096]; @@ -243,16 +244,16 @@ pub async fn state_update_to_blob_data( block_no: u64, state_update: StateUpdate, config: Arc, -) -> color_eyre::Result> { +) -> color_eyre::Result> { let mut state_diff = state_update.state_diff; - let mut blob_data: Vec = vec![FieldElement::from(state_diff.storage_diffs.len())]; + let mut blob_data: Vec = vec![Felt::from(state_diff.storage_diffs.len())]; - let deployed_contracts: HashMap = + let deployed_contracts: HashMap = state_diff.deployed_contracts.into_iter().map(|item| (item.address, item.class_hash)).collect(); - let replaced_classes: HashMap = + let replaced_classes: HashMap = state_diff.replaced_classes.into_iter().map(|item| (item.contract_address, item.class_hash)).collect(); - let mut nonces: HashMap = + let mut nonces: HashMap = state_diff.nonces.into_iter().map(|item| (item.contract_address, item.nonce)).collect(); // sort storage diffs @@ -267,7 +268,7 @@ pub async fn state_update_to_blob_data( // @note: if nonce is null and there is some len of writes, make an api call to get the contract // nonce for the block - if nonce.is_none() && !storage_entries.is_empty() && address != FieldElement::ONE { + if nonce.is_none() && !storage_entries.is_empty() && address != Felt::ONE { let get_current_nonce_result = config .starknet_client() .get_nonce(BlockId::Number(block_no), address) @@ -291,7 +292,7 @@ pub async fn state_update_to_blob_data( } } // Handle declared classes - blob_data.push(FieldElement::from(state_diff.declared_classes.len())); + blob_data.push(Felt::from(state_diff.declared_classes.len())); // sort storage diffs state_diff.declared_classes.sort_by_key(|class| class.class_hash); @@ -321,7 +322,7 @@ async fn store_blob_data(blob_data: Vec, block_number: u64, config: Arc /// DA word encoding: /// |---padding---|---class flag---|---new nonce---|---num changes---| /// 127 bits 1 bit 64 bits 64 bits -fn da_word(class_flag: bool, nonce_change: Option, num_changes: u64) -> FieldElement { +fn da_word(class_flag: bool, nonce_change: Option, num_changes: u64) -> Felt { // padding of 127 bits let mut binary_string = "0".repeat(127); @@ -353,7 +354,7 @@ fn da_word(class_flag: bool, nonce_change: Option, num_changes: u6 // Now convert the BigUint to a decimal string let decimal_string = biguint.to_str_radix(10); - FieldElement::from_dec_str(&decimal_string).expect("issue while converting to fieldElement") + Felt::from_dec_str(&decimal_string).expect("issue while converting to fieldElement") } #[cfg(test)] @@ -370,9 +371,9 @@ pub mod test { use majin_blob_types::serde; use rstest::rstest; use serde_json::json; + use starknet::core::types::{Felt, StateUpdate}; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; - use starknet_core::types::{FieldElement, StateUpdate}; use url::Url; use da_client_interface::MockDaClient; @@ -380,9 +381,9 @@ pub mod test { use crate::jobs::da_job::da_word; /// Tests `da_word` function with various inputs for class flag, new nonce, and number of changes. - /// Verifies that `da_word` produces the correct FieldElement based on the provided parameters. + /// Verifies that `da_word` produces the correct Felt based on the provided parameters. /// Uses test cases with different combinations of inputs and expected output strings. - /// Asserts the function's correctness by comparing the computed and expected FieldElements. + /// Asserts the function's correctness by comparing the computed and expected Felts. #[rstest] #[case(false, 1, 1, "18446744073709551617")] #[case(false, 1, 0, "18446744073709551616")] @@ -394,9 +395,9 @@ pub mod test { #[case] num_changes: u64, #[case] expected: String, ) { - let new_nonce = if new_nonce > 0 { Some(FieldElement::from(new_nonce)) } else { None }; + let new_nonce = if new_nonce > 0 { Some(Felt::from(new_nonce)) } else { None }; let da_word = da_word(class_flag, new_nonce, num_changes); - let expected = FieldElement::from_dec_str(expected.as_str()).unwrap(); + let expected = Felt::from_dec_str(expected.as_str()).unwrap(); assert_eq!(da_word, expected); } @@ -544,7 +545,7 @@ pub mod test { let nonce = entry.nonce.clone(); let response = json!({ "id": 1,"jsonrpc":"2.0","result": nonce }); let field_element = - FieldElement::from_dec_str(&address).expect("issue while converting the hex to field").to_bytes_be(); + Felt::from_dec_str(&address).expect("issue while converting the hex to field").to_bytes_be(); let hex_field_element = vec_u8_to_hex_string(&field_element); server.mock(|when, then| { diff --git a/crates/orchestrator/src/tests/config.rs b/crates/orchestrator/src/tests/config.rs index 10085d1b..96122e99 100644 --- a/crates/orchestrator/src/tests/config.rs +++ b/crates/orchestrator/src/tests/config.rs @@ -157,7 +157,7 @@ impl TestConfigBuilder { } pub async fn build(self) -> TestConfigBuilderReturns { - dotenvy::from_filename("../.env.test").expect("Failed to load the .env.test file"); + dotenvy::from_filename_override("../.env.test").expect("Failed to load the .env.test file"); let settings_provider = EnvSettingsProvider {}; let provider_config = Arc::new(ProviderConfig::AWS(Box::new(get_aws_config(&settings_provider).await))); diff --git a/crates/orchestrator/src/tests/data_storage/mod.rs b/crates/orchestrator/src/tests/data_storage/mod.rs index a041d18f..ff8a9663 100644 --- a/crates/orchestrator/src/tests/data_storage/mod.rs +++ b/crates/orchestrator/src/tests/data_storage/mod.rs @@ -1,8 +1,7 @@ -use bytes::Bytes; -use serde_json::json; - use crate::tests::config::{ConfigType, TestConfigBuilder}; +use bytes::Bytes; use rstest::rstest; +use serde_json::json; /// This test checks the ability to put and get data from AWS S3 using `AWSS3`. /// It puts JSON data into a test bucket and retrieves it, verifying the data @@ -13,7 +12,7 @@ use rstest::rstest; async fn test_put_and_get_data_s3() -> color_eyre::Result<()> { let services = TestConfigBuilder::new().configure_storage_client(ConfigType::Actual).build().await; - dotenvy::from_filename("../.env.test")?; + dotenvy::from_filename_override("../.env.test")?; let s3_client = services.config.storage(); diff --git a/crates/orchestrator/src/tests/jobs/da_job/mod.rs b/crates/orchestrator/src/tests/jobs/da_job/mod.rs index c5c2259b..10e518e5 100644 --- a/crates/orchestrator/src/tests/jobs/da_job/mod.rs +++ b/crates/orchestrator/src/tests/jobs/da_job/mod.rs @@ -6,7 +6,7 @@ use color_eyre::eyre::eyre; use mockall::predicate::always; use rstest::rstest; use serde_json::json; -use starknet_core::types::{FieldElement, MaybePendingStateUpdate, PendingStateUpdate, StateDiff}; +use starknet::core::types::{Felt, MaybePendingStateUpdate, PendingStateUpdate, StateDiff}; use uuid::Uuid; use da_client_interface::MockDaClient; @@ -110,7 +110,7 @@ async fn test_da_job_process_job_failure_on_pending_block() { let internal_id = "1"; let pending_state_update = MaybePendingStateUpdate::PendingUpdate(PendingStateUpdate { - old_root: FieldElement::default(), + old_root: Felt::default(), state_diff: StateDiff { storage_diffs: vec![], deprecated_declared_classes: vec![], diff --git a/crates/orchestrator/src/tests/jobs/state_update_job/mod.rs b/crates/orchestrator/src/tests/jobs/state_update_job/mod.rs index ebb27f76..7186c6a8 100644 --- a/crates/orchestrator/src/tests/jobs/state_update_job/mod.rs +++ b/crates/orchestrator/src/tests/jobs/state_update_job/mod.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use std::fs; use std::path::PathBuf; +use std::{env, fs}; use assert_matches::assert_matches; use bytes::Bytes; @@ -61,7 +61,13 @@ async fn test_process_job_works( use crate::tests::config::ConfigType; - dotenvy::from_filename("../.env.test").expect("Failed to load the .env file"); + let aws_region = env::var("AWS_REGION").unwrap(); + println!("AWS_REGION: {}", aws_region); + + dotenvy::from_filename_override("../.env.test").expect("Failed to load the .env file"); + + let aws_region = env::var("AWS_REGION").unwrap(); + println!("AWS_REGION: {}", aws_region); // Mocking the settlement client. let mut settlement_client = MockSettlementClient::new(); diff --git a/crates/prover-services/gps-fact-checker/src/fact_info.rs b/crates/prover-services/gps-fact-checker/src/fact_info.rs index d203cf2c..10e87972 100644 --- a/crates/prover-services/gps-fact-checker/src/fact_info.rs +++ b/crates/prover-services/gps-fact-checker/src/fact_info.rs @@ -8,7 +8,8 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::types::relocatable::MaybeRelocatable; use cairo_vm::vm::runners::cairo_pie::CairoPie; use cairo_vm::Felt252; -use starknet::core::types::FieldElement; +use starknet::core::types::Felt; +// use starknet::core::types::FieldElement; use super::error::FactCheckerError; use super::fact_node::generate_merkle_root; @@ -25,12 +26,14 @@ pub struct FactInfo { pub fact: B256, } -pub fn get_fact_info(cairo_pie: &CairoPie, program_hash: Option) -> Result { +pub fn get_fact_info(cairo_pie: &CairoPie, program_hash: Option) -> Result { let program_output = get_program_output(cairo_pie)?; let fact_topology = get_fact_topology(cairo_pie, program_output.len())?; let program_hash = match program_hash { Some(hash) => hash, - None => compute_program_hash_chain(&cairo_pie.metadata.program, BOOTLOADER_VERSION)?, + None => Felt::from_bytes_be( + &compute_program_hash_chain(&cairo_pie.metadata.program, BOOTLOADER_VERSION)?.to_bytes_be(), + ), }; let output_root = generate_merkle_root(&program_output, &fact_topology)?; let fact = keccak256([program_hash.to_bytes_be(), *output_root.node_hash].concat()); diff --git a/crates/prover-services/sharp-service/tests/lib.rs b/crates/prover-services/sharp-service/tests/lib.rs index 0171af93..62f8c635 100644 --- a/crates/prover-services/sharp-service/tests/lib.rs +++ b/crates/prover-services/sharp-service/tests/lib.rs @@ -52,6 +52,7 @@ async fn prover_client_submit_task_works() { #[case(CairoJobStatus::IN_PROGRESS)] #[case(CairoJobStatus::NOT_CREATED)] #[case(CairoJobStatus::PROCESSED)] +#[ignore] #[case(CairoJobStatus::ONCHAIN)] #[tokio::test] async fn prover_client_get_task_status_works(#[case] cairo_job_status: CairoJobStatus) { diff --git a/crates/settlement-clients/ethereum/src/config.rs b/crates/settlement-clients/ethereum/src/config.rs index 89b0dcd5..5cd90b74 100644 --- a/crates/settlement-clients/ethereum/src/config.rs +++ b/crates/settlement-clients/ethereum/src/config.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; -use settlement_client_interface::SettlementConfig; use url::Url; use utils::settings::Settings; @@ -15,8 +14,8 @@ pub struct EthereumSettlementConfig { pub core_contract_address: String, } -impl SettlementConfig for EthereumSettlementConfig { - fn new_with_settings(settings: &impl Settings) -> Self { +impl EthereumSettlementConfig { + pub fn new_with_settings(settings: &impl Settings) -> Self { let rpc_url = settings.get_settings_or_panic(SETTLEMENT_RPC_URL); let rpc_url = Url::from_str(&rpc_url).unwrap_or_else(|_| panic!("Failed to parse {}", SETTLEMENT_RPC_URL)); let core_contract_address = settings.get_settings_or_panic(ENV_CORE_CONTRACT_ADDRESS); diff --git a/crates/settlement-clients/ethereum/src/lib.rs b/crates/settlement-clients/ethereum/src/lib.rs index fb37cdf8..bac11c46 100644 --- a/crates/settlement-clients/ethereum/src/lib.rs +++ b/crates/settlement-clients/ethereum/src/lib.rs @@ -27,10 +27,7 @@ use mockall::{automock, predicate::*}; use alloy::providers::ProviderBuilder; use conversion::{get_input_data_for_eip_4844, prepare_sidecar}; -#[cfg(feature = "testing")] -use settlement_client_interface::{SettlementClient, SettlementConfig, SettlementVerificationStatus}; -#[cfg(not(feature = "testing"))] -use settlement_client_interface::{SettlementClient, SettlementConfig, SettlementVerificationStatus}; +use settlement_client_interface::{SettlementClient, SettlementVerificationStatus}; #[cfg(feature = "testing")] use url::Url; use utils::env_utils::get_env_var_or_panic; @@ -164,11 +161,11 @@ impl SettlementClient for EthereumSettlementClient { &self, program_output: Vec<[u8; 32]>, onchain_data_hash: [u8; 32], - onchain_data_size: usize, + onchain_data_size: [u8; 32], ) -> Result { let program_output: Vec = vec_u8_32_to_vec_u256(program_output.as_slice())?; let onchain_data_hash: U256 = slice_u8_to_u256(&onchain_data_hash)?; - let onchain_data_size: U256 = onchain_data_size.try_into()?; + let onchain_data_size = U256::from_be_bytes(onchain_data_size); let tx_receipt = self.core_contract_client.update_state(program_output, onchain_data_hash, onchain_data_size).await?; Ok(format!("0x{:x}", tx_receipt.transaction_hash)) diff --git a/crates/settlement-clients/settlement-client-interface/src/lib.rs b/crates/settlement-clients/settlement-client-interface/src/lib.rs index afe3d2e7..be30cf33 100644 --- a/crates/settlement-clients/settlement-client-interface/src/lib.rs +++ b/crates/settlement-clients/settlement-client-interface/src/lib.rs @@ -2,7 +2,6 @@ use async_trait::async_trait; use color_eyre::eyre::Result; use mockall::automock; use mockall::predicate::*; -use utils::settings::Settings; pub const SETTLEMENT_SETTINGS_NAME: &str = "settlement_settings"; @@ -26,7 +25,7 @@ pub trait SettlementClient: Send + Sync { &self, program_output: Vec<[u8; 32]>, onchain_data_hash: [u8; 32], - onchain_data_size: usize, + onchain_data_size: [u8; 32], ) -> Result; /// Should be used to update state on contract and publish the blob on ethereum. @@ -49,9 +48,3 @@ pub trait SettlementClient: Send + Sync { /// Should retrieve the latest transaction count to be used as nonce. async fn get_nonce(&self) -> Result; } - -/// Trait for every new SettlementConfig to implement -pub trait SettlementConfig { - /// Should create a new instance of the SettlementConfig from the environment variables - fn new_with_settings(settings: &impl Settings) -> Self; -} diff --git a/crates/settlement-clients/starknet/Cargo.toml b/crates/settlement-clients/starknet/Cargo.toml index 099a4da1..e06dd646 100644 --- a/crates/settlement-clients/starknet/Cargo.toml +++ b/crates/settlement-clients/starknet/Cargo.toml @@ -4,16 +4,22 @@ version.workspace = true edition.workspace = true [dependencies] +anyhow = "1.0.89" +appchain-core-contract-client = { workspace = true } async-trait = { workspace = true } c-kzg = { workspace = true } color-eyre = { workspace = true } +crypto-bigint = { workspace = true } +dotenvy.workspace = true lazy_static = { workspace = true } +log = { workspace = true } mockall = { workspace = true } reqwest = { workspace = true } rstest = { workspace = true } serde = { workspace = true } settlement-client-interface = { workspace = true } starknet = { workspace = true } +tempfile.workspace = true tokio = { workspace = true } url = { workspace = true } utils = { workspace = true } @@ -35,4 +41,6 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] } [dev-dependencies] +async-std = { version = "1.13.0", features = ["attributes"] } +serde_json.workspace = true tokio-test = "*" diff --git a/crates/settlement-clients/starknet/src/config.rs b/crates/settlement-clients/starknet/src/config.rs index 3f3eb146..f7f595c9 100644 --- a/crates/settlement-clients/starknet/src/config.rs +++ b/crates/settlement-clients/starknet/src/config.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; -use settlement_client_interface::SettlementConfig; use url::Url; use utils::env_utils::get_env_var_or_default; use utils::settings::Settings; @@ -19,9 +18,9 @@ pub struct StarknetSettlementConfig { pub tx_finality_retry_delay_in_seconds: u64, } -impl SettlementConfig for StarknetSettlementConfig { +impl StarknetSettlementConfig { /// Should create a new instance of the DaConfig from the environment variables - fn new_with_settings(settings: &impl Settings) -> Self { + pub fn new_with_settings(settings: &impl Settings) -> Self { let rpc_url = settings.get_settings_or_panic(ENV_STARKNET_RPC_URL); let rpc_url = Url::from_str(&rpc_url).unwrap_or_else(|_| panic!("Failed to parse {}", ENV_STARKNET_RPC_URL)); let core_contract_address = settings.get_settings_or_panic(ENV_CORE_CONTRACT_ADDRESS); diff --git a/crates/settlement-clients/starknet/src/conversion.rs b/crates/settlement-clients/starknet/src/conversion.rs index 816999ea..5324c01f 100644 --- a/crates/settlement-clients/starknet/src/conversion.rs +++ b/crates/settlement-clients/starknet/src/conversion.rs @@ -1,9 +1,38 @@ -use starknet::core::types::FieldElement; +use color_eyre::Result; +use starknet::core::types::Felt; -pub(crate) fn slice_slice_u8_to_vec_field(slices: &[[u8; 32]]) -> Vec { +pub(crate) fn slice_slice_u8_to_vec_field(slices: &[[u8; 32]]) -> Vec { slices.iter().map(slice_u8_to_field).collect() } -pub(crate) fn slice_u8_to_field(slice: &[u8; 32]) -> FieldElement { - FieldElement::from_byte_slice_be(slice).expect("could not convert u8 slice to FieldElement") +pub(crate) fn slice_u8_to_field(slice: &[u8; 32]) -> Felt { + Felt::from_bytes_be_slice(slice) +} + +pub(crate) fn u64_from_felt(number: Felt) -> Result { + let bytes = number.to_bytes_be(); + + for x in &bytes[0..24] { + if *x != 0 { + return Err(color_eyre::Report::msg("byte should be zero, cannot convert to Felt")); + } + } + Ok(u64::from_be_bytes(bytes[24..32].try_into().unwrap())) +} + +#[test] +fn test_u64_from_from_felt_ok() { + let number = 10.into(); + let converted = u64_from_felt(number); + assert!(converted.unwrap() == 10u64, "Should be able to convert"); +} + +#[test] +fn test_u64_from_from_felt_panic() { + let number = Felt::MAX; + let number = u64_from_felt(number); + match number { + Ok(n) => log::info!("Nonce value from get_nonce: {:?}", n), + Err(e) => log::error!("Error getting nonce: {:?}", e), + } } diff --git a/crates/settlement-clients/starknet/src/lib.rs b/crates/settlement-clients/starknet/src/lib.rs index 8d2f5041..0a09f358 100644 --- a/crates/settlement-clients/starknet/src/lib.rs +++ b/crates/settlement-clients/starknet/src/lib.rs @@ -1,20 +1,24 @@ pub mod config; pub mod conversion; +#[cfg(test)] +pub mod tests; use std::sync::Arc; +use appchain_core_contract_client::interfaces::core_contract::CoreContract; use async_trait::async_trait; use color_eyre::eyre::{eyre, Ok}; use color_eyre::Result; +use crypto_bigint::Encoding; use lazy_static::lazy_static; use mockall::{automock, predicate::*}; use starknet::accounts::ConnectedAccount; -use starknet::core::types::{ExecutionResult, MaybePendingTransactionReceipt}; +use starknet::core::types::TransactionExecutionStatus; use starknet::providers::Provider; use starknet::{ - accounts::{Account, Call, ExecutionEncoding, SingleOwnerAccount}, + accounts::{ExecutionEncoding, SingleOwnerAccount}, core::{ - types::{BlockId, BlockTag, FieldElement, FunctionCall}, + types::{BlockId, BlockTag, Felt, FunctionCall}, utils::get_selector_from_name, }, providers::{jsonrpc::HttpTransport, JsonRpcClient}, @@ -22,19 +26,23 @@ use starknet::{ }; use tokio::time::{sleep, Duration}; -use settlement_client_interface::{SettlementClient, SettlementConfig, SettlementVerificationStatus}; +use appchain_core_contract_client::clients::StarknetCoreContractClient; +use settlement_client_interface::{SettlementClient, SettlementVerificationStatus}; use utils::settings::Settings; use crate::config::StarknetSettlementConfig; -use crate::conversion::{slice_slice_u8_to_vec_field, slice_u8_to_field}; +use crate::conversion::{slice_slice_u8_to_vec_field, slice_u8_to_field, u64_from_felt}; + +pub type LocalWalletSignerMiddleware = Arc>, LocalWallet>>; pub struct StarknetSettlementClient { - pub account: SingleOwnerAccount>, LocalWallet>, - pub core_contract_address: FieldElement, + pub account: LocalWalletSignerMiddleware, + pub starknet_core_contract_client: StarknetCoreContractClient, + pub core_contract_address: Felt, pub tx_finality_retry_delay_in_seconds: u64, } -pub const ENV_PUBLIC_KEY: &str = "STARKNET_PUBLIC_KEY"; +pub const ENV_ACCOUNT_ADDRESS: &str = "STARKNET_ACCOUNT_ADDRESS"; pub const ENV_PRIVATE_KEY: &str = "STARKNET_PRIVATE_KEY"; const MAX_RETRIES_VERIFY_TX_FINALITY: usize = 10; @@ -45,48 +53,54 @@ const MAX_RETRIES_VERIFY_TX_FINALITY: usize = 10; impl StarknetSettlementClient { pub async fn new_with_settings(settings: &impl Settings) -> Self { let settlement_cfg = StarknetSettlementConfig::new_with_settings(settings); - let provider = Arc::new(JsonRpcClient::new(HttpTransport::new(settlement_cfg.rpc_url))); + let provider: Arc> = + Arc::new(JsonRpcClient::new(HttpTransport::new(settlement_cfg.rpc_url.clone()))); - let public_key = settings.get_settings_or_panic(ENV_PUBLIC_KEY); - let signer_address = FieldElement::from_hex_be(&public_key).expect("invalid signer address"); + let public_key = settings.get_settings_or_panic(ENV_ACCOUNT_ADDRESS); + let signer_address = Felt::from_hex(&public_key).expect("invalid signer address"); // TODO: Very insecure way of building the signer. Needs to be adjusted. let private_key = settings.get_settings_or_panic(ENV_PRIVATE_KEY); - let signer = FieldElement::from_hex_be(&private_key).expect("Invalid private key"); + let signer = Felt::from_hex(&private_key).expect("Invalid private key"); let signer = LocalWallet::from(SigningKey::from_secret_scalar(signer)); let core_contract_address = - FieldElement::from_hex_be(&settlement_cfg.core_contract_address).expect("Invalid core contract address"); + Felt::from_hex(&settlement_cfg.core_contract_address).expect("Invalid core contract address"); + + let account: Arc>, LocalWallet>> = + Arc::new(SingleOwnerAccount::new( + provider.clone(), + signer.clone(), + signer_address, + provider.chain_id().await.unwrap(), + ExecutionEncoding::New, + )); - let account = SingleOwnerAccount::new( - provider.clone(), - signer, - signer_address, - provider.chain_id().await.unwrap(), - ExecutionEncoding::Legacy, - ); + let starknet_core_contract_client: StarknetCoreContractClient = + StarknetCoreContractClient::new(core_contract_address, account.clone()); StarknetSettlementClient { account, core_contract_address, + starknet_core_contract_client, tx_finality_retry_delay_in_seconds: settlement_cfg.tx_finality_retry_delay_in_seconds, } } } lazy_static! { - pub static ref CONTRACT_WRITE_UPDATE_STATE_SELECTOR: FieldElement = + pub static ref CONTRACT_WRITE_UPDATE_STATE_SELECTOR: Felt = get_selector_from_name("update_state").expect("Invalid update state selector"); // TODO: `stateBlockNumber` does not exists yet in our implementation: // https://github.com/keep-starknet-strange/piltover // It should get added to match the solidity implementation of the core contract. - pub static ref CONTRACT_READ_STATE_BLOCK_NUMBER: FieldElement = + pub static ref CONTRACT_READ_STATE_BLOCK_NUMBER: Felt = get_selector_from_name("stateBlockNumber").expect("Invalid update state selector"); } // TODO: Note that we already have an implementation of the appchain core contract client available here: // https://github.com/keep-starknet-strange/zaun/tree/main/crates/l3/appchain-core-contract-client -// However, this implementation uses different FieldElement types, and incorporating all of them +// However, this implementation uses different Felt types, and incorporating all of them // into this repository would introduce unnecessary complexity. // Therefore, we will wait for the update of starknet_rs in the Zaun repository before adapting // the StarknetSettlementClient implementation. @@ -106,44 +120,37 @@ impl SettlementClient for StarknetSettlementClient { &self, program_output: Vec<[u8; 32]>, onchain_data_hash: [u8; 32], - onchain_data_size: usize, + onchain_data_size: [u8; 32], ) -> Result { let program_output = slice_slice_u8_to_vec_field(program_output.as_slice()); let onchain_data_hash = slice_u8_to_field(&onchain_data_hash); - let mut calldata: Vec = Vec::with_capacity(program_output.len() + 2); - calldata.extend(program_output); - calldata.push(onchain_data_hash); - calldata.push(FieldElement::from(onchain_data_size)); - let invoke_result = self - .account - .execute(vec![Call { - to: self.core_contract_address, - selector: *CONTRACT_WRITE_UPDATE_STATE_SELECTOR, - calldata, - }]) - .send() - .await?; - Ok(format!("0x{:x}", invoke_result.transaction_hash)) + let core_contract: &CoreContract = self.starknet_core_contract_client.as_ref(); + let onchain_data_size = crypto_bigint::U256::from_be_bytes(onchain_data_size).into(); + let invoke_result = core_contract.update_state(program_output, onchain_data_hash, onchain_data_size).await?; + + Ok(invoke_result.transaction_hash.to_hex_string()) } /// Should verify the inclusion of a tx in the settlement layer async fn verify_tx_inclusion(&self, tx_hash: &str) -> Result { - let tx_hash = FieldElement::from_hex_be(tx_hash)?; + let tx_hash = Felt::from_hex(tx_hash)?; let tx_receipt = self.account.provider().get_transaction_receipt(tx_hash).await?; - match tx_receipt { - MaybePendingTransactionReceipt::Receipt(tx) => match tx.execution_result() { - ExecutionResult::Succeeded => Ok(SettlementVerificationStatus::Verified), - ExecutionResult::Reverted { reason } => { - Ok(SettlementVerificationStatus::Rejected(format!("Tx {} has been reverted: {}", tx_hash, reason))) + let execution_result = tx_receipt.receipt.execution_result(); + let status = execution_result.status(); + + match status { + TransactionExecutionStatus::Reverted => Ok(SettlementVerificationStatus::Rejected(format!( + "Transaction {} has been reverted: {}", + tx_hash, + execution_result.revert_reason().unwrap() + ))), + TransactionExecutionStatus::Succeeded => { + if tx_receipt.block.is_pending() { + Ok(SettlementVerificationStatus::Pending) + } else { + Ok(SettlementVerificationStatus::Verified) } - }, - MaybePendingTransactionReceipt::PendingReceipt(tx) => match tx.execution_result() { - ExecutionResult::Succeeded => Ok(SettlementVerificationStatus::Pending), - ExecutionResult::Reverted { reason } => Ok(SettlementVerificationStatus::Rejected(format!( - "Pending tx {} has been reverted: {}", - tx_hash, reason - ))), - }, + } } } @@ -164,10 +171,10 @@ impl SettlementClient for StarknetSettlementClient { let duration_to_wait_between_polling = Duration::from_secs(self.tx_finality_retry_delay_in_seconds); sleep(duration_to_wait_between_polling).await; - let tx_hash = FieldElement::from_hex_be(tx_hash)?; + let tx_hash = Felt::from_hex(tx_hash)?; loop { let tx_receipt = self.account.provider().get_transaction_receipt(tx_hash).await?; - if let MaybePendingTransactionReceipt::PendingReceipt(_) = tx_receipt { + if tx_receipt.block.is_pending() { retries += 1; if retries > MAX_RETRIES_VERIFY_TX_FINALITY { return Err(eyre!("Max retries exceeeded while waiting for tx {tx_hash} finality.")); @@ -197,11 +204,13 @@ impl SettlementClient for StarknetSettlementClient { if block_number.is_empty() { return Err(eyre!("Could not fetch last block number from core contract.")); } - Ok(block_number[0].try_into()?) + + Ok(u64_from_felt(block_number[0]).expect("Failed to convert to u64")) } /// Returns the nonce for the wallet in use. async fn get_nonce(&self) -> Result { - todo!("Yet to impl nonce call for Starknet.") + let nonce = self.account.get_nonce().await?; + Ok(u64_from_felt(nonce).expect("Failed to convert to u64")) } } diff --git a/crates/settlement-clients/starknet/src/tests/mock_contracts/.gitignore b/crates/settlement-clients/starknet/src/tests/mock_contracts/.gitignore new file mode 100644 index 00000000..73aa31e6 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/mock_contracts/.gitignore @@ -0,0 +1,2 @@ +target +.snfoundry_cache/ diff --git a/crates/settlement-clients/starknet/src/tests/mock_contracts/.tool-versions b/crates/settlement-clients/starknet/src/tests/mock_contracts/.tool-versions new file mode 100644 index 00000000..fca91f1c --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/mock_contracts/.tool-versions @@ -0,0 +1,2 @@ +starknet-foundry 0.30.0 +scarb 2.8.2 diff --git a/crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.lock b/crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.lock new file mode 100644 index 00000000..8b9d4818 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.lock @@ -0,0 +1,22 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "mock_contracts" +version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "snforge_scarb_plugin" +version = "0.1.0" +source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.30.0#196f06b251926697c3d66800f2a93ae595e76496" + +[[package]] +name = "snforge_std" +version = "0.30.0" +source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.30.0#196f06b251926697c3d66800f2a93ae595e76496" +dependencies = [ + "snforge_scarb_plugin", +] diff --git a/crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.toml b/crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.toml new file mode 100644 index 00000000..d02816bb --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/mock_contracts/Scarb.toml @@ -0,0 +1,19 @@ +[package] +name = "mock_contracts" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.8.2" + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.30.0" } + +[[target.starknet-contract]] +sierra = true +casm = true + +[scripts] +test = "snforge test" diff --git a/crates/settlement-clients/starknet/src/tests/mock_contracts/src/lib.cairo b/crates/settlement-clients/starknet/src/tests/mock_contracts/src/lib.cairo new file mode 100644 index 00000000..43577b0a --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/mock_contracts/src/lib.cairo @@ -0,0 +1,36 @@ +#[starknet::interface] +pub trait IPiltover { + fn update_state( + ref self: TContractState, + program_output: Span, + onchain_data_hash: felt252, + onchain_data_size: u256 + ); + + fn get_is_updated(self: @TContractState, onchain_data_hash: felt252) -> bool; +} + +#[starknet::contract] +mod Piltover { + use starknet::storage::Map; + #[storage] + struct Storage { + is_updated: Map, + } + + #[abi(embed_v0)] + impl IPiltoverImpl of super::IPiltover { + fn update_state( + ref self: ContractState, + program_output: Span, + onchain_data_hash: felt252, + onchain_data_size: u256 + ) { + self.is_updated.write(onchain_data_hash, true); + } + + fn get_is_updated(self: @ContractState, onchain_data_hash: felt252) -> bool { + self.is_updated.read(onchain_data_hash) + } + } +} diff --git a/crates/settlement-clients/starknet/src/tests/mod.rs b/crates/settlement-clients/starknet/src/tests/mod.rs new file mode 100644 index 00000000..f67283f2 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/mod.rs @@ -0,0 +1,2 @@ +pub mod setup; +mod test; diff --git a/crates/settlement-clients/starknet/src/tests/preset.yml b/crates/settlement-clients/starknet/src/tests/preset.yml new file mode 100644 index 00000000..8b812a14 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/preset.yml @@ -0,0 +1,34 @@ +chain_name: "Madara" +chain_id: "MADARA_DEVNET" +native_fee_token_address: "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" +parent_fee_token_address: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" +versioned_constants: + "0.13.0": "./src/tests/resources/versioned_constants_13_0.json" + "0.13.1": "./src/tests/resources/versioned_constants_13_1.json" + "0.13.1.1": "./src/tests/resources/versioned_constants_13_1_1.json" + "0.13.2": "./src/tests/resources/versioned_constants_13_2.json" +latest_protocol_version: "0.13.2" +block_time: "100ms" +pending_block_update_time: 200ms +execution_batch_size: 16 +bouncer_config: + block_max_capacity: + builtin_count: + add_mod: 18446744073709551615 + bitwise: 18446744073709551615 + ecdsa: 18446744073709551615 + ec_op: 18446744073709551615 + keccak: 18446744073709551615 + mul_mod: 18446744073709551615 + pedersen: 18446744073709551615 + poseidon: 18446744073709551615 + range_check: 18446744073709551615 + range_check96: 18446744073709551615 + gas: 5000000 + message_segment_length: 18446744073709551615 + n_events: 18446744073709551615 + n_steps: 40000000 + state_diff_size: 131072 +sequencer_address: "0x123" +max_nonce_for_validation_skip: 2 +eth_core_contract_address: "0xE2Bb56ee936fd6433DC0F6e7e3b8365C906AA057" diff --git a/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_0.json b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_0.json new file mode 100644 index 00000000..da8bc502 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_0.json @@ -0,0 +1,509 @@ +{ + "gateway": { + "max_calldata_length": 4000, + "max_contract_bytecode_size": 61440 + }, + "invoke_tx_max_n_steps": 3000000, + "max_recursion_depth": 50, + "segment_arena_cells": true, + "os_constants": { + "nop_entry_point_offset": -1, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "entry_point_type_constructor": 2, + "l1_handler_version": 0, + "sierra_array_len_bound": 4294967296, + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "default_entry_point_selector": 0, + "block_hash_contract_address": 1, + "stored_block_hash_buffer": 10, + "step_gas_cost": 100, + "range_check_gas_cost": 70, + "memory_hole_gas_cost": 10, + "initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "entry_point_gas_cost": { + "entry_point_initial_budget": 1, + "step_gas_cost": 500 + }, + "fee_transfer_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 100 + }, + "transaction_gas_cost": { + "entry_point_gas_cost": 2, + "fee_transfer_gas_cost": 1, + "step_gas_cost": 100 + }, + "call_contract_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10, + "entry_point_gas_cost": 1 + }, + "deploy_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 200, + "entry_point_gas_cost": 1 + }, + "get_block_hash_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_execution_info_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "library_call_gas_cost": { + "call_contract_gas_cost": 1 + }, + "replace_class_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_read_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_write_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "emit_event_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "send_message_to_l1_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "secp256k1_add_gas_cost": { + "step_gas_cost": 406, + "range_check_gas_cost": 29 + }, + "secp256k1_get_point_from_x_gas_cost": { + "step_gas_cost": 391, + "range_check_gas_cost": 30, + "memory_hole_gas_cost": 20 + }, + "secp256k1_get_xy_gas_cost": { + "step_gas_cost": 239, + "range_check_gas_cost": 11, + "memory_hole_gas_cost": 40 + }, + "secp256k1_mul_gas_cost": { + "step_gas_cost": 76401, + "range_check_gas_cost": 7045 + }, + "secp256k1_new_gas_cost": { + "step_gas_cost": 475, + "range_check_gas_cost": 35, + "memory_hole_gas_cost": 40 + }, + "secp256r1_add_gas_cost": { + "step_gas_cost": 589, + "range_check_gas_cost": 57 + }, + "secp256r1_get_point_from_x_gas_cost": { + "step_gas_cost": 510, + "range_check_gas_cost": 44, + "memory_hole_gas_cost": 20 + }, + "secp256r1_get_xy_gas_cost": { + "step_gas_cost": 241, + "range_check_gas_cost": 11, + "memory_hole_gas_cost": 40 + }, + "secp256r1_mul_gas_cost": { + "step_gas_cost": 125240, + "range_check_gas_cost": 13961 + }, + "secp256r1_new_gas_cost": { + "step_gas_cost": 594, + "range_check_gas_cost": 49, + "memory_hole_gas_cost": 40 + }, + "keccak_gas_cost": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost_gas_cost": 180000, + "sha256_process_block_gas_cost": { + "step_gas_cost": 0, + "range_check_gas_cost": 0, + "syscall_base_gas_cost": 0 + }, + "error_block_number_out_of_range": "Block number out of range", + "error_out_of_gas": "Out of gas", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "validated": "VALID", + "l1_gas": "L1_GAS", + "l2_gas": "L2_GAS", + "l1_gas_index": 0, + "l2_gas_index": 1 + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0, + "n_steps": 691 + }, + "DelegateCall": { + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0, + "n_steps": 713 + }, + "DelegateL1Handler": { + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0, + "n_steps": 692 + }, + "Deploy": { + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0, + "n_steps": 944 + }, + "EmitEvent": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 19 + }, + "GetBlockHash": { + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0, + "n_steps": 74 + }, + "GetBlockNumber": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 40 + }, + "GetBlockTimestamp": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 38 + }, + "GetCallerAddress": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 32 + }, + "GetContractAddress": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 36 + }, + "GetExecutionInfo": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 29 + }, + "GetSequencerAddress": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 34 + }, + "GetTxInfo": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 29 + }, + "GetTxSignature": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 44 + }, + "Keccak": { + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0, + "n_steps": 381 + }, + "LibraryCall": { + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0, + "n_steps": 680 + }, + "LibraryCallL1Handler": { + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0, + "n_steps": 659 + }, + "ReplaceClass": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 73 + }, + "Secp256k1Add": { + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0, + "n_steps": 406 + }, + "Secp256k1GetPointFromX": { + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 20, + "n_steps": 391 + }, + "Secp256k1GetXy": { + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 40, + "n_steps": 239 + }, + "Secp256k1Mul": { + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0, + "n_steps": 76401 + }, + "Secp256k1New": { + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 40, + "n_steps": 475 + }, + "Secp256r1Add": { + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0, + "n_steps": 589 + }, + "Secp256r1GetPointFromX": { + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 20, + "n_steps": 510 + }, + "Secp256r1GetXy": { + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 40, + "n_steps": 241 + }, + "Secp256r1Mul": { + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0, + "n_steps": 125240 + }, + "Secp256r1New": { + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 40, + "n_steps": 594 + }, + "SendMessageToL1": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 84 + }, + "Sha256ProcessBlock": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 0 + }, + "StorageRead": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 44 + }, + "StorageWrite": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 46 + } + }, + "execute_txs_inner": { + "Declare": { + "resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 15, + "range_check_builtin": 63 + }, + "n_memory_holes": 0, + "n_steps": 2711 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 15, + "range_check_builtin": 63 + }, + "n_memory_holes": 0, + "n_steps": 2711 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 83 + }, + "n_memory_holes": 0, + "n_steps": 3628 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 83 + }, + "n_memory_holes": 0, + "n_steps": 3628 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 80 + }, + "n_memory_holes": 0, + "n_steps": 3382 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 80 + }, + "n_memory_holes": 0, + "n_steps": 3382 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 17 + }, + "n_memory_holes": 0, + "n_steps": 1069 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 17 + }, + "n_memory_holes": 0, + "n_steps": 1069 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "vm_resource_fee_cost": { + "add_mod_builtin": [0, 1], + "bitwise_builtin": [32, 100], + "ec_op_builtin": [512, 100], + "ecdsa_builtin": [1024, 100], + "keccak_builtin": [1024, 100], + "mul_mod_builtin": [0, 1], + "n_steps": [5, 1000], + "output_builtin": [0, 1], + "pedersen_builtin": [16, 100], + "poseidon_builtin": [16, 100], + "range_check_builtin": [8, 100], + "range_check96_builtin": [0, 1] + } +} diff --git a/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1.json b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1.json new file mode 100644 index 00000000..e4068473 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1.json @@ -0,0 +1,555 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 4000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 4000000, + "l2_resource_gas_costs": { + "gas_per_data_felt": [128, 1000], + "event_key_factor": [2, 1], + "gas_per_code_byte": [875, 1000] + }, + "max_recursion_depth": 50, + "segment_arena_cells": true, + "os_constants": { + "nop_entry_point_offset": -1, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "entry_point_type_constructor": 2, + "l1_handler_version": 0, + "sierra_array_len_bound": 4294967296, + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "default_entry_point_selector": 0, + "block_hash_contract_address": 1, + "stored_block_hash_buffer": 10, + "step_gas_cost": 100, + "range_check_gas_cost": 70, + "memory_hole_gas_cost": 10, + "initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "entry_point_gas_cost": { + "entry_point_initial_budget": 1, + "step_gas_cost": 500 + }, + "fee_transfer_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 100 + }, + "transaction_gas_cost": { + "entry_point_gas_cost": 2, + "fee_transfer_gas_cost": 1, + "step_gas_cost": 100 + }, + "call_contract_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10, + "entry_point_gas_cost": 1 + }, + "deploy_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 200, + "entry_point_gas_cost": 1 + }, + "get_block_hash_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_execution_info_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "library_call_gas_cost": { + "call_contract_gas_cost": 1 + }, + "replace_class_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_read_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_write_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "emit_event_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "send_message_to_l1_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "secp256k1_add_gas_cost": { + "step_gas_cost": 406, + "range_check_gas_cost": 29 + }, + "secp256k1_get_point_from_x_gas_cost": { + "step_gas_cost": 391, + "range_check_gas_cost": 30, + "memory_hole_gas_cost": 20 + }, + "secp256k1_get_xy_gas_cost": { + "step_gas_cost": 239, + "range_check_gas_cost": 11, + "memory_hole_gas_cost": 40 + }, + "secp256k1_mul_gas_cost": { + "step_gas_cost": 76501, + "range_check_gas_cost": 7045, + "memory_hole_gas_cost": 2 + }, + "secp256k1_new_gas_cost": { + "step_gas_cost": 475, + "range_check_gas_cost": 35, + "memory_hole_gas_cost": 40 + }, + "secp256r1_add_gas_cost": { + "step_gas_cost": 589, + "range_check_gas_cost": 57 + }, + "secp256r1_get_point_from_x_gas_cost": { + "step_gas_cost": 510, + "range_check_gas_cost": 44, + "memory_hole_gas_cost": 20 + }, + "secp256r1_get_xy_gas_cost": { + "step_gas_cost": 241, + "range_check_gas_cost": 11, + "memory_hole_gas_cost": 40 + }, + "secp256r1_mul_gas_cost": { + "step_gas_cost": 125340, + "range_check_gas_cost": 13961, + "memory_hole_gas_cost": 2 + }, + "secp256r1_new_gas_cost": { + "step_gas_cost": 594, + "range_check_gas_cost": 49, + "memory_hole_gas_cost": 40 + }, + "keccak_gas_cost": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost_gas_cost": 180000, + "sha256_process_block_gas_cost": { + "step_gas_cost": 0, + "range_check_gas_cost": 0, + "syscall_base_gas_cost": 0 + }, + "error_block_number_out_of_range": "Block number out of range", + "error_out_of_gas": "Out of gas", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "validated": "VALID", + "l1_gas": "L1_GAS", + "l2_gas": "L2_GAS", + "l1_gas_index": 0, + "l2_gas_index": 1, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + } + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 760, + "builtin_instance_counter": { + "range_check_builtin": 20 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1012, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 751, + "builtin_instance_counter": { + "range_check_builtin": 20 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 408, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 393, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 205, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76503, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 459, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 591, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 512, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125342, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 578, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 139, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "resources": { + "constant": { + "n_steps": 2839, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 63 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 2839, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 63 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "resources": { + "constant": { + "n_steps": 3792, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 83 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 3792, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 83 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "resources": { + "constant": { + "n_steps": 3546, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 80 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 3546, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 80 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "resources": { + "constant": { + "n_steps": 1146, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 1146, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "vm_resource_fee_cost": { + "add_mod_builtin": [0, 1], + "bitwise_builtin": [16, 100], + "ec_op_builtin": [256, 100], + "ecdsa_builtin": [512, 100], + "keccak_builtin": [512, 100], + "mul_mod_builtin": [0, 1], + "n_steps": [25, 10000], + "output_builtin": [0, 1], + "pedersen_builtin": [8, 100], + "poseidon_builtin": [8, 100], + "range_check_builtin": [4, 100], + "range_check96_builtin": [0, 1] + } +} diff --git a/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1_1.json b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1_1.json new file mode 100644 index 00000000..fd317d73 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_1_1.json @@ -0,0 +1,554 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 4000000, + "l2_resource_gas_costs": { + "gas_per_data_felt": [128, 1000], + "event_key_factor": [2, 1], + "gas_per_code_byte": [32, 1000] + }, + "max_recursion_depth": 50, + "os_constants": { + "nop_entry_point_offset": -1, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "entry_point_type_constructor": 2, + "l1_handler_version": 0, + "sierra_array_len_bound": 4294967296, + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "default_entry_point_selector": 0, + "block_hash_contract_address": 1, + "stored_block_hash_buffer": 10, + "step_gas_cost": 100, + "range_check_gas_cost": 70, + "memory_hole_gas_cost": 10, + "initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "entry_point_gas_cost": { + "entry_point_initial_budget": 1, + "step_gas_cost": 500 + }, + "fee_transfer_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 100 + }, + "transaction_gas_cost": { + "entry_point_gas_cost": 2, + "fee_transfer_gas_cost": 1, + "step_gas_cost": 100 + }, + "call_contract_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10, + "entry_point_gas_cost": 1 + }, + "deploy_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 200, + "entry_point_gas_cost": 1 + }, + "get_block_hash_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_execution_info_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "library_call_gas_cost": { + "call_contract_gas_cost": 1 + }, + "replace_class_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_read_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_write_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "emit_event_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "send_message_to_l1_gas_cost": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "secp256k1_add_gas_cost": { + "step_gas_cost": 406, + "range_check_gas_cost": 29 + }, + "secp256k1_get_point_from_x_gas_cost": { + "step_gas_cost": 391, + "range_check_gas_cost": 30, + "memory_hole_gas_cost": 20 + }, + "secp256k1_get_xy_gas_cost": { + "step_gas_cost": 239, + "range_check_gas_cost": 11, + "memory_hole_gas_cost": 40 + }, + "secp256k1_mul_gas_cost": { + "step_gas_cost": 76501, + "range_check_gas_cost": 7045, + "memory_hole_gas_cost": 2 + }, + "secp256k1_new_gas_cost": { + "step_gas_cost": 475, + "range_check_gas_cost": 35, + "memory_hole_gas_cost": 40 + }, + "secp256r1_add_gas_cost": { + "step_gas_cost": 589, + "range_check_gas_cost": 57 + }, + "secp256r1_get_point_from_x_gas_cost": { + "step_gas_cost": 510, + "range_check_gas_cost": 44, + "memory_hole_gas_cost": 20 + }, + "secp256r1_get_xy_gas_cost": { + "step_gas_cost": 241, + "range_check_gas_cost": 11, + "memory_hole_gas_cost": 40 + }, + "secp256r1_mul_gas_cost": { + "step_gas_cost": 125340, + "range_check_gas_cost": 13961, + "memory_hole_gas_cost": 2 + }, + "secp256r1_new_gas_cost": { + "step_gas_cost": 594, + "range_check_gas_cost": 49, + "memory_hole_gas_cost": 40 + }, + "keccak_gas_cost": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost_gas_cost": 180000, + "sha256_process_block_gas_cost": { + "step_gas_cost": 0, + "range_check_gas_cost": 0, + "syscall_base_gas_cost": 0 + }, + "error_block_number_out_of_range": "Block number out of range", + "error_out_of_gas": "Out of gas", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "validated": "VALID", + "l1_gas": "L1_GAS", + "l2_gas": "L2_GAS", + "l1_gas_index": 0, + "l2_gas_index": 1, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + } + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 760, + "builtin_instance_counter": { + "range_check_builtin": 20 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1012, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 751, + "builtin_instance_counter": { + "range_check_builtin": 20 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 408, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 393, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 205, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76503, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 459, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 591, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 512, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125342, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 578, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 139, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "resources": { + "constant": { + "n_steps": 2839, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 63 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 2839, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 63 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "resources": { + "constant": { + "n_steps": 3792, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 83 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 3792, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 83 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "resources": { + "constant": { + "n_steps": 3546, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 80 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 3546, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 80 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "resources": { + "constant": { + "n_steps": 1146, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "deprecated_resources": { + "constant": { + "n_steps": 1146, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "vm_resource_fee_cost": { + "add_mod_builtin": [0, 1], + "bitwise_builtin": [16, 100], + "ec_op_builtin": [256, 100], + "ecdsa_builtin": [512, 100], + "keccak_builtin": [512, 100], + "mul_mod_builtin": [0, 1], + "n_steps": [25, 10000], + "output_builtin": [0, 1], + "pedersen_builtin": [8, 100], + "poseidon_builtin": [8, 100], + "range_check_builtin": [4, 100], + "range_check96_builtin": [0, 1] + } +} diff --git a/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_2.json b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_2.json new file mode 100644 index 00000000..4d3a9ceb --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/resources/versioned_constants_13_2.json @@ -0,0 +1,563 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "l2_resource_gas_costs": { + "gas_per_data_felt": [128, 1000], + "event_key_factor": [2, 1], + "gas_per_code_byte": [875, 1000] + }, + "disable_cairo0_redeclaration": true, + "max_recursion_depth": 50, + "segment_arena_cells": false, + "os_constants": { + "block_hash_contract_address": 1, + "call_contract_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "deploy_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 200, + "syscall_base_gas_cost": 1 + }, + "emit_event_gas_cost": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "entry_point_gas_cost": { + "entry_point_initial_budget": 1, + "step_gas_cost": 500 + }, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "fee_transfer_gas_cost": { + "entry_point_gas_cost": 1, + "step_gas_cost": 100 + }, + "get_block_hash_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_execution_info_gas_cost": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "keccak_gas_cost": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost_gas_cost": 180000, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l2_gas_index": 1, + "library_call_gas_cost": { + "call_contract_gas_cost": 1 + }, + "sha256_process_block_gas_cost": { + "step_gas_cost": 1852, + "range_check_gas_cost": 65, + "bitwise_builtin_gas_cost": 1115, + "syscall_base_gas_cost": 1 + }, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "range_check_gas_cost": 70, + "bitwise_builtin_gas_cost": 594, + "replace_class_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "secp256k1_add_gas_cost": { + "range_check_gas_cost": 29, + "step_gas_cost": 406 + }, + "secp256k1_get_point_from_x_gas_cost": { + "memory_hole_gas_cost": 20, + "range_check_gas_cost": 30, + "step_gas_cost": 391 + }, + "secp256k1_get_xy_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 11, + "step_gas_cost": 239 + }, + "secp256k1_mul_gas_cost": { + "memory_hole_gas_cost": 2, + "range_check_gas_cost": 7045, + "step_gas_cost": 76501 + }, + "secp256k1_new_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 35, + "step_gas_cost": 475 + }, + "secp256r1_add_gas_cost": { + "range_check_gas_cost": 57, + "step_gas_cost": 589 + }, + "secp256r1_get_point_from_x_gas_cost": { + "memory_hole_gas_cost": 20, + "range_check_gas_cost": 44, + "step_gas_cost": 510 + }, + "secp256r1_get_xy_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 11, + "step_gas_cost": 241 + }, + "secp256r1_mul_gas_cost": { + "memory_hole_gas_cost": 2, + "range_check_gas_cost": 13961, + "step_gas_cost": 125340 + }, + "secp256r1_new_gas_cost": { + "memory_hole_gas_cost": 40, + "range_check_gas_cost": 49, + "step_gas_cost": 594 + }, + "send_message_to_l1_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "storage_read_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_write_gas_cost": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transaction_gas_cost": { + "entry_point_gas_cost": 2, + "fee_transfer_gas_cost": 1, + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID" + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 827, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1097, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 818, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1855, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 2973, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 53 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3079, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 58, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4015, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4137, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 77, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3763, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3904, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 74, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1233, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "vm_resource_fee_cost": { + "add_mod_builtin": [4, 100], + "bitwise_builtin": [16, 100], + "ec_op_builtin": [256, 100], + "ecdsa_builtin": [512, 100], + "keccak_builtin": [512, 100], + "mul_mod_builtin": [4, 100], + "n_steps": [25, 10000], + "output_builtin": [0, 1], + "pedersen_builtin": [8, 100], + "poseidon_builtin": [8, 100], + "range_check_builtin": [4, 100], + "range_check96_builtin": [4, 100] + } +} diff --git a/crates/settlement-clients/starknet/src/tests/setup.rs b/crates/settlement-clients/starknet/src/tests/setup.rs new file mode 100644 index 00000000..e2b29cee --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/setup.rs @@ -0,0 +1,176 @@ +use std::env; +use std::ops::Range; +use std::sync::Mutex; +use std::{ + collections::HashMap, + future::Future, + path::{Path, PathBuf}, + process::{Child, Command, Stdio}, + time::Duration, +}; +use tempfile::TempDir; +use url::Url; + +// This code has been take from [here](https://github.com/madara-alliance/madara/blob/main/crates/tests/src/lib.rs) +// and modified to fit the needs of this project. +pub struct MadaraCmd { + pub process: Option, + pub ready: bool, + pub rpc_url: Url, + pub tempdir: TempDir, + pub _port: MadaraPortNum, +} + +pub async fn wait_for_cond>>( + mut cond: impl FnMut() -> F, + duration: Duration, +) -> Result { + let mut attempt = 0; + loop { + let err = match cond().await { + Ok(result) => return Ok(result), + Err(err) => { + // Empty block, no action needed + err + } + }; + + attempt += 1; + if attempt >= 10 { + panic!("No answer from the node after {attempt} attempts: {:#}", err) + } + + tokio::time::sleep(duration).await; + } +} + +impl MadaraCmd { + pub fn db_dir(&self) -> &Path { + self.tempdir.path() + } + + pub async fn wait_for_ready(&mut self) -> &mut Self { + let endpoint = self.rpc_url.join("/health").unwrap(); + wait_for_cond( + || async { + let res = reqwest::get(endpoint.clone()).await?; + res.error_for_status()?; + anyhow::Ok(true) + }, + Duration::from_millis(1000), + ) + .await + .expect("Could not get health of Madara"); + self.ready = true; + self + } +} + +impl Drop for MadaraCmd { + fn drop(&mut self) { + let Some(mut child) = self.process.take() else { return }; + let kill = || { + let mut kill = Command::new("kill").args(["-s", "TERM", &child.id().to_string()]).spawn()?; + kill.wait()?; + anyhow::Ok(()) + }; + if let Err(_err) = kill() { + child.kill().unwrap() + } + child.wait().unwrap(); + } +} + +// this really should use unix sockets, sad + +const PORT_RANGE: Range = 19944..20000; + +struct AvailablePorts> { + to_reuse: Vec, + next: I, +} + +lazy_static::lazy_static! { + static ref AVAILABLE_PORTS: Mutex>> = Mutex::new(AvailablePorts { to_reuse: vec![], next: PORT_RANGE }); +} + +pub struct MadaraPortNum(pub u16); +impl Drop for MadaraPortNum { + fn drop(&mut self) { + let mut guard = AVAILABLE_PORTS.lock().expect("poisoned lock"); + guard.to_reuse.push(self.0); + } +} + +pub fn get_port() -> MadaraPortNum { + let mut guard = AVAILABLE_PORTS.lock().expect("poisoned lock"); + if let Some(el) = guard.to_reuse.pop() { + return MadaraPortNum(el); + } + MadaraPortNum(guard.next.next().expect("no more port to use")) +} + +pub struct MadaraCmdBuilder { + args: Vec, + env: HashMap, + tempdir: TempDir, + port: MadaraPortNum, +} + +impl Default for MadaraCmdBuilder { + fn default() -> Self { + Self::new() + } +} + +impl MadaraCmdBuilder { + pub fn new() -> Self { + Self { + args: Default::default(), + env: Default::default(), + tempdir: TempDir::with_prefix("madara-test").unwrap(), + port: get_port(), + } + } + + pub fn args(mut self, args: impl IntoIterator>) -> Self { + self.args = args.into_iter().map(Into::into).collect(); + self + } + + pub fn env(mut self, env: impl IntoIterator, impl Into)>) -> Self { + self.env = env.into_iter().map(|(k, v)| (k.into(), v.into())).collect(); + self + } + + pub fn run(self) -> MadaraCmd { + let target_bin = env::var("MADARA_BINARY_PATH").expect("failed to get binary path"); + let target_bin = PathBuf::from(target_bin); + + if !target_bin.exists() { + panic!("No binary to run: {:?}", target_bin) + } + + let process = Command::new(target_bin) + .envs(self.env) + .args(self.args.into_iter().chain([ + "--telemetry-disabled".into(), // important: disable telemetry!! + "--no-prometheus".into(), + "--base-path".into(), + format!("{}", self.tempdir.as_ref().display()), + "--rpc-port".into(), + format!("{}", self.port.0), + ])) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + MadaraCmd { + process: Some(process), + ready: false, + rpc_url: Url::parse(&format!("http://127.0.0.1:{}/", self.port.0)).unwrap(), + tempdir: self.tempdir, + _port: self.port, + } + } +} diff --git a/crates/settlement-clients/starknet/src/tests/test.rs b/crates/settlement-clients/starknet/src/tests/test.rs new file mode 100644 index 00000000..f7aa2880 --- /dev/null +++ b/crates/settlement-clients/starknet/src/tests/test.rs @@ -0,0 +1,185 @@ +use super::setup::{wait_for_cond, MadaraCmd, MadaraCmdBuilder}; +use crate::{LocalWalletSignerMiddleware, StarknetSettlementClient}; +use rstest::{fixture, rstest}; +use settlement_client_interface::SettlementClient; +use starknet::{ + accounts::{Account, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount}, + contract::ContractFactory, + core::types::{ + contract::{CompiledClass, SierraClass}, + BlockId, BlockTag, DeclareTransactionResult, Felt, FunctionCall, InvokeTransactionResult, StarknetError, + TransactionExecutionStatus, TransactionStatus, + }, + macros::{felt, selector}, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError, Url}, + signers::{LocalWallet, SigningKey}, +}; +use std::env; +use std::path::Path; +use std::sync::Arc; +use std::time::Duration; +use utils::settings::env::EnvSettingsProvider; +use utils::settings::Settings; + +#[fixture] +pub async fn spin_up_madara() -> MadaraCmd { + dotenvy::from_filename_override(".env.test").expect("Failed to load the .env file"); + log::trace!("Spinning up Madara"); + let mut node = MadaraCmdBuilder::new() + .args([ + "--no-sync-polling", + "--devnet", + "--no-l1-sync", + "--chain-config-path=./src/tests/preset.yml", + "--rpc-cors", + "all", + ]) + .run(); + node.wait_for_ready().await; + node +} + +async fn wait_for_tx(account: &LocalWalletSignerMiddleware, transaction_hash: Felt, duration: Duration) -> bool { + let result = wait_for_cond( + || async { + let receipt = match account.provider().get_transaction_status(transaction_hash).await { + Ok(receipt) => Ok(receipt), + Err(ProviderError::StarknetError(StarknetError::TransactionHashNotFound)) => { + Err(anyhow::anyhow!("Transaction not yet received")) + } + _ => Err(anyhow::anyhow!("Unknown error")), + }; + + match receipt { + Ok(TransactionStatus::Received) => Err(anyhow::anyhow!("Transaction not yet received")), + Ok(TransactionStatus::Rejected) => Ok(false), + Ok(TransactionStatus::AcceptedOnL2(status)) => match status { + TransactionExecutionStatus::Succeeded => Ok(true), + TransactionExecutionStatus::Reverted => Ok(false), + }, + Ok(TransactionStatus::AcceptedOnL1(status)) => match status { + TransactionExecutionStatus::Succeeded => Ok(true), + TransactionExecutionStatus::Reverted => Ok(false), + }, + Err(e) => Err(anyhow::anyhow!("Unknown error: {}", e)), + } + }, + duration, + ) + .await; + match result { + Ok(true) => true, + Ok(false) => false, + Err(e) => panic!("Error while waiting for transaction: {}", e), + } +} + +#[fixture] +async fn setup(#[future] spin_up_madara: MadaraCmd) -> (LocalWalletSignerMiddleware, MadaraCmd) { + let madara_process = spin_up_madara.await; + env::set_var("STARKNET_RPC_URL", madara_process.rpc_url.to_string()); + + let env_settings = EnvSettingsProvider::default(); + let rpc_url = Url::parse(&env_settings.get_settings_or_panic("STARKNET_RPC_URL")).unwrap(); + + let provider = Arc::new(JsonRpcClient::new(HttpTransport::new(rpc_url))); + let signer = LocalWallet::from(SigningKey::from_secret_scalar( + Felt::from_hex(&env_settings.get_settings_or_panic("STARKNET_PRIVATE_KEY")).expect("Invalid private key"), + )); + let address = Felt::from_hex(&env_settings.get_settings_or_panic("STARKNET_ACCOUNT_ADDRESS")).unwrap(); + + let chain_id = provider.chain_id().await.unwrap(); + let mut account = SingleOwnerAccount::new(provider, signer, address, chain_id, ExecutionEncoding::New); + + // `SingleOwnerAccount` defaults to checking nonce and estimating fees against the latest + // block. Optionally change the target block to pending with the following line: + account.set_block_id(BlockId::Tag(BlockTag::Pending)); + (Arc::new(account), madara_process) +} + +#[rstest] +#[tokio::test] +async fn test_settle(#[future] setup: (LocalWalletSignerMiddleware, MadaraCmd)) { + let (account, _madara_process) = setup.await; + + let project_root = Path::new(env!("CARGO_MANIFEST_DIR")).ancestors().nth(3).unwrap(); + let contract_path = project_root.join("crates/settlement-clients/starknet/src/tests/mock_contracts/target/dev"); + let sierra_class: SierraClass = serde_json::from_reader( + std::fs::File::open(contract_path.join("mock_contracts_Piltover.contract_class.json")) + .expect("Could not open sierra class file"), + ) + .expect("Failed to parse SierraClass"); + + let compiled_class: CompiledClass = serde_json::from_reader( + std::fs::File::open(contract_path.join("mock_contracts_Piltover.compiled_contract_class.json")) + .expect("Could not open compiled class file"), + ) + .expect("Failed to parse CompiledClass"); + + let flattened_class = sierra_class.clone().flatten().unwrap(); + let compiled_class_hash = compiled_class.class_hash().unwrap(); + + let DeclareTransactionResult { transaction_hash: declare_tx_hash, class_hash: _ } = + account.declare_v2(Arc::new(flattened_class.clone()), compiled_class_hash).send().await.unwrap(); + log::debug!("declare tx hash {:?}", declare_tx_hash); + + let is_success = wait_for_tx(&account, declare_tx_hash, Duration::from_secs(2)).await; + assert!(is_success, "Declare trasactiion failed"); + + let contract_factory = ContractFactory::new(flattened_class.class_hash(), account.clone()); + let deploy_v1 = contract_factory.deploy_v1(vec![], felt!("1122"), false); + let deployed_address = deploy_v1.deployed_address(); + + env::set_var("STARKNET_CAIRO_CORE_CONTRACT_ADDRESS", deployed_address.to_hex_string()); + let InvokeTransactionResult { transaction_hash: deploy_tx_hash } = + deploy_v1.send().await.expect("Unable to deploy contract"); + + let is_success = wait_for_tx(&account, deploy_tx_hash, Duration::from_secs(2)).await; + assert!(is_success, "Deploy trasaction failed"); + + let env_settings = EnvSettingsProvider {}; + let settlement_client = StarknetSettlementClient::new_with_settings(&env_settings).await; + let onchain_data_hash = [1; 32]; + let mut program_output = Vec::with_capacity(32); + program_output.fill(onchain_data_hash); + let update_state_tx_hash = settlement_client + .update_state_calldata(program_output, onchain_data_hash, [1; 32]) + .await + .expect("Sending Update state"); + + log::debug!("update state tx hash {:?}", update_state_tx_hash); + + let is_success = wait_for_tx( + &account, + Felt::from_hex(&update_state_tx_hash).expect("Incorrect transaction hash"), + Duration::from_secs(2), + ) + .await; + assert!(is_success, "Update state transaction failed/reverted"); + + let call_result = account + .provider() + .call( + FunctionCall { + contract_address: deployed_address, + entry_point_selector: selector!("get_is_updated"), + calldata: vec![Felt::from_bytes_be_slice(&onchain_data_hash)], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await + .expect("failed to call the contract"); + assert!(call_result[0] == true.into(), "Should be updated"); +} + +#[rstest] +#[tokio::test] +async fn test_get_nonce_works(#[future] setup: (LocalWalletSignerMiddleware, MadaraCmd)) { + let (account, _madara_process) = setup.await; + let nonce = account.get_nonce().await; + match &nonce { + Ok(n) => log::info!("Nonce value from get_nonce: {:?}", n), + Err(e) => log::error!("Error getting nonce: {:?}", e), + } + assert!(nonce.is_ok(), "Failed to get nonce"); +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..e2c4df03 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +services: + localstack: + image: localstack/localstack + container_name: localstack + environment: + - DEFAULT_REGION=us-east-1 + - AWS_ACCESS_KEY_ID=AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY=AWS_SECRET_ACCESS_KEY + ports: + - "4566:4566" + + mongodb: + image: mongo:latest + container_name: mongodb + ports: + - "27017:27017" diff --git a/e2e-tests/tests.rs b/e2e-tests/tests.rs index 54314c5a..16a43821 100644 --- a/e2e-tests/tests.rs +++ b/e2e-tests/tests.rs @@ -13,11 +13,10 @@ use orchestrator::queue::job_queue::WorkerTriggerType; use rstest::rstest; use serde::{Deserialize, Serialize}; use serde_json::json; -use starknet::core::types::{FieldElement, MaybePendingStateUpdate}; +use starknet::core::types::{Felt, MaybePendingStateUpdate}; use std::collections::HashMap; use std::fs::{read, File}; use std::io::Read; -use std::str::FromStr; use std::time::{Duration, Instant}; use utils::env_utils::get_env_var_or_panic; use uuid::Uuid; @@ -327,7 +326,7 @@ pub async fn mock_starknet_get_nonce(starknet_client: &mut StarknetClient, l2_bl let vec: Vec = serde_json::from_str(&contents).unwrap(); for ele in vec { - let address = FieldElement::from_str(&ele.address).unwrap(); + let address = Felt::from_dec_str(&ele.address).expect("Failed to convert to felt"); let hex_field_element = vec_u8_to_hex_string(&address.to_bytes_be()); let response = json!({ "id": 640641,"jsonrpc":"2.0","result": ele.nonce });