diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a22be2289..99b3cdf15 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -214,42 +214,42 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} files: lcov.info - snos-integration-test: - needs: [fmt, clippy] - runs-on: ubuntu-latest-32-cores - timeout-minutes: 30 - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false) - container: - image: ghcr.io/dojoengine/katana-dev:latest - env: - MLIR_SYS_190_PREFIX: /usr/lib/llvm-19/ - LLVM_SYS_191_PREFIX: /usr/lib/llvm-19/ - TABLEGEN_190_PREFIX: /usr/lib/llvm-19/ - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - # Workaround for https://github.com/actions/runner-images/issues/6775 - - run: git config --global --add safe.directory "*" + # snos-integration-test: + # needs: [fmt, clippy] + # runs-on: ubuntu-latest-32-cores + # timeout-minutes: 30 + # if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false) + # container: + # image: ghcr.io/dojoengine/katana-dev:latest + # env: + # MLIR_SYS_190_PREFIX: /usr/lib/llvm-19/ + # LLVM_SYS_191_PREFIX: /usr/lib/llvm-19/ + # TABLEGEN_190_PREFIX: /usr/lib/llvm-19/ + # steps: + # - uses: actions/checkout@v3 + # with: + # submodules: recursive + # # Workaround for https://github.com/actions/runner-images/issues/6775 + # - run: git config --global --add safe.directory "*" - - uses: Swatinem/rust-cache@v2 - with: - key: ci-${{ github.job }} - shared-key: katana-ci-cache + # - uses: Swatinem/rust-cache@v2 + # with: + # key: ci-${{ github.job }} + # shared-key: katana-ci-cache - - name: Download test artifacts - uses: actions/download-artifact@v5 - with: - name: test-artifacts + # - name: Download test artifacts + # uses: actions/download-artifact@v5 + # with: + # name: test-artifacts - - name: Prepare SNOS test environment - run: | - if [ ! -d "./tests/snos/snos/build" ]; then - make snos-artifacts - fi + # - name: Prepare SNOS test environment + # run: | + # if [ ! -d "./tests/snos/snos/build" ]; then + # make snos-artifacts + # fi - - run: | - cargo run -p snos-integration-test + # - run: | + # cargo run -p snos-integration-test explorer-reverse-proxy: needs: [fmt, clippy, build-katana-binary] diff --git a/.gitignore b/.gitignore index 8ee46c026..856d0f9ec 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ output.txt crates/benches/bench_results.txt **/generated .vscode -bindings justfile spawn-and-move-db types-test-db diff --git a/Cargo.lock b/Cargo.lock index b0baba56f..0168bb66c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,7 +401,7 @@ dependencies = [ "lru 0.13.0", "parking_lot", "pin-project 1.1.10", - "reqwest 0.12.22", + "reqwest", "serde", "serde_json", "thiserror 2.0.12", @@ -445,7 +445,7 @@ dependencies = [ "alloy-transport-http", "futures", "pin-project 1.1.10", - "reqwest 0.12.22", + "reqwest", "serde", "serde_json", "tokio", @@ -646,7 +646,7 @@ checksum = "0d3615ec64d775fec840f4e9d5c8e1f739eb1854d8d28db093fb3d4805e0cb53" dependencies = [ "alloy-json-rpc", "alloy-transport", - "reqwest 0.12.22", + "reqwest", "serde_json", "tower 0.5.2", "tracing", @@ -759,28 +759,12 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" -[[package]] -name = "apollo_config" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "clap", - "itertools 0.12.1", - "serde", - "serde_json", - "strum_macros 0.25.3", - "thiserror 1.0.69", - "tracing", - "validator", -] - [[package]] name = "apollo_config" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_infra_utils", "clap", "itertools 0.12.1", "serde", @@ -791,43 +775,20 @@ dependencies = [ "validator", ] -[[package]] -name = "apollo_infra" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "apollo_config 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_metrics 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "async-trait", - "hyper 0.14.32", - "rstest 0.17.0", - "serde", - "serde_json", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "thiserror 1.0.69", - "time", - "tokio", - "tower 0.4.13", - "tracing", - "tracing-subscriber", - "validator", -] - [[package]] name = "apollo_infra" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ - "apollo_config 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_metrics 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_config", + "apollo_infra_utils", + "apollo_metrics", "async-trait", "hyper 0.14.32", "rstest 0.17.0", "serde", "serde_json", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "thiserror 1.0.69", "time", "tokio", @@ -837,22 +798,6 @@ dependencies = [ "validator", ] -[[package]] -name = "apollo_infra_utils" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "assert-json-diff", - "cached", - "colored 3.0.0", - "serde", - "serde_json", - "socket2 0.5.10", - "tokio", - "toml", - "tracing", -] - [[package]] name = "apollo_infra_utils" version = "0.0.0" @@ -869,18 +814,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "apollo_metrics" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "indexmap 2.10.0", - "metrics 0.24.2", - "num-traits", - "paste", - "regex", -] - [[package]] name = "apollo_metrics" version = "0.0.0" @@ -893,15 +826,6 @@ dependencies = [ "regex", ] -[[package]] -name = "apollo_proc_macros" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "quote", - "syn 2.0.104", -] - [[package]] name = "apollo_proc_macros" version = "0.0.0" @@ -911,39 +835,15 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "apollo_sierra_multicompile" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "apollo_config 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_infra 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_sierra_multicompile_types 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "async-trait", - "cairo-lang-sierra", - "cairo-lang-starknet-classes", - "cairo-lang-utils", - "rlimit", - "serde", - "serde_json", - "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "tempfile", - "thiserror 1.0.69", - "tracing", - "validator", -] - [[package]] name = "apollo_sierra_multicompile" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ - "apollo_config 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_infra 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_sierra_multicompile_types 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_config", + "apollo_infra", + "apollo_infra_utils", + "apollo_sierra_multicompile_types", "async-trait", "cairo-lang-sierra", "cairo-lang-starknet-classes", @@ -953,38 +853,24 @@ dependencies = [ "serde", "serde_json", "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "tempfile", "thiserror 1.0.69", "tracing", "validator", ] -[[package]] -name = "apollo_sierra_multicompile_types" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "apollo_infra 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_proc_macros 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "async-trait", - "serde", - "serde_json", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "thiserror 1.0.69", -] - [[package]] name = "apollo_sierra_multicompile_types" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ - "apollo_infra 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_proc_macros 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_infra", + "apollo_proc_macros", "async-trait", "serde", "serde_json", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "thiserror 1.0.69", ] @@ -1801,7 +1687,6 @@ checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", - "serde", "tap", "wyz", ] @@ -1815,71 +1700,26 @@ dependencies = [ "generic-array", ] -[[package]] -name = "blockifier" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "anyhow", - "apollo_config 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "apollo_sierra_multicompile 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "ark-ec 0.4.2", - "ark-ff 0.4.2", - "ark-secp256k1 0.4.0", - "ark-secp256r1 0.4.0", - "blockifier_test_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "cached", - "cairo-lang-casm", - "cairo-lang-runner", - "cairo-lang-starknet-classes", - "cairo-vm 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.20", - "indexmap 2.10.0", - "itertools 0.12.1", - "keccak", - "log", - "mockall", - "num-bigint", - "num-integer", - "num-rational", - "num-traits", - "paste", - "phf", - "rand 0.8.5", - "rstest 0.17.0", - "rstest_reuse 0.7.0", - "semver 1.0.26", - "serde", - "serde_json", - "sha2", - "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "strum 0.25.0", - "strum_macros 0.25.3", - "thiserror 1.0.69", -] - [[package]] name = "blockifier" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ "anyhow", - "apollo_config 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", - "apollo_sierra_multicompile 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_config", + "apollo_infra_utils", + "apollo_sierra_multicompile", "ark-ec 0.4.2", "ark-ff 0.4.2", "ark-secp256k1 0.4.0", "ark-secp256r1 0.4.0", - "blockifier_test_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "blockifier_test_utils", "cached", "cairo-lang-casm", "cairo-lang-runner", "cairo-lang-starknet-classes", "cairo-native", - "cairo-vm 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-vm", "derive_more 0.99.20", "indexmap 2.10.0", "itertools 0.12.1", @@ -1900,46 +1740,25 @@ dependencies = [ "serde_json", "sha2", "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "strum 0.25.0", "strum_macros 0.25.3", "thiserror 1.0.69", ] -[[package]] -name = "blockifier_test_utils" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "cairo-lang-starknet-classes", - "itertools 0.12.1", - "pretty_assertions", - "rstest 0.17.0", - "serde_json", - "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "strum 0.25.0", - "strum_macros 0.25.3", - "tempfile", - "tokio", - "tracing", - "tracing-test", -] - [[package]] name = "blockifier_test_utils" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_infra_utils", "cairo-lang-starknet-classes", "itertools 0.12.1", "pretty_assertions", "rstest 0.17.0", "serde_json", "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "strum 0.25.0", "strum_macros 0.25.3", "tempfile", @@ -2512,7 +2331,7 @@ dependencies = [ "cairo-lang-sierra-to-casm", "cairo-lang-sierra-type-size", "cairo-lang-utils", - "cairo-vm 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-vm", "itertools 0.14.0", "thiserror 2.0.12", ] @@ -2534,7 +2353,7 @@ dependencies = [ "cairo-lang-sierra-to-casm", "cairo-lang-starknet", "cairo-lang-utils", - "cairo-vm 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-vm", "itertools 0.14.0", "keccak", "num-bigint", @@ -2881,16 +2700,6 @@ dependencies = [ "utf8_iter", ] -[[package]] -name = "cairo-type-derive" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/snos?rev=c96eb9e#c96eb9e433c89da1a12a8a8474a30e6590431662" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "cairo-vm" version = "1.0.2" @@ -2923,42 +2732,6 @@ dependencies = [ "zip 0.6.6", ] -[[package]] -name = "cairo-vm" -version = "1.0.2" -source = "git+https://github.com/kariy/cairo-vm?branch=kariy%2F1.0.2_clear-cell#0881dafa5440b304fb000578b6f17c0a6e5f0595" -dependencies = [ - "anyhow", - "ark-ff 0.4.2", - "ark-std 0.4.0", - "bincode 2.0.1", - "bitvec", - "cairo-lang-casm", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "generic-array", - "hashbrown 0.14.5", - "hex", - "keccak", - "lazy_static", - "nom", - "num-bigint", - "num-integer", - "num-prime", - "num-traits", - "rand 0.8.5", - "rust_decimal", - "serde", - "serde_json", - "sha2", - "sha3", - "starknet-crypto 0.6.2", - "starknet-types-core", - "thiserror-no-std", - "wasm-bindgen", - "zip 0.6.6", -] - [[package]] name = "camino" version = "1.1.10" @@ -3003,7 +2776,7 @@ dependencies = [ "lazy_static", "num-bigint", "parking_lot", - "reqwest 0.12.22", + "reqwest", "serde", "serde_json", "stark-vrf", @@ -3661,10 +3434,11 @@ name = "db-compat-test" version = "1.7.0-alpha.3" dependencies = [ "anyhow", + "clap", "katana-chain-spec", - "katana-cli", "katana-db", "katana-node", + "katana-node-cli", "katana-primitives", "katana-provider", "starknet", @@ -3894,18 +3668,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" -[[package]] -name = "dummy" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac124e13ae9aa56acc4241f8c8207501d93afdd8d8e62f0c1f2e12f6508c65" -dependencies = [ - "darling 0.20.11", - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "dunce" version = "1.0.5" @@ -4013,15 +3775,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "endian-type" version = "0.1.2" @@ -4054,35 +3807,12 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "env_filter" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" -dependencies = [ - "log", - "regex", -] - [[package]] name = "env_home" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" -[[package]] -name = "env_logger" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -4148,18 +3878,6 @@ dependencies = [ "uint", ] -[[package]] -name = "fake" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d391ba4af7f1d93f01fcf7b2f29e2bc9348e109dfdbf4dcbdc51dfa38dab0b6" -dependencies = [ - "deunicode", - "dummy", - "rand 0.8.5", - "serde_json", -] - [[package]] name = "fastrand" version = "2.3.0" @@ -4241,7 +3959,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", - "libz-sys", "miniz_oxide", ] @@ -4422,7 +4139,7 @@ dependencies = [ "once_cell", "prost 0.13.5", "prost-types 0.13.5", - "reqwest 0.12.22", + "reqwest", "secret-vault-value", "serde", "serde_json", @@ -4449,10 +4166,10 @@ dependencies = [ "http 1.3.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls 0.27.7", + "hyper-rustls", "hyper-util", "ring", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "serde", "serde_json", "thiserror 1.0.69", @@ -4769,7 +4486,7 @@ dependencies = [ "url", "walkdir", "which 7.0.3", - "winreg 0.55.0", + "winreg", "zip 2.4.2", ] @@ -4957,20 +4674,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.32", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", -] - [[package]] name = "hyper-rustls" version = "0.27.7" @@ -5309,7 +5012,7 @@ checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ "console", "number_prefix", - "portable-atomic 1.11.1", + "portable-atomic", "unicode-width 0.2.1", "web-time", ] @@ -5491,39 +5194,15 @@ dependencies = [ ] [[package]] -name = "jiff" -version = "0.2.15" +name = "jni" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ - "jiff-static", - "log", - "portable-atomic 1.11.1", - "portable-atomic-util", - "serde", -] - -[[package]] -name = "jiff-static" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", + "cesu8", + "cfg-if", + "combine", + "jni-sys", "log", "thiserror 1.0.69", "walkdir", @@ -5636,7 +5315,7 @@ dependencies = [ "base64 0.22.1", "http-body 1.0.1", "hyper 1.6.0", - "hyper-rustls 0.27.7", + "hyper-rustls", "hyper-util", "jsonrpsee-core", "jsonrpsee-types", @@ -5775,8 +5454,8 @@ dependencies = [ "indicatif", "inquire", "katana-chain-spec", - "katana-cli", "katana-db", + "katana-node-cli", "katana-primitives", "katana-provider", "katana-rpc-client", @@ -5797,7 +5476,7 @@ dependencies = [ "tokio", "tracing", "url", - "vergen 9.0.6", + "vergen", "vergen-gitcl", ] @@ -5825,36 +5504,6 @@ dependencies = [ "url", ] -[[package]] -name = "katana-cli" -version = "1.7.0-alpha.3" -dependencies = [ - "alloy-primitives", - "anyhow", - "assert_matches", - "clap", - "console", - "katana-chain-spec", - "katana-core", - "katana-gas-price-oracle", - "katana-messaging", - "katana-node", - "katana-primitives", - "katana-rpc", - "katana-slot-controller", - "katana-tracing", - "katana-utils", - "serde", - "serde-utils", - "serde_json", - "shellexpand", - "starknet", - "tokio", - "toml", - "tracing", - "url", -] - [[package]] name = "katana-codecs" version = "1.7.0-alpha.3" @@ -5974,9 +5623,9 @@ dependencies = [ "alloy-primitives", "anyhow", "assert_matches", - "blockifier 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "blockifier", "cairo-native", - "cairo-vm 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-vm", "criterion", "katana-chain-spec", "katana-contracts", @@ -5995,7 +5644,7 @@ dependencies = [ "serde_json", "similar-asserts", "starknet", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "thiserror 1.0.69", "tokio", "tracing", @@ -6010,7 +5659,7 @@ dependencies = [ "http-body 1.0.1", "jsonrpsee", "katana-runner", - "reqwest 0.12.22", + "reqwest", "rust-embed", "serde", "serde_json", @@ -6027,7 +5676,7 @@ version = "1.7.0-alpha.3" dependencies = [ "katana-primitives", "katana-rpc-types", - "reqwest 0.12.22", + "reqwest", "rstest 0.18.2", "serde", "serde-utils", @@ -6075,7 +5724,7 @@ dependencies = [ "katana-utils", "num-traits", "parking_lot", - "reqwest 0.12.22", + "reqwest", "starknet", "thiserror 1.0.69", "tokio", @@ -6108,7 +5757,7 @@ dependencies = [ "katana-chain-spec", "katana-pool", "katana-primitives", - "reqwest 0.12.22", + "reqwest", "serde", "serde_json", "starknet", @@ -6153,6 +5802,7 @@ dependencies = [ "katana-gas-price-oracle", "katana-messaging", "katana-metrics", + "katana-node-defaults", "katana-pipeline", "katana-pool", "katana-primitives", @@ -6195,6 +5845,55 @@ dependencies = [ "url", ] +[[package]] +name = "katana-node-cli" +version = "1.7.0-alpha.3" +dependencies = [ + "alloy-primitives", + "anyhow", + "assert_matches", + "clap", + "console", + "katana-chain-spec", + "katana-core", + "katana-gas-price-oracle", + "katana-messaging", + "katana-node", + "katana-node-cli-args", + "katana-primitives", + "katana-slot-controller", + "katana-tracing", + "katana-utils", + "serde", + "serde_json", + "starknet", + "tokio", + "tracing", +] + +[[package]] +name = "katana-node-cli-args" +version = "1.7.0-alpha.3" +dependencies = [ + "anyhow", + "clap", + "http 1.3.1", + "katana-chain-spec", + "katana-node-defaults", + "katana-primitives", + "katana-tracing", + "serde", + "serde-utils", + "serde_json", + "shellexpand", + "toml", + "url", +] + +[[package]] +name = "katana-node-defaults" +version = "1.7.0-alpha.3" + [[package]] name = "katana-pipeline" version = "1.7.0-alpha.3" @@ -6247,10 +5946,10 @@ dependencies = [ "arbitrary", "assert_matches", "base64 0.21.7", - "blockifier 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "blockifier", "cainome-cairo-serde", "cairo-lang-starknet-classes", - "cairo-vm 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-vm", "criterion", "derive_more 0.99.20", "heapless", @@ -6269,7 +5968,7 @@ dependencies = [ "starknet", "starknet-crypto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "strum 0.25.0", "strum_macros 0.25.3", "thiserror 1.0.69", @@ -6424,7 +6123,7 @@ dependencies = [ "serde_with", "similar-asserts", "starknet", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "starknet_api", "thiserror 1.0.69", ] @@ -6715,17 +6414,6 @@ dependencies = [ "libc", ] -[[package]] -name = "libz-sys" -version = "1.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -6917,17 +6605,6 @@ dependencies = [ "libc", ] -[[package]] -name = "metrics" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b9b8653cec6897f73b519a43fba5ee3d50f62fe9af80b428accdcc093b4a849" -dependencies = [ - "ahash 0.7.8", - "metrics-macros", - "portable-atomic 0.3.20", -] - [[package]] name = "metrics" version = "0.23.1" @@ -6935,7 +6612,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3045b4193fbdc5b5681f32f11070da9be3609f189a79f3390706d42587f46bb5" dependencies = [ "ahash 0.8.12", - "portable-atomic 1.11.1", + "portable-atomic", ] [[package]] @@ -6945,7 +6622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" dependencies = [ "ahash 0.8.12", - "portable-atomic 1.11.1", + "portable-atomic", ] [[package]] @@ -6969,7 +6646,7 @@ dependencies = [ "base64 0.22.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls 0.27.7", + "hyper-rustls", "hyper-util", "indexmap 2.10.0", "ipnet", @@ -6981,17 +6658,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "metrics-macros" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731f8ecebd9f3a4aa847dfe75455e4757a45da40a7793d2f0b1f9b6ed18b23f3" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "metrics-process" version = "2.4.0" @@ -7143,7 +6809,7 @@ dependencies = [ "num-complex", "num-integer", "num-traits", - "portable-atomic 1.11.1", + "portable-atomic", "portable-atomic-util", "rawpointer", ] @@ -7489,7 +7155,7 @@ dependencies = [ "bytes", "http 1.3.1", "opentelemetry", - "reqwest 0.12.22", + "reqwest", ] [[package]] @@ -7504,7 +7170,7 @@ dependencies = [ "opentelemetry-proto", "opentelemetry_sdk", "prost 0.13.5", - "reqwest 0.12.22", + "reqwest", "thiserror 2.0.12", "tokio", "tonic 0.13.1", @@ -7673,56 +7339,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" -[[package]] -name = "pathfinder-common" -version = "0.14.3" -source = "git+https://github.com/Moonsong-Labs/pathfinder?rev=9c19d9a37be8f447ec4548456c440ccbd0e44260#9c19d9a37be8f447ec4548456c440ccbd0e44260" -dependencies = [ - "anyhow", - "bitvec", - "fake", - "metrics 0.20.1", - "num-bigint", - "paste", - "pathfinder-crypto", - "primitive-types", - "rand 0.8.5", - "serde", - "serde_json", - "serde_with", - "sha3", - "tagged", - "tagged-debug-derive", - "thiserror 1.0.69", - "vergen 8.3.2", -] - -[[package]] -name = "pathfinder-crypto" -version = "0.14.3" -source = "git+https://github.com/Moonsong-Labs/pathfinder?rev=9c19d9a37be8f447ec4548456c440ccbd0e44260#9c19d9a37be8f447ec4548456c440ccbd0e44260" -dependencies = [ - "bitvec", - "fake", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "pathfinder-serde" -version = "0.14.3" -source = "git+https://github.com/Moonsong-Labs/pathfinder?rev=9c19d9a37be8f447ec4548456c440ccbd0e44260#9c19d9a37be8f447ec4548456c440ccbd0e44260" -dependencies = [ - "anyhow", - "num-bigint", - "pathfinder-common", - "pathfinder-crypto", - "primitive-types", - "serde", - "serde_json", - "serde_with", -] - [[package]] name = "pbkdf2" version = "0.11.0" @@ -7951,15 +7567,6 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "portable-atomic" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e30165d31df606f5726b090ec7592c308a0eaf61721ff64c9a3018e344a8753e" -dependencies = [ - "portable-atomic 1.11.1", -] - [[package]] name = "portable-atomic" version = "1.11.1" @@ -7972,7 +7579,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" dependencies = [ - "portable-atomic 1.11.1", + "portable-atomic", ] [[package]] @@ -8333,39 +7940,6 @@ dependencies = [ "prost 0.14.1", ] -[[package]] -name = "prove_block" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/snos?rev=c96eb9e#c96eb9e433c89da1a12a8a8474a30e6590431662" -dependencies = [ - "anyhow", - "blockifier 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "cairo-lang-starknet-classes", - "cairo-lang-utils", - "cairo-vm 1.0.2 (git+https://github.com/kariy/cairo-vm?branch=kariy%2F1.0.2_clear-cell)", - "clap", - "env_logger", - "futures-core", - "log", - "num-bigint", - "pathfinder-common", - "pathfinder-crypto", - "pathfinder-serde", - "reqwest 0.11.27", - "rpc-client", - "rpc-replay", - "serde", - "serde_json", - "serde_with", - "starknet", - "starknet-os", - "starknet-os-types", - "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "ptr_meta" version = "0.1.4" @@ -8725,47 +8299,6 @@ dependencies = [ "bytecheck", ] -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.27", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.25.4", - "winreg 0.50.0", -] - [[package]] name = "reqwest" version = "0.12.22" @@ -8775,20 +8308,17 @@ dependencies = [ "async-compression", "base64 0.22.1", "bytes", - "encoding_rs", "futures-channel", "futures-core", "futures-util", - "h2 0.4.12", "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls 0.27.7", + "hyper-rustls", "hyper-util", "js-sys", "log", - "mime", "mime_guess", "percent-encoding", "pin-project-lite", @@ -8846,7 +8376,7 @@ dependencies = [ "anyhow", "headless_chrome", "nix 0.30.1", - "reqwest 0.12.22", + "reqwest", "tokio", ] @@ -8948,39 +8478,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" -[[package]] -name = "rpc-client" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/snos?rev=c96eb9e#c96eb9e433c89da1a12a8a8474a30e6590431662" -dependencies = [ - "log", - "reqwest 0.11.27", - "serde", - "serde_json", - "starknet", - "starknet-crypto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "starknet-os", - "starknet-types-core", - "thiserror 1.0.69", -] - -[[package]] -name = "rpc-replay" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/snos?rev=c96eb9e#c96eb9e433c89da1a12a8a8474a30e6590431662" -dependencies = [ - "blockifier 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "cairo-lang-starknet-classes", - "rpc-client", - "serde", - "serde_json", - "starknet", - "starknet-os-types", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "rsb_derive" version = "0.5.1" @@ -9251,18 +8748,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.4" @@ -9300,7 +8785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "rustls-pki-types", "schannel", "security-framework 2.11.1", @@ -9318,15 +8803,6 @@ dependencies = [ "security-framework 3.3.0", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -9373,16 +8849,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.102.8" @@ -9544,16 +9010,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "seahash" version = "4.1.0" @@ -9793,19 +9249,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.10.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "serdect" version = "0.2.0" @@ -10041,25 +9484,6 @@ dependencies = [ "serde", ] -[[package]] -name = "snos-integration-test" -version = "1.7.0-alpha.3" -dependencies = [ - "anyhow", - "c-kzg", - "cairo-vm 1.0.2 (git+https://github.com/kariy/cairo-vm?branch=kariy%2F1.0.2_clear-cell)", - "either", - "katana-chain-spec", - "katana-messaging", - "katana-node", - "katana-primitives", - "katana-provider", - "prove_block", - "starknet", - "starknet-os", - "tokio", -] - [[package]] name = "socket2" version = "0.5.10" @@ -10347,28 +9771,6 @@ dependencies = [ "serde", ] -[[package]] -name = "starknet-gateway-types" -version = "0.14.3" -source = "git+https://github.com/Moonsong-Labs/pathfinder?rev=9c19d9a37be8f447ec4548456c440ccbd0e44260#9c19d9a37be8f447ec4548456c440ccbd0e44260" -dependencies = [ - "anyhow", - "fake", - "pathfinder-common", - "pathfinder-crypto", - "pathfinder-serde", - "primitive-types", - "rand 0.8.5", - "reqwest 0.12.22", - "rstest 0.18.2", - "serde", - "serde_json", - "serde_with", - "sha3", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "starknet-macros" version = "0.2.5-rc.2" @@ -10378,79 +9780,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "starknet-os" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/snos?rev=c96eb9e#c96eb9e433c89da1a12a8a8474a30e6590431662" -dependencies = [ - "anyhow", - "ark-ec 0.4.2", - "ark-ff 0.4.2", - "ark-secp256k1 0.4.0", - "ark-secp256r1 0.4.0", - "base64 0.21.7", - "bitvec", - "blockifier 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "c-kzg", - "cairo-lang-casm", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "cairo-type-derive", - "cairo-vm 1.0.2 (git+https://github.com/kariy/cairo-vm?branch=kariy%2F1.0.2_clear-cell)", - "futures", - "futures-util", - "heck 0.4.1", - "hex", - "indexmap 2.10.0", - "indoc", - "keccak", - "lazy_static", - "log", - "num-bigint", - "num-integer", - "num-traits", - "pathfinder-common", - "pathfinder-crypto", - "reqwest 0.11.27", - "serde", - "serde_json", - "serde_with", - "serde_yaml", - "sha2", - "starknet-crypto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "starknet-gateway-types", - "starknet-os-types", - "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "thiserror 1.0.69", - "tokio", - "uuid 1.17.0", - "zip 0.6.6", -] - -[[package]] -name = "starknet-os-types" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/snos?rev=c96eb9e#c96eb9e433c89da1a12a8a8474a30e6590431662" -dependencies = [ - "blockifier 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "cairo-lang-starknet-classes", - "cairo-vm 1.0.2 (git+https://github.com/kariy/cairo-vm?branch=kariy%2F1.0.2_clear-cell)", - "flate2", - "num-bigint", - "once_cell", - "serde", - "serde_json", - "serde_with", - "starknet", - "starknet-crypto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "starknet-gateway-types", - "starknet-types-core", - "starknet_api 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "starknet-providers" version = "0.16.0-rc.2" @@ -10462,7 +9791,7 @@ dependencies = [ "flate2", "getrandom 0.2.16", "log", - "reqwest 0.12.22", + "reqwest", "serde", "serde_json", "serde_with", @@ -10505,45 +9834,12 @@ dependencies = [ "zeroize", ] -[[package]] -name = "starknet_api" -version = "0.0.0" -source = "git+https://github.com/dojoengine/sequencer?rev=4b1587c5e#4b1587c5e3effc4cfbbb8551cdcab6454a2dbe30" -dependencies = [ - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=4b1587c5e)", - "base64 0.13.1", - "bitvec", - "cached", - "cairo-lang-runner", - "cairo-lang-starknet-classes", - "derive_more 0.99.20", - "flate2", - "hex", - "indexmap 2.10.0", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "pretty_assertions", - "primitive-types", - "rand 0.8.5", - "semver 1.0.26", - "serde", - "serde_json", - "sha3", - "size-of", - "starknet-crypto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "starknet-types-core", - "strum 0.25.0", - "strum_macros 0.25.3", - "thiserror 1.0.69", -] - [[package]] name = "starknet_api" version = "0.0.0" source = "git+https://github.com/dojoengine/sequencer?rev=5d737b9c9#5d737b9c90a14bdf4483d759d1a1d4ce64aa9fd2" dependencies = [ - "apollo_infra_utils 0.0.0 (git+https://github.com/dojoengine/sequencer?rev=5d737b9c9)", + "apollo_infra_utils", "base64 0.13.1", "bitvec", "cached", @@ -10772,45 +10068,6 @@ dependencies = [ "windows 0.61.3", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tagged" -version = "0.14.3" -source = "git+https://github.com/Moonsong-Labs/pathfinder?rev=9c19d9a37be8f447ec4548456c440ccbd0e44260#9c19d9a37be8f447ec4548456c440ccbd0e44260" -dependencies = [ - "fake", -] - -[[package]] -name = "tagged-debug-derive" -version = "0.14.3" -source = "git+https://github.com/Moonsong-Labs/pathfinder?rev=9c19d9a37be8f447ec4548456c440ccbd0e44260#9c19d9a37be8f447ec4548456c440ccbd0e44260" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "tap" version = "1.0.1" @@ -11065,16 +10322,6 @@ dependencies = [ "tokio-stream", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.25.0" @@ -11185,7 +10432,7 @@ dependencies = [ "pin-project 1.1.10", "prost 0.12.6", "rustls-native-certs 0.7.3", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", @@ -11618,12 +10865,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "untrusted" version = "0.9.0" @@ -11675,7 +10916,7 @@ dependencies = [ "log", "percent-encoding", "rustls 0.23.31", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "rustls-pki-types", "ureq-proto", "utf-8", @@ -11748,7 +10989,6 @@ checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ "getrandom 0.3.3", "js-sys", - "serde", "wasm-bindgen", ] @@ -11797,24 +11037,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vergen" -version = "8.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" -dependencies = [ - "anyhow", - "cfg-if", - "rustversion", - "time", -] - [[package]] name = "vergen" version = "9.0.6" @@ -11842,7 +11064,7 @@ dependencies = [ "derive_builder", "rustversion", "time", - "vergen 9.0.6", + "vergen", "vergen-lib", ] @@ -12042,12 +11264,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.11" @@ -12646,16 +11862,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "winreg" version = "0.55.0" diff --git a/Cargo.toml b/Cargo.toml index 94f4dedb9..92bb661c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,8 @@ members = [ "bin/katana", "crates/cartridge", "crates/chain-spec", - "crates/cli", "crates/contracts", + "crates/contracts/macro", "crates/controller", "crates/core", "crates/executor", @@ -15,8 +15,11 @@ members = [ "crates/grpc", "crates/messaging", "crates/metrics", - "crates/node", - "crates/node-bindings", + "crates/node/node", + "crates/node/node-bindings", + "crates/node/node-cli", + "crates/node/node-cli-args", + "crates/node/node-defaults", "crates/oracle/gas", "crates/pool/pool", "crates/pool/pool-api", @@ -43,7 +46,7 @@ members = [ "crates/utils", "tests/db-compat", "tests/reverse-proxy", - "tests/snos", + # "tests/snos", ] [workspace.package] @@ -68,7 +71,6 @@ cartridge = { path = "crates/cartridge" } serde-utils = { path = "crates/serde-utils" } katana-chain-spec = { path = "crates/chain-spec" } -katana-cli = { path = "crates/cli" } katana-codecs = { path = "crates/storage/codecs" } katana-codecs-derive = { path = "crates/storage/codecs/derive" } katana-contracts = { path = "crates/contracts" } @@ -81,8 +83,11 @@ katana-fork = { path = "crates/storage/fork" } katana-gas-price-oracle = { path = "crates/oracle/gas" } katana-messaging = { path = "crates/messaging" } katana-metrics = { path = "crates/metrics" } -katana-node = { path = "crates/node" } -katana-node-bindings = { path = "crates/node-bindings" } +katana-node = { path = "crates/node/node" } +katana-node-bindings = { path = "crates/node/node-bindings" } +katana-node-cli = { path = "crates/node/node-cli" } +katana-node-cli-args = { path = "crates/node/node-cli-args" } +katana-node-defaults = { path = "crates/node/node-defaults" } katana-pipeline = { path = "crates/sync/pipeline" } katana-pool = { path = "crates/pool/pool" } katana-pool-api = { path = "crates/pool/pool-api" } @@ -221,6 +226,7 @@ starknet-types-core = { version = "0.1.8", features = [ "arbitrary", "hash" ] } cairo-vm = { version = "1.0.2", features = [ "test_utils" ] } blockifier = { git = "https://github.com/dojoengine/sequencer", rev = "5d737b9c9", default-features = false } +cairo-native = "0.4" starknet_api = { git = "https://github.com/dojoengine/sequencer", rev = "5d737b9c9" } cainome = { git = "https://github.com/cartridge-gg/cainome", rev = "7d60de1", features = [ "abigen-rs" ] } diff --git a/bin/katana/Cargo.toml b/bin/katana/Cargo.toml index 0fa740026..5199f2b03 100644 --- a/bin/katana/Cargo.toml +++ b/bin/katana/Cargo.toml @@ -8,8 +8,8 @@ version.workspace = true [dependencies] katana-chain-spec.workspace = true -katana-cli.workspace = true katana-db = { workspace = true, features = [ "arbitrary" ] } +katana-node-cli.workspace = true katana-primitives.workspace = true katana-rpc-client.workspace = true katana-rpc-types.workspace = true @@ -59,12 +59,12 @@ default = [ "client", "init-slot", "jemalloc", - "katana-cli/explorer", + "katana-node-cli/explorer", ] -cartridge = [ "katana-cli/cartridge" ] +cartridge = [ "katana-node-cli/cartridge" ] client = [ "dep:colored_json", "dep:serde", "dep:serde_json" ] init-custom-settlement-chain = [ ] init-slot = [ ] jemalloc = [ ] -native = [ "katana-cli/native" ] +native = [ "katana-node-cli/native" ] diff --git a/bin/katana/src/cli/mod.rs b/bin/katana/src/cli/mod.rs index 7c8949b2f..84e9b429c 100644 --- a/bin/katana/src/cli/mod.rs +++ b/bin/katana/src/cli/mod.rs @@ -3,7 +3,6 @@ use std::future::Future; use anyhow::{Context, Result}; use clap::{Args, CommandFactory, Parser, Subcommand}; use clap_complete::Shell; -use katana_cli::NodeArgs; use tokio::runtime::Runtime; mod config; @@ -23,7 +22,7 @@ pub struct Cli { commands: Option, #[command(flatten)] - node: NodeArgs, + node: katana_node_cli::Cli, } impl Cli { @@ -39,7 +38,7 @@ impl Cli { }; } - execute_async(self.node.with_config_file()?.execute())? + execute_async(self.node.execute())? } } diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs deleted file mode 100644 index 9b459f653..000000000 --- a/crates/cli/src/args.rs +++ /dev/null @@ -1,801 +0,0 @@ -//! Katana node CLI options and configuration. - -use std::path::PathBuf; -use std::sync::Arc; - -use alloy_primitives::U256; -#[cfg(feature = "server")] -use anyhow::bail; -use anyhow::{Context, Result}; -pub use clap::Parser; -use katana_chain_spec::rollup::ChainConfigDir; -use katana_chain_spec::ChainSpec; -use katana_core::constants::DEFAULT_SEQUENCER_ADDRESS; -use katana_messaging::MessagingConfig; -use katana_node::config::db::DbConfig; -use katana_node::config::dev::{DevConfig, FixedL1GasPriceConfig}; -use katana_node::config::execution::ExecutionConfig; -use katana_node::config::fork::ForkingConfig; -use katana_node::config::metrics::MetricsConfig; -#[cfg(feature = "cartridge")] -use katana_node::config::paymaster::PaymasterConfig; -use katana_node::config::rpc::RpcConfig; -#[cfg(feature = "server")] -use katana_node::config::rpc::{RpcModuleKind, RpcModulesList}; -use katana_node::config::sequencing::SequencingConfig; -use katana_node::config::Config; -use katana_node::Node; -use katana_primitives::genesis::allocation::DevAllocationsGenerator; -use katana_primitives::genesis::constant::DEFAULT_PREFUNDED_ACCOUNT_BALANCE; -use serde::{Deserialize, Serialize}; -use tracing::info; -use url::Url; - -use crate::file::NodeArgsConfig; -use crate::options::*; -use crate::utils::{self, parse_chain_config_dir, parse_seed}; - -pub(crate) const LOG_TARGET: &str = "katana::cli"; - -#[derive(Parser, Debug, Serialize, Deserialize, Default, Clone)] -#[command(next_help_heading = "Node options")] -pub struct NodeArgs { - /// Don't print anything on startup. - #[arg(long)] - pub silent: bool, - - /// Path to the chain configuration file. - #[arg(long, hide = true)] - #[arg(value_parser = parse_chain_config_dir)] - pub chain: Option, - - /// Disable auto and interval mining, and mine on demand instead via an endpoint. - #[arg(long)] - #[arg(conflicts_with = "block_time")] - pub no_mining: bool, - - /// Block time in milliseconds for interval mining. - #[arg(short, long)] - #[arg(value_name = "MILLISECONDS")] - pub block_time: Option, - - #[arg(long = "sequencing.block-max-cairo-steps")] - #[arg(value_name = "TOTAL")] - pub block_cairo_steps_limit: Option, - - /// Directory path of the database to initialize from. - /// - /// The path must either be an empty directory or a directory which already contains a - /// previously initialized Katana database. - #[arg(long)] - #[arg(value_name = "PATH")] - pub db_dir: Option, - - /// Configuration file - #[arg(long)] - pub config: Option, - - /// Configure the messaging with an other chain. - /// - /// Configure the messaging to allow Katana listening/sending messages on a - /// settlement chain that can be Ethereum or an other Starknet sequencer. - #[arg(long)] - #[arg(value_name = "PATH")] - #[arg(value_parser = katana_messaging::MessagingConfig::parse)] - #[arg(conflicts_with = "chain")] - pub messaging: Option, - - #[arg(long = "l1.provider", value_name = "URL", alias = "l1-provider")] - #[arg(help = "The Ethereum RPC provider to sample the gas prices from to enable the gas \ - price oracle.")] - pub l1_provider_url: Option, - - #[command(flatten)] - pub logging: LoggingOptions, - - #[command(flatten)] - pub tracer: TracerOptions, - - #[cfg(feature = "server")] - #[command(flatten)] - pub metrics: MetricsOptions, - - #[cfg(feature = "server")] - #[command(flatten)] - pub server: ServerOptions, - - #[command(flatten)] - pub starknet: StarknetOptions, - - #[command(flatten)] - pub gpo: GasPriceOracleOptions, - - #[command(flatten)] - pub forking: ForkingOptions, - - #[command(flatten)] - pub development: DevOptions, - - #[cfg(feature = "explorer")] - #[command(flatten)] - pub explorer: ExplorerOptions, - - #[cfg(feature = "cartridge")] - #[command(flatten)] - pub cartridge: CartridgeOptions, -} - -impl NodeArgs { - pub async fn execute(&self) -> Result<()> { - // Initialize logging with tracer - let tracer_config = self.tracer_config(); - katana_tracing::init(self.logging.log_format, tracer_config).await?; - self.start_node().await - } - - async fn start_node(&self) -> Result<()> { - // Build the node - let config = self.config()?; - let node = Node::build(config).await.context("failed to build node")?; - - if !self.silent { - utils::print_intro(self, &node.backend().chain_spec); - } - - // Launch the node - let handle = node.launch().await.context("failed to launch node")?; - - // Wait until an OS signal (ie SIGINT, SIGTERM) is received or the node is shutdown. - tokio::select! { - _ = katana_utils::wait_shutdown_signals() => { - // Gracefully shutdown the node before exiting - handle.stop().await?; - }, - - _ = handle.stopped() => { } - } - - info!("Shutting down."); - - Ok(()) - } - - pub fn config(&self) -> Result { - let db = self.db_config(); - let rpc = self.rpc_config()?; - let dev = self.dev_config(); - let (chain, cs_messaging) = self.chain_spec()?; - let metrics = self.metrics_config(); - let forking = self.forking_config()?; - let execution = self.execution_config(); - let sequencing = self.sequencer_config(); - - // the `katana init` will automatically generate a messaging config. so if katana is run - // with `--chain` then the `--messaging` flag is not required. this is temporary and - // the messagign config will eventually be removed slowly. - let messaging = if cs_messaging.is_some() { cs_messaging } else { self.messaging.clone() }; - - #[cfg(feature = "cartridge")] - { - let paymaster = self.cartridge_config(); - - Ok(Config { - db, - dev, - rpc, - chain, - metrics, - forking, - execution, - messaging, - paymaster, - sequencing, - }) - } - - #[cfg(not(feature = "cartridge"))] - Ok(Config { metrics, db, dev, rpc, chain, execution, sequencing, messaging, forking }) - } - - fn sequencer_config(&self) -> SequencingConfig { - SequencingConfig { - block_time: self.block_time, - no_mining: self.no_mining, - block_cairo_steps_limit: self.block_cairo_steps_limit, - } - } - - pub fn rpc_config(&self) -> Result { - #[cfg(feature = "server")] - { - use std::time::Duration; - - #[allow(unused_mut)] - let mut modules = if let Some(modules) = &self.server.http_modules { - // TODO: This check should be handled in the `katana-node` level. Right now if you - // instantiate katana programmatically, you can still add the dev module without - // enabling dev mode. - // - // We only allow the `dev` module in dev mode (ie `--dev` flag) - if !self.development.dev && modules.contains(&RpcModuleKind::Dev) { - bail!("The `dev` module can only be enabled in dev mode (ie `--dev` flag)") - } - - modules.clone() - } else { - // Expose the default modules if none is specified. - let mut modules = RpcModulesList::default(); - - // Ensures the `--dev` flag enabled the dev module. - if self.development.dev { - modules.add(RpcModuleKind::Dev); - } - - modules - }; - - // The cartridge rpc must be enabled if the paymaster is enabled. - // We put it here so that even when the individual api are explicitly specified - // (ie `--rpc.api`) we guarantee that the cartridge rpc is enabled. - #[cfg(feature = "cartridge")] - if self.cartridge.paymaster { - modules.add(RpcModuleKind::Cartridge); - } - - let cors_origins = self.server.http_cors_origins.clone(); - - Ok(RpcConfig { - apis: modules, - port: self.server.http_port, - addr: self.server.http_addr, - max_connections: self.server.max_connections, - max_concurrent_estimate_fee_requests: None, - max_request_body_size: None, - max_response_body_size: None, - timeout: self.server.timeout.map(Duration::from_secs), - cors_origins, - #[cfg(feature = "explorer")] - explorer: self.explorer.explorer, - max_event_page_size: Some(self.server.max_event_page_size), - max_proof_keys: Some(self.server.max_proof_keys), - max_call_gas: Some(self.server.max_call_gas), - }) - } - - #[cfg(not(feature = "server"))] - { - Ok(RpcConfig::default()) - } - } - - fn chain_spec(&self) -> Result<(Arc, Option)> { - if let Some(path) = &self.chain { - let mut cs = katana_chain_spec::rollup::read(path)?; - cs.genesis.sequencer_address = *DEFAULT_SEQUENCER_ADDRESS; - let messaging_config = MessagingConfig::from_chain_spec(&cs); - Ok((Arc::new(ChainSpec::Rollup(cs)), Some(messaging_config))) - } - // exclusively for development mode - else { - let mut chain_spec = katana_chain_spec::dev::DEV_UNALLOCATED.clone(); - - if let Some(id) = self.starknet.environment.chain_id { - chain_spec.id = id; - } - - if let Some(genesis) = &self.starknet.genesis { - chain_spec.genesis = genesis.clone(); - } else { - chain_spec.genesis.sequencer_address = *DEFAULT_SEQUENCER_ADDRESS; - } - - // Generate dev accounts. - // If `cartridge` is enabled, the first account will be the paymaster. - let accounts = DevAllocationsGenerator::new(self.development.total_accounts) - .with_seed(parse_seed(&self.development.seed)) - .with_balance(U256::from(DEFAULT_PREFUNDED_ACCOUNT_BALANCE)) - .generate(); - - chain_spec.genesis.extend_allocations(accounts.into_iter().map(|(k, v)| (k, v.into()))); - - #[cfg(feature = "cartridge")] - if self.cartridge.controllers || self.cartridge.paymaster { - katana_slot_controller::add_controller_classes(&mut chain_spec.genesis); - katana_slot_controller::add_vrf_provider_class(&mut chain_spec.genesis); - } - - Ok((Arc::new(ChainSpec::Dev(chain_spec)), None)) - } - } - - fn dev_config(&self) -> DevConfig { - let mut fixed_gas_prices = None; - - if let Some(eth) = self.gpo.l2_eth_gas_price { - let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); - prices.l2_gas_prices.eth = eth; - } - - if let Some(strk) = self.gpo.l2_strk_gas_price { - let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); - prices.l2_gas_prices.strk = strk; - } - - if let Some(eth) = self.gpo.l1_eth_gas_price { - let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); - prices.l1_gas_prices.eth = eth; - } - - if let Some(strk) = self.gpo.l1_strk_gas_price { - let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); - prices.l1_gas_prices.strk = strk; - } - - if let Some(eth) = self.gpo.l1_eth_data_gas_price { - let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); - prices.l1_data_gas_prices.eth = eth; - } - - if let Some(strk) = self.gpo.l1_strk_data_gas_price { - let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); - prices.l1_data_gas_prices.strk = strk; - } - - DevConfig { - fixed_gas_prices, - fee: !self.development.no_fee, - account_validation: !self.development.no_account_validation, - } - } - - fn execution_config(&self) -> ExecutionConfig { - ExecutionConfig { - invocation_max_steps: self.starknet.environment.invoke_max_steps, - validation_max_steps: self.starknet.environment.validate_max_steps, - #[cfg(feature = "native")] - compile_native: self.starknet.environment.compile_native, - ..Default::default() - } - } - - fn forking_config(&self) -> Result> { - if let Some(ref url) = self.forking.fork_provider { - let cfg = ForkingConfig { url: url.clone(), block: self.forking.fork_block }; - return Ok(Some(cfg)); - } - - Ok(None) - } - - fn db_config(&self) -> DbConfig { - DbConfig { dir: self.db_dir.clone() } - } - - fn metrics_config(&self) -> Option { - #[cfg(feature = "server")] - if self.metrics.metrics { - Some(MetricsConfig { addr: self.metrics.metrics_addr, port: self.metrics.metrics_port }) - } else { - None - } - - #[cfg(not(feature = "server"))] - None - } - - #[cfg(feature = "cartridge")] - fn cartridge_config(&self) -> Option { - if self.cartridge.paymaster { - Some(PaymasterConfig { cartridge_api_url: self.cartridge.api.clone() }) - } else { - None - } - } - - /// Parse the node config from the command line arguments and the config file, - /// and merge them together prioritizing the command line arguments. - pub fn with_config_file(mut self) -> Result { - let config = if let Some(path) = &self.config { - NodeArgsConfig::read(path)? - } else { - return Ok(self); - }; - - // the CLI (self) takes precedence over the config file. - // Currently, the merge is made at the top level of the commands. - // We may add recursive merging in the future. - - if !self.no_mining { - self.no_mining = config.no_mining.unwrap_or_default(); - } - - if self.block_time.is_none() { - self.block_time = config.block_time; - } - - if self.db_dir.is_none() { - self.db_dir = config.db_dir; - } - - if self.logging == LoggingOptions::default() { - if let Some(logging) = config.logging { - self.logging = logging; - } - } - - if self.messaging.is_none() { - self.messaging = config.messaging; - } - - #[cfg(feature = "server")] - { - self.server.merge(config.server.as_ref()); - - if self.metrics == MetricsOptions::default() { - if let Some(metrics) = config.metrics { - self.metrics = metrics; - } - } - } - - self.starknet.merge(config.starknet.as_ref()); - self.development.merge(config.development.as_ref()); - - if self.gpo == GasPriceOracleOptions::default() { - if let Some(gpo) = config.gpo { - self.gpo = gpo; - } - } - - if self.forking == ForkingOptions::default() { - if let Some(forking) = config.forking { - self.forking = forking; - } - } - - #[cfg(feature = "cartridge")] - { - self.cartridge.merge(config.cartridge.as_ref()); - } - - Ok(self) - } - - fn tracer_config(&self) -> Option { - self.tracer.config() - } -} - -#[cfg(test)] -mod test { - use std::str::FromStr; - - use assert_matches::assert_matches; - use katana_gas_price_oracle::{ - DEFAULT_ETH_L1_DATA_GAS_PRICE, DEFAULT_ETH_L1_GAS_PRICE, DEFAULT_ETH_L2_GAS_PRICE, - DEFAULT_STRK_L1_DATA_GAS_PRICE, DEFAULT_STRK_L1_GAS_PRICE, - }; - use katana_node::config::execution::{ - DEFAULT_INVOCATION_MAX_STEPS, DEFAULT_VALIDATION_MAX_STEPS, - }; - use katana_node::config::rpc::RpcModuleKind; - use katana_primitives::chain::ChainId; - use katana_primitives::{address, felt, ContractAddress, Felt}; - - use super::*; - - #[test] - fn test_starknet_config_default() { - let args = NodeArgs::parse_from(["katana"]); - let config = args.config().unwrap(); - - assert!(config.dev.fee); - assert!(config.dev.account_validation); - assert!(config.forking.is_none()); - assert_eq!(config.execution.invocation_max_steps, DEFAULT_INVOCATION_MAX_STEPS); - assert_eq!(config.execution.validation_max_steps, DEFAULT_VALIDATION_MAX_STEPS); - assert_eq!(config.db.dir, None); - assert_eq!(config.chain.id(), ChainId::parse("KATANA").unwrap()); - assert_eq!(config.chain.genesis().sequencer_address, *DEFAULT_SEQUENCER_ADDRESS); - } - - #[test] - fn test_starknet_config_custom() { - let args = NodeArgs::parse_from([ - "katana", - "--dev", - "--dev.no-fee", - "--dev.no-account-validation", - "--chain-id", - "SN_GOERLI", - "--invoke-max-steps", - "200", - "--validate-max-steps", - "100", - "--db-dir", - "/path/to/db", - ]); - let config = args.config().unwrap(); - - assert!(!config.dev.fee); - assert!(!config.dev.account_validation); - assert_eq!(config.execution.invocation_max_steps, 200); - assert_eq!(config.execution.validation_max_steps, 100); - assert_eq!(config.db.dir, Some(PathBuf::from("/path/to/db"))); - assert_eq!(config.chain.id(), ChainId::GOERLI); - assert_eq!(config.chain.genesis().sequencer_address, *DEFAULT_SEQUENCER_ADDRESS); - } - - #[test] - fn custom_fixed_gas_prices() { - let config = NodeArgs::parse_from(["katana"]).config().unwrap(); - assert!(config.dev.fixed_gas_prices.is_none()); - - let config = - NodeArgs::parse_from(["katana", "--gpo.l1-eth-gas-price", "10"]).config().unwrap(); - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth.get(), 10); - assert_eq!(prices.l1_gas_prices.strk, DEFAULT_ETH_L2_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.eth, DEFAULT_ETH_L1_DATA_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.strk, DEFAULT_STRK_L1_DATA_GAS_PRICE); - }); - - let config = - NodeArgs::parse_from(["katana", "--gpo.l1-strk-gas-price", "20"]).config().unwrap(); - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth, DEFAULT_ETH_L1_GAS_PRICE); - assert_eq!(prices.l1_gas_prices.strk.get(), 20); - assert_eq!(prices.l1_data_gas_prices.eth, DEFAULT_ETH_L1_DATA_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.strk, DEFAULT_STRK_L1_DATA_GAS_PRICE); - }); - - let config = - NodeArgs::parse_from(["katana", "--gpo.l1-eth-data-gas-price", "2"]).config().unwrap(); - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth, DEFAULT_ETH_L1_GAS_PRICE); - assert_eq!(prices.l1_gas_prices.strk, DEFAULT_STRK_L1_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.eth.get(), 2); - assert_eq!(prices.l1_data_gas_prices.strk, DEFAULT_STRK_L1_DATA_GAS_PRICE); - }); - - let config = - NodeArgs::parse_from(["katana", "--gpo.l1-strk-data-gas-price", "2"]).config().unwrap(); - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth, DEFAULT_ETH_L1_GAS_PRICE); - assert_eq!(prices.l1_gas_prices.strk, DEFAULT_STRK_L1_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.eth, DEFAULT_ETH_L1_DATA_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.strk.get(), 2); - }); - - let config = NodeArgs::parse_from([ - "katana", - "--gpo.l1-eth-gas-price", - "10", - "--gpo.l1-strk-data-gas-price", - "2", - ]) - .config() - .unwrap(); - - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth.get(), 10); - assert_eq!(prices.l1_gas_prices.strk, DEFAULT_STRK_L1_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.eth, DEFAULT_ETH_L1_DATA_GAS_PRICE); - assert_eq!(prices.l1_data_gas_prices.strk.get(), 2); - }); - - // Set all the gas prices options - - let config = NodeArgs::parse_from([ - "katana", - "--gpo.l1-eth-gas-price", - "10", - "--gpo.l1-strk-gas-price", - "20", - "--gpo.l1-eth-data-gas-price", - "1", - "--gpo.l1-strk-data-gas-price", - "2", - ]) - .config() - .unwrap(); - - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth.get(), 10); - assert_eq!(prices.l1_gas_prices.strk.get(), 20); - assert_eq!(prices.l1_data_gas_prices.eth.get(), 1); - assert_eq!(prices.l1_data_gas_prices.strk.get(), 2); - }) - } - - #[test] - fn genesis_with_fixed_gas_prices() { - let config = NodeArgs::parse_from([ - "katana", - "--genesis", - "./test-data/genesis.json", - "--gpo.l1-eth-gas-price", - "100", - "--gpo.l1-strk-gas-price", - "200", - "--gpo.l1-eth-data-gas-price", - "111", - "--gpo.l1-strk-data-gas-price", - "222", - ]) - .config() - .unwrap(); - - assert_eq!(config.chain.genesis().number, 0); - assert_eq!(config.chain.genesis().parent_hash, felt!("0x999")); - assert_eq!(config.chain.genesis().timestamp, 5123512314); - assert_eq!(config.chain.genesis().state_root, felt!("0x99")); - assert_eq!(config.chain.genesis().sequencer_address, address!("0x100")); - assert_eq!(config.chain.genesis().gas_prices.eth.get(), 9999); - assert_eq!(config.chain.genesis().gas_prices.strk.get(), 8888); - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth.get(), 100); - assert_eq!(prices.l1_gas_prices.strk.get(), 200); - assert_eq!(prices.l1_data_gas_prices.eth.get(), 111); - assert_eq!(prices.l1_data_gas_prices.strk.get(), 222); - }) - } - - #[test] - fn config_from_file_and_cli() { - // CLI args must take precedence over the config file. - let content = r#" -[gpo] -l1_eth_gas_price = "0xfe" -l1_strk_gas_price = "200" -l1_eth_data_gas_price = "111" -l1_strk_data_gas_price = "222" - -[dev] -total_accounts = 20 - -[starknet.env] -validate_max_steps = 500 -invoke_max_steps = 9988 -chain_id.Named = "Mainnet" - "#; - let path = std::env::temp_dir().join("katana-config.json"); - std::fs::write(&path, content).unwrap(); - - let path_str = path.to_string_lossy().to_string(); - - let args = vec![ - "katana", - "--config", - path_str.as_str(), - "--genesis", - "./test-data/genesis.json", - "--validate-max-steps", - "1234", - "--dev", - "--dev.no-fee", - "--chain-id", - "0x123", - ]; - - let config = - NodeArgs::parse_from(args.clone()).with_config_file().unwrap().config().unwrap(); - - assert_eq!(config.execution.validation_max_steps, 1234); - assert_eq!(config.execution.invocation_max_steps, 9988); - assert!(!config.dev.fee); - assert_matches!(config.dev.fixed_gas_prices, Some(prices) => { - assert_eq!(prices.l1_gas_prices.eth.get(), 254); - assert_eq!(prices.l1_gas_prices.strk.get(), 200); - assert_eq!(prices.l1_data_gas_prices.eth.get(), 111); - assert_eq!(prices.l1_data_gas_prices.strk.get(), 222); - }); - assert_eq!(config.chain.genesis().number, 0); - assert_eq!(config.chain.genesis().parent_hash, felt!("0x999")); - assert_eq!(config.chain.genesis().timestamp, 5123512314); - assert_eq!(config.chain.genesis().state_root, felt!("0x99")); - assert_eq!(config.chain.genesis().sequencer_address, address!("0x100")); - assert_eq!(config.chain.genesis().gas_prices.eth.get(), 9999); - assert_eq!(config.chain.genesis().gas_prices.strk.get(), 8888); - assert_eq!(config.chain.id(), ChainId::Id(Felt::from_str("0x123").unwrap())); - } - - #[test] - #[cfg(feature = "server")] - fn parse_cors_origins() { - use katana_rpc::cors::HeaderValue; - - let config = NodeArgs::parse_from([ - "katana", - "--http.cors_origins", - "*,http://localhost:3000,https://example.com", - ]) - .config() - .unwrap(); - - let cors_origins = config.rpc.cors_origins; - - assert_eq!(cors_origins.len(), 3); - assert!(cors_origins.contains(&HeaderValue::from_static("*"))); - assert!(cors_origins.contains(&HeaderValue::from_static("http://localhost:3000"))); - assert!(cors_origins.contains(&HeaderValue::from_static("https://example.com"))); - } - - #[test] - fn http_modules() { - // If the `--http.api` isn't specified, only starknet module will be exposed. - let config = NodeArgs::parse_from(["katana"]).config().unwrap(); - let modules = config.rpc.apis; - assert_eq!(modules.len(), 1); - assert!(modules.contains(&RpcModuleKind::Starknet)); - - // If the `--http.api` is specified, only the ones in the list will be exposed. - let config = NodeArgs::parse_from(["katana", "--http.api", "starknet"]).config().unwrap(); - let modules = config.rpc.apis; - assert_eq!(modules.len(), 1); - assert!(modules.contains(&RpcModuleKind::Starknet)); - - // Specifiying the dev module without enabling dev mode is forbidden. - let err = - NodeArgs::parse_from(["katana", "--http.api", "starknet,dev"]).config().unwrap_err(); - assert!(err - .to_string() - .contains("The `dev` module can only be enabled in dev mode (ie `--dev` flag)")); - } - - #[test] - fn test_dev_api_enabled() { - let args = NodeArgs::parse_from(["katana", "--dev"]); - let config = args.config().unwrap(); - - assert!(config.rpc.apis.contains(&RpcModuleKind::Dev)); - } - - #[cfg(feature = "cartridge")] - #[test] - fn cartridge_paymaster() { - let args = NodeArgs::parse_from(["katana", "--cartridge.paymaster"]); - let config = args.config().unwrap(); - - // Verify cartridge module is automatically enabled - assert!(config.rpc.apis.contains(&RpcModuleKind::Cartridge)); - - // Test with paymaster explicitly specified in RPC modules - let args = - NodeArgs::parse_from(["katana", "--cartridge.paymaster", "--http.api", "starknet"]); - let config = args.config().unwrap(); - - // Verify cartridge module is still enabled even when not in explicit RPC list - assert!(config.rpc.apis.contains(&RpcModuleKind::Cartridge)); - assert!(config.rpc.apis.contains(&RpcModuleKind::Starknet)); - - // Verify that all the Controller classes are added to the genesis - use katana_slot_controller::{ - ControllerLatest, ControllerV104, ControllerV105, ControllerV106, ControllerV107, - ControllerV108, ControllerV109, - }; - - assert!(config.chain.genesis().classes.get(&ControllerV104::HASH).is_some()); - assert!(config.chain.genesis().classes.get(&ControllerV105::HASH).is_some()); - assert!(config.chain.genesis().classes.get(&ControllerV106::HASH).is_some()); - assert!(config.chain.genesis().classes.get(&ControllerV107::HASH).is_some()); - assert!(config.chain.genesis().classes.get(&ControllerV108::HASH).is_some()); - assert!(config.chain.genesis().classes.get(&ControllerV109::HASH).is_some()); - assert!(config.chain.genesis().classes.get(&ControllerLatest::HASH).is_some()); - - // Test without paymaster enabled - let args = NodeArgs::parse_from(["katana"]); - let config = args.config().unwrap(); - - // Verify cartridge module is not enabled by default - assert!(!config.rpc.apis.contains(&RpcModuleKind::Cartridge)); - - assert!(config.chain.genesis().classes.get(&ControllerV104::HASH).is_none()); - assert!(config.chain.genesis().classes.get(&ControllerV105::HASH).is_none()); - assert!(config.chain.genesis().classes.get(&ControllerV106::HASH).is_none()); - assert!(config.chain.genesis().classes.get(&ControllerV107::HASH).is_none()); - assert!(config.chain.genesis().classes.get(&ControllerV108::HASH).is_none()); - assert!(config.chain.genesis().classes.get(&ControllerV109::HASH).is_none()); - assert!(config.chain.genesis().classes.get(&ControllerLatest::HASH).is_none()); - } -} diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs deleted file mode 100644 index b8a2a0a70..000000000 --- a/crates/cli/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![cfg_attr(not(test), warn(unused_crate_dependencies))] - -pub mod args; -pub mod file; -pub mod options; -pub mod utils; - -pub use args::NodeArgs; -pub use options::*; diff --git a/crates/contracts/macro/Cargo.toml b/crates/contracts/macro/Cargo.toml index 206f1d90d..8d38691db 100644 --- a/crates/contracts/macro/Cargo.toml +++ b/crates/contracts/macro/Cargo.toml @@ -13,7 +13,7 @@ serde_json = "1.0" syn = { version = "2.0", features = [ "extra-traits", "full" ] } # Dependencies for contract class parsing and hash computation -cairo-lang-starknet-classes = "2.11.2" -katana-primitives = { path = "../../primitives" } -starknet-crypto = "0.7.4" -starknet-types-core = "0.1.8" +cairo-lang-starknet-classes.workspace = true +katana-primitives.workspace = true +starknet-crypto.workspace = true +starknet-types-core.workspace = true diff --git a/crates/executor/Cargo.toml b/crates/executor/Cargo.toml index 4636940db..fa50e5f04 100644 --- a/crates/executor/Cargo.toml +++ b/crates/executor/Cargo.toml @@ -18,7 +18,7 @@ thiserror.workspace = true tracing.workspace = true # cairo-native -cairo-native = { version = "0.4.1", optional = true } +cairo-native = { workspace = true, optional = true } cairo-vm.workspace = true parking_lot.workspace = true rayon = { workspace = true, optional = true } diff --git a/crates/executor/src/implementation/blockifier/cache.rs b/crates/executor/src/implementation/blockifier/cache.rs index d4312a178..ebeba4c29 100644 --- a/crates/executor/src/implementation/blockifier/cache.rs +++ b/crates/executor/src/implementation/blockifier/cache.rs @@ -273,7 +273,7 @@ impl ClassCache { let _span = span.enter(); let executor = - AotContractExecutor::new(&program, &entry_points, version.into(), OptLevel::Default) + AotContractExecutor::new(&program, &entry_points, version.into(), OptLevel::Default, None) .inspect_err(|error| tracing::error!(target: "class_cache", %error, "Failed to compile native class")) .unwrap(); diff --git a/crates/executor/src/implementation/blockifier/utils.rs b/crates/executor/src/implementation/blockifier/utils.rs index ec599e359..fd3b9d277 100644 --- a/crates/executor/src/implementation/blockifier/utils.rs +++ b/crates/executor/src/implementation/blockifier/utils.rs @@ -200,7 +200,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - tx: ApiInvokeTransaction::V0(starknet_api::transaction::InvokeTransactionV0 { entry_point_selector: EntryPointSelector(tx.entry_point_selector), contract_address: to_blk_address(tx.contract_address), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), calldata: Calldata(Arc::new(calldata)), max_fee: Fee(tx.max_fee), }), @@ -222,7 +222,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - max_fee: Fee(tx.max_fee), nonce: Nonce(tx.nonce), sender_address: to_blk_address(tx.sender_address), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), calldata: Calldata(Arc::new(calldata)), }), tx_hash: TransactionHash(hash), @@ -248,7 +248,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - tip: Tip(tx.tip), nonce: Nonce(tx.nonce), sender_address: to_blk_address(tx.sender_address), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), calldata: Calldata(Arc::new(calldata)), paymaster_data: PaymasterData(paymaster_data), account_deployment_data: AccountDeploymentData(account_deploy_data), @@ -278,7 +278,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - tx: ApiDeployAccountTransaction::V1(DeployAccountTransactionV1 { max_fee: Fee(tx.max_fee), nonce: Nonce(tx.nonce), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), class_hash: ClassHash(tx.class_hash), constructor_calldata: Calldata(Arc::new(calldata)), contract_address_salt: salt, @@ -306,7 +306,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - tx: ApiDeployAccountTransaction::V3(DeployAccountTransactionV3 { tip: Tip(tx.tip), nonce: Nonce(tx.nonce), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), class_hash: ClassHash(tx.class_hash), constructor_calldata: Calldata(Arc::new(calldata)), contract_address_salt: salt, @@ -333,7 +333,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - max_fee: Fee(tx.max_fee), nonce: Nonce::default(), sender_address: to_blk_address(tx.sender_address), - signature: TransactionSignature(tx.signature), + signature: TransactionSignature(tx.signature.into()), class_hash: ClassHash(tx.class_hash), }), @@ -341,7 +341,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - max_fee: Fee(tx.max_fee), nonce: Nonce(tx.nonce), sender_address: to_blk_address(tx.sender_address), - signature: TransactionSignature(tx.signature), + signature: TransactionSignature(tx.signature.into()), class_hash: ClassHash(tx.class_hash), }), @@ -352,7 +352,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - max_fee: Fee(tx.max_fee), nonce: Nonce(tx.nonce), sender_address: to_blk_address(tx.sender_address), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), class_hash: ClassHash(tx.class_hash), compiled_class_hash: CompiledClassHash(tx.compiled_class_hash), }) @@ -371,7 +371,7 @@ pub fn to_executor_tx(mut tx: ExecutableTxWithHash, mut flags: ExecutionFlags) - tip: Tip(tx.tip), nonce: Nonce(tx.nonce), sender_address: to_blk_address(tx.sender_address), - signature: TransactionSignature(signature), + signature: TransactionSignature(signature.into()), class_hash: ClassHash(tx.class_hash), account_deployment_data: AccountDeploymentData(account_deploy_data), compiled_class_hash: CompiledClassHash(tx.compiled_class_hash), diff --git a/crates/node-bindings/Cargo.toml b/crates/node/node-bindings/Cargo.toml similarity index 100% rename from crates/node-bindings/Cargo.toml rename to crates/node/node-bindings/Cargo.toml diff --git a/crates/node-bindings/benches/startup.rs b/crates/node/node-bindings/benches/startup.rs similarity index 100% rename from crates/node-bindings/benches/startup.rs rename to crates/node/node-bindings/benches/startup.rs diff --git a/crates/node-bindings/src/json.rs b/crates/node/node-bindings/src/json.rs similarity index 100% rename from crates/node-bindings/src/json.rs rename to crates/node/node-bindings/src/json.rs diff --git a/crates/node-bindings/src/lib.rs b/crates/node/node-bindings/src/lib.rs similarity index 100% rename from crates/node-bindings/src/lib.rs rename to crates/node/node-bindings/src/lib.rs diff --git a/crates/node/node-cli-args/Cargo.toml b/crates/node/node-cli-args/Cargo.toml new file mode 100644 index 000000000..56c007494 --- /dev/null +++ b/crates/node/node-cli-args/Cargo.toml @@ -0,0 +1,32 @@ +[package] +description = "CLI argument types for Katana" +edition.workspace = true +license.workspace = true +name = "katana-node-cli-args" +repository.workspace = true +version.workspace = true + +[dependencies] +katana-chain-spec.workspace = true +katana-node-defaults.workspace = true +katana-primitives.workspace = true +katana-tracing.workspace = true +serde-utils.workspace = true + +anyhow.workspace = true +clap.workspace = true +http = { workspace = true, optional = true } +serde.workspace = true +shellexpand = "3.1.0" +toml.workspace = true +url.workspace = true + +[dev-dependencies] +serde_json.workspace = true + +[features] +cartridge = [ ] +default = [ ] +explorer = [ ] +native = [ ] +server = [ "dep:http" ] diff --git a/crates/cli/src/file.rs b/crates/node/node-cli-args/src/file.rs similarity index 89% rename from crates/cli/src/file.rs rename to crates/node/node-cli-args/src/file.rs index 9a4dd5809..11432f645 100644 --- a/crates/cli/src/file.rs +++ b/crates/node/node-cli-args/src/file.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use anyhow::Result; -use katana_messaging::MessagingConfig; +// use katana_messaging::MessagingConfig; use serde::{Deserialize, Serialize}; use crate::options::*; @@ -14,8 +14,8 @@ pub struct NodeArgsConfig { pub block_time: Option, pub block_cairo_steps_limit: Option, pub db_dir: Option, - pub messaging: Option, pub logging: Option, + pub messaging: Option, pub starknet: Option, pub gpo: Option, pub forking: Option, @@ -39,21 +39,23 @@ impl NodeArgsConfig { impl TryFrom for NodeArgsConfig { type Error = anyhow::Error; - fn try_from(args: NodeArgs) -> Result { + fn try_from(mut args: NodeArgs) -> Result { // Ensure the config file is merged with the CLI arguments. - let args = args.with_config_file()?; + args.with_config_file()?; let mut node_config = NodeArgsConfig { no_mining: if args.no_mining { Some(true) } else { None }, block_time: args.block_time, block_cairo_steps_limit: args.block_cairo_steps_limit, db_dir: args.db_dir, - messaging: args.messaging, + // messaging: args.messaging, ..Default::default() }; // Only include the following options if they are not the default. // This makes the config file more readable. + node_config.messaging = + if args.messaging == MessagingOptions::default() { None } else { Some(args.messaging) }; node_config.logging = if args.logging == LoggingOptions::default() { None } else { Some(args.logging) }; node_config.starknet = diff --git a/crates/node/node-cli-args/src/lib.rs b/crates/node/node-cli-args/src/lib.rs new file mode 100644 index 000000000..523b8b033 --- /dev/null +++ b/crates/node/node-cli-args/src/lib.rs @@ -0,0 +1,178 @@ +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + +use std::path::PathBuf; + +use anyhow::Result; +use clap::Parser; +use katana_chain_spec::rollup::ChainConfigDir; +use serde::{Deserialize, Serialize}; + +pub mod file; +pub mod options; +pub mod utils; + +pub use file::NodeArgsConfig; +pub use options::*; +use utils::parse_chain_config_dir; + +#[derive(Parser, Debug, Serialize, Deserialize, Default, Clone)] +#[command(next_help_heading = "Node options")] +pub struct NodeArgs { + /// Don't print anything on startup. + #[arg(long)] + pub silent: bool, + + /// Path to the chain configuration file. + #[arg(long, hide = true)] + #[arg(value_parser = parse_chain_config_dir)] + pub chain: Option, + + /// Disable auto and interval mining, and mine on demand instead via an endpoint. + #[arg(long)] + #[arg(conflicts_with = "block_time")] + pub no_mining: bool, + + /// Block time in milliseconds for interval mining. + #[arg(short, long)] + #[arg(value_name = "MILLISECONDS")] + pub block_time: Option, + + #[arg(long = "sequencing.block-max-cairo-steps")] + #[arg(value_name = "TOTAL")] + pub block_cairo_steps_limit: Option, + + /// Directory path of the database to initialize from. + /// + /// The path must either be an empty directory or a directory which already contains a + /// previously initialized Katana database. + #[arg(long)] + #[arg(value_name = "PATH")] + pub db_dir: Option, + + /// Configuration file + #[arg(long)] + pub config: Option, + + // /// Configure the messaging with an other chain. + // /// + // /// Configure the messaging to allow Katana listening/sending messages on a + // /// settlement chain that can be Ethereum or an other Starknet sequencer. + // #[arg(long)] + // #[arg(value_name = "PATH")] + // #[arg(value_parser = katana_messaging::MessagingConfig::parse)] + // #[arg(conflicts_with = "chain")] + // pub messaging: Option, + // #[arg(long = "l1.provider", value_name = "URL", alias = "l1-provider")] + // #[arg(help = "The Ethereum RPC provider to sample the gas prices from to enable the gas \ + // price oracle.")] + // pub l1_provider_url: Option, + #[command(flatten)] + pub messaging: MessagingOptions, + + #[command(flatten)] + pub logging: LoggingOptions, + + #[command(flatten)] + pub tracer: TracerOptions, + + #[cfg(feature = "server")] + #[command(flatten)] + pub metrics: MetricsOptions, + + #[cfg(feature = "server")] + #[command(flatten)] + pub server: ServerOptions, + + #[command(flatten)] + pub starknet: StarknetOptions, + + #[command(flatten)] + pub gpo: GasPriceOracleOptions, + + #[command(flatten)] + pub forking: ForkingOptions, + + #[command(flatten)] + pub development: DevOptions, + + #[cfg(feature = "explorer")] + #[command(flatten)] + pub explorer: ExplorerOptions, + + #[cfg(feature = "cartridge")] + #[command(flatten)] + pub cartridge: CartridgeOptions, +} + +impl NodeArgs { + /// Parse the node config from the command line arguments and the config file, + /// and merge them together prioritizing the command line arguments. + pub fn with_config_file(&mut self) -> Result<()> { + let config = if let Some(path) = &self.config { + NodeArgsConfig::read(path)? + } else { + return Ok(()); + }; + + // the CLI (self) takes precedence over the config file. + // Currently, the merge is made at the top level of the commands. + // We may add recursive merging in the future. + + if !self.no_mining { + self.no_mining = config.no_mining.unwrap_or_default(); + } + + if self.block_time.is_none() { + self.block_time = config.block_time; + } + + if self.db_dir.is_none() { + self.db_dir = config.db_dir; + } + + if self.logging == LoggingOptions::default() { + if let Some(logging) = config.logging { + self.logging = logging; + } + } + + if self.messaging == MessagingOptions::default() { + if let Some(messaging) = config.messaging { + self.messaging = messaging; + } + } + + #[cfg(feature = "server")] + { + self.server.merge(config.server.as_ref()); + + if self.metrics == MetricsOptions::default() { + if let Some(metrics) = config.metrics { + self.metrics = metrics; + } + } + } + + self.starknet.merge(config.starknet.as_ref()); + self.development.merge(config.development.as_ref()); + + if self.gpo == GasPriceOracleOptions::default() { + if let Some(gpo) = config.gpo { + self.gpo = gpo; + } + } + + if self.forking == ForkingOptions::default() { + if let Some(forking) = config.forking { + self.forking = forking; + } + } + + #[cfg(feature = "cartridge")] + { + self.cartridge.merge(config.cartridge.as_ref()); + } + + Ok(()) + } +} diff --git a/crates/cli/src/options.rs b/crates/node/node-cli-args/src/options.rs similarity index 94% rename from crates/cli/src/options.rs rename to crates/node/node-cli-args/src/options.rs index ee5b33885..cc56792f5 100644 --- a/crates/cli/src/options.rs +++ b/crates/node/node-cli-args/src/options.rs @@ -12,20 +12,18 @@ use std::net::IpAddr; use std::num::NonZeroU128; use clap::Args; -use katana_node::config::execution::{DEFAULT_INVOCATION_MAX_STEPS, DEFAULT_VALIDATION_MAX_STEPS}; +use katana_node_defaults::execution::{DEFAULT_INVOCATION_MAX_STEPS, DEFAULT_VALIDATION_MAX_STEPS}; #[cfg(feature = "server")] -use katana_node::config::metrics::{DEFAULT_METRICS_ADDR, DEFAULT_METRICS_PORT}; +use katana_node_defaults::metrics::{DEFAULT_METRICS_ADDR, DEFAULT_METRICS_PORT}; #[cfg(feature = "server")] -use katana_node::config::rpc::{RpcModulesList, DEFAULT_RPC_MAX_PROOF_KEYS}; +use katana_node_defaults::rpc::DEFAULT_RPC_MAX_PROOF_KEYS; #[cfg(feature = "server")] -use katana_node::config::rpc::{ +use katana_node_defaults::rpc::{ DEFAULT_RPC_ADDR, DEFAULT_RPC_MAX_CALL_GAS, DEFAULT_RPC_MAX_EVENT_PAGE_SIZE, DEFAULT_RPC_PORT, }; -use katana_primitives::block::{BlockHashOrNumber, GasPrice}; +use katana_primitives::block::BlockHashOrNumber; use katana_primitives::chain::ChainId; use katana_primitives::genesis::Genesis; -#[cfg(feature = "server")] -use katana_rpc::cors::HeaderValue; use katana_tracing::{gcloud, otlp, LogFormat, TracerConfig}; use serde::{Deserialize, Serialize}; use serde_utils::serialize_opt_as_hex; @@ -100,13 +98,13 @@ pub struct ServerOptions { serialize_with = "serialize_cors_origins", deserialize_with = "deserialize_cors_origins" )] - pub http_cors_origins: Vec, + pub http_cors_origins: Vec, /// API's offered over the HTTP-RPC interface. #[arg(long = "http.api", value_name = "MODULES")] - #[arg(value_parser = RpcModulesList::parse)] + // #[arg(value_parser = RpcModulesList::parse)] #[serde(default)] - pub http_modules: Option, + pub http_modules: Option>, /// Maximum number of concurrent connections allowed. #[arg(long = "rpc.max-connections", value_name = "MAX")] @@ -391,6 +389,7 @@ pub struct LoggingOptions { #[arg(default_value_t = LogFormat::Full)] pub log_format: LogFormat, } + #[derive(Debug, Args, Default, Clone, Serialize, Deserialize, PartialEq)] #[command(next_help_heading = "Gas Price Oracle Options")] pub struct GasPriceOracleOptions { @@ -399,42 +398,42 @@ pub struct GasPriceOracleOptions { #[serde(serialize_with = "serialize_opt_as_hex")] #[serde(deserialize_with = "deserialize_gas_price")] #[serde(default)] - pub l2_eth_gas_price: Option, + pub l2_eth_gas_price: Option, /// The L2 STRK gas price. (denominated in fri) #[arg(long = "gpo.l2-strk-gas-price", value_name = "FRI")] #[serde(serialize_with = "serialize_opt_as_hex")] #[serde(deserialize_with = "deserialize_gas_price")] #[serde(default)] - pub l2_strk_gas_price: Option, + pub l2_strk_gas_price: Option, /// The L1 ETH gas price. (denominated in wei) #[arg(long = "gpo.l1-eth-gas-price", value_name = "WEI")] #[serde(serialize_with = "serialize_opt_as_hex")] #[serde(default)] #[serde(deserialize_with = "deserialize_gas_price")] - pub l1_eth_gas_price: Option, + pub l1_eth_gas_price: Option, /// The L1 STRK gas price. (denominated in fri) #[arg(long = "gpo.l1-strk-gas-price", value_name = "FRI")] #[serde(serialize_with = "serialize_opt_as_hex")] #[serde(deserialize_with = "deserialize_gas_price")] #[serde(default)] - pub l1_strk_gas_price: Option, + pub l1_strk_gas_price: Option, /// The L1 ETH data gas price. (denominated in wei) #[arg(long = "gpo.l1-eth-data-gas-price", value_name = "WEI")] #[serde(serialize_with = "serialize_opt_as_hex")] #[serde(deserialize_with = "deserialize_gas_price")] #[serde(default)] - pub l1_eth_data_gas_price: Option, + pub l1_eth_data_gas_price: Option, /// The L1 STRK data gas price. (denominated in fri) #[arg(long = "gpo.l1-strk-data-gas-price", value_name = "FRI")] #[serde(serialize_with = "serialize_opt_as_hex")] #[serde(deserialize_with = "deserialize_gas_price")] #[serde(default)] - pub l1_strk_data_gas_price: Option, + pub l1_strk_data_gas_price: Option, } #[cfg(feature = "cartridge")] @@ -544,7 +543,7 @@ fn default_page_size() -> u64 { #[cfg(feature = "server")] fn default_proof_keys() -> u64 { - katana_node::config::rpc::DEFAULT_RPC_MAX_PROOF_KEYS + katana_node_defaults::rpc::DEFAULT_RPC_MAX_PROOF_KEYS } #[cfg(feature = "server")] @@ -563,7 +562,7 @@ fn default_max_call_gas() -> u64 { } /// Deserialize a string (hex or decimal) into a [`GasPrice`] -fn deserialize_gas_price<'de, D>(deserializer: D) -> Result, D::Error> +fn deserialize_gas_price<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de>, { @@ -580,10 +579,7 @@ where u128::from_str(&s).map_err(D::Error::custom)? }; - NonZeroU128::new(value) - .map(GasPrice::new) - .map(Some) - .ok_or_else(|| D::Error::custom("value cannot be zero")) + NonZeroU128::new(value).map(Some).ok_or_else(|| D::Error::custom("gas price cannot be zero")) } #[cfg(feature = "cartridge")] @@ -657,3 +653,14 @@ impl TracerOptions { self } } + +#[derive(Debug, Default, Args, Clone, Serialize, Deserialize, PartialEq)] +#[command(next_help_heading = "Messaging options")] +pub struct MessagingOptions { + /// Frequency (in seconds) of message collection. + /// + /// This controls how often messages are collected from the settlement chain. + #[arg(long = "messaging.interval")] + #[serde(default)] + pub interval: u64, +} diff --git a/crates/node/node-cli-args/src/utils.rs b/crates/node/node-cli-args/src/utils.rs new file mode 100644 index 000000000..4c2f8edb2 --- /dev/null +++ b/crates/node/node-cli-args/src/utils.rs @@ -0,0 +1,95 @@ +use std::path::PathBuf; + +use anyhow::{anyhow, Context, Result}; +use katana_chain_spec::rollup::ChainConfigDir; +use katana_primitives::block::{BlockHash, BlockHashOrNumber, BlockNumber}; +use katana_primitives::chain::ChainId; +use katana_primitives::genesis::json::GenesisJson; +use katana_primitives::genesis::Genesis; +use serde::{Deserialize, Deserializer, Serializer}; + +pub fn parse_seed(seed: &str) -> [u8; 32] { + let seed = seed.as_bytes(); + + if seed.len() >= 32 { + unsafe { *(seed[..32].as_ptr() as *const [u8; 32]) } + } else { + let mut actual_seed = [0u8; 32]; + seed.iter().enumerate().for_each(|(i, b)| actual_seed[i] = *b); + actual_seed + } +} + +/// Used as clap value parser for [Genesis]. +pub fn parse_genesis(value: &str) -> Result { + let path = PathBuf::from(shellexpand::full(value)?.into_owned()); + let genesis = Genesis::try_from(GenesisJson::load(path)?)?; + Ok(genesis) +} + +/// If the value starts with `0x`, it is parsed as a [`BlockHash`], otherwise as a [`BlockNumber`]. +pub fn parse_block_hash_or_number(value: &str) -> Result { + if value.starts_with("0x") { + Ok(BlockHashOrNumber::Hash(BlockHash::from_hex(value)?)) + } else { + let num = value.parse::().context("could not parse block number")?; + Ok(BlockHashOrNumber::Num(num)) + } +} + +// Chain IDs can be arbitrary ASCII strings, making them indistinguishable from filesystem paths. +// To handle this ambiguity, we first try parsing single-component inputs as paths, then as chain +// IDs. Multi-component inputs are always treated as paths. +pub fn parse_chain_config_dir(value: &str) -> Result { + let path = PathBuf::from(value); + + if path.components().count() == 1 { + if path.exists() { + Ok(ChainConfigDir::open(path)?) + } else if let Ok(id) = ChainId::parse(value) { + Ok(ChainConfigDir::open_local(&id)?) + } else { + Err(anyhow!("Invalid path or chain id")) + } + } else { + let path = PathBuf::from(shellexpand::tilde(value).as_ref()); + Ok(ChainConfigDir::open(path)?) + } +} + +#[cfg(feature = "server")] +pub fn serialize_cors_origins( + values: &[http::HeaderValue], + serializer: S, +) -> Result +where + S: Serializer, +{ + use serde::Serialize; + + let strings: Vec = values.iter().map(|v| v.to_str().unwrap().to_string()).collect(); + strings.serialize(serializer) +} + +#[cfg(feature = "server")] +pub fn deserialize_cors_origins<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let strings: Vec = Vec::deserialize(deserializer)?; + strings + .into_iter() + .map(|s| http::HeaderValue::from_str(&s).map_err(serde::de::Error::custom)) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_genesis_file() { + let path = "./test-data/genesis.json"; + parse_genesis(path).unwrap(); + } +} diff --git a/crates/cli/Cargo.toml b/crates/node/node-cli/Cargo.toml similarity index 71% rename from crates/cli/Cargo.toml rename to crates/node/node-cli/Cargo.toml index d7c838a44..973df20e6 100644 --- a/crates/cli/Cargo.toml +++ b/crates/node/node-cli/Cargo.toml @@ -1,7 +1,7 @@ [package] edition.workspace = true license.workspace = true -name = "katana-cli" +name = "katana-node-cli" repository.workspace = true version.workspace = true @@ -10,12 +10,11 @@ katana-chain-spec.workspace = true katana-core.workspace = true katana-messaging.workspace = true katana-node.workspace = true +katana-node-cli-args = { workspace = true, features = [ "cartridge", "server" ] } katana-primitives.workspace = true -katana-rpc.workspace = true katana-slot-controller = { workspace = true, optional = true } katana-tracing.workspace = true katana-utils.workspace = true -serde-utils.workspace = true alloy-primitives.workspace = true anyhow.workspace = true @@ -23,11 +22,8 @@ clap.workspace = true console.workspace = true serde.workspace = true serde_json.workspace = true -shellexpand = "3.1.0" tokio.workspace = true -toml.workspace = true tracing.workspace = true -url.workspace = true [dev-dependencies] assert_matches.workspace = true @@ -35,12 +31,8 @@ katana-gas-price-oracle.workspace = true starknet.workspace = true [features] -cartridge = [ - "dep:katana-slot-controller", - "katana-node/cartridge", - "katana-rpc/cartridge", -] +cartridge = [ "dep:katana-slot-controller", "katana-node/cartridge" ] default = [ "cartridge", "server" ] -explorer = [ "katana-node/explorer" ] -native = [ "katana-node/native" ] +explorer = [ "katana-node-cli-args/explorer", "katana-node/explorer" ] +native = [ "katana-node-cli-args/native", "katana-node/native" ] server = [ ] diff --git a/crates/node/node-cli/src/lib.rs b/crates/node/node-cli/src/lib.rs new file mode 100644 index 000000000..ce1017887 --- /dev/null +++ b/crates/node/node-cli/src/lib.rs @@ -0,0 +1,333 @@ +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + +pub mod utils; + +use std::sync::Arc; + +use alloy_primitives::U256; +use anyhow::{Context, Result}; +use clap::Parser; +use katana_chain_spec::ChainSpec; +use katana_core::constants::DEFAULT_SEQUENCER_ADDRESS; +use katana_messaging::MessagingConfig; +use katana_node::config::db::DbConfig; +use katana_node::config::dev::{DevConfig, FixedL1GasPriceConfig}; +use katana_node::config::execution::ExecutionConfig; +use katana_node::config::fork::ForkingConfig; +use katana_node::config::metrics::MetricsConfig; +#[cfg(feature = "cartridge")] +use katana_node::config::paymaster::PaymasterConfig; +use katana_node::config::rpc::RpcConfig; +#[cfg(feature = "server")] +use katana_node::config::rpc::{RpcModuleKind, RpcModulesList}; +use katana_node::config::sequencing::SequencingConfig; +use katana_node::config::Config; +use katana_node::Node; +pub use katana_node_cli_args::options::*; +use katana_node_cli_args::utils::parse_seed; +pub use katana_node_cli_args::{NodeArgs, NodeArgsConfig}; +use katana_primitives::genesis::allocation::DevAllocationsGenerator; +use katana_primitives::genesis::constant::DEFAULT_PREFUNDED_ACCOUNT_BALANCE; +use serde::{Deserialize, Serialize}; +use tracing::info; + +pub(crate) const LOG_TARGET: &str = "katana::cli"; + +#[derive(Parser, Debug, Serialize, Deserialize, Default, Clone)] +pub struct Cli { + #[command(flatten)] + pub args: NodeArgs, +} + +impl Cli { + pub fn parse_from(itr: I) -> Self + where + I: IntoIterator, + T: Into + Clone, + { + Self { args: NodeArgs::parse_from(itr) } + } +} + +impl Cli { + pub async fn execute(mut self) -> Result<()> { + self.args.with_config_file()?; + + // Initialize logging with tracer + let tracer_config = self.tracer_config(); + katana_tracing::init(self.args.logging.log_format, tracer_config).await?; + + self.start_node().await + } + + async fn start_node(&self) -> Result<()> { + // Build the node + let config = self.build_config()?; + let node = Node::build(config).await.context("failed to build node")?; + + if !self.args.silent { + utils::print_intro(&self.args, &node.backend().chain_spec); + } + + // Launch the node + let handle = node.launch().await.context("failed to launch node")?; + + // Wait until an OS signal (ie SIGINT, SIGTERM) is received or the node is shutdown. + tokio::select! { + _ = katana_utils::wait_shutdown_signals() => { + // Gracefully shutdown the node before exiting + handle.stop().await?; + }, + + _ = handle.stopped() => { } + } + + info!("Shutting down."); + + Ok(()) + } + + pub fn build_config(&self) -> Result { + let db = self.db_config(); + let rpc = self.rpc_config()?; + let dev = self.dev_config(); + let (chain, messaging) = self.chain_spec()?; + let metrics = self.metrics_config(); + let forking = self.forking_config()?; + let execution = self.execution_config(); + let sequencing = self.sequencer_config(); + + // // the `katana init` will automatically generate a messaging config. so if katana is run + // // with `--chain` then the `--messaging` flag is not required. this is temporary and + // // the messagign config will eventually be removed slowly. + // let messaging = + // if cs_messaging.is_some() { cs_messaging } else { self.args.messaging.clone() }; + + #[cfg(feature = "cartridge")] + { + let paymaster = self.cartridge_config(); + + Ok(Config { + db, + dev, + rpc, + chain, + metrics, + forking, + execution, + messaging, + paymaster, + sequencing, + }) + } + + #[cfg(not(feature = "cartridge"))] + Ok(Config { metrics, db, dev, rpc, chain, execution, sequencing, messaging, forking }) + } + + fn sequencer_config(&self) -> SequencingConfig { + SequencingConfig { + block_time: self.args.block_time, + no_mining: self.args.no_mining, + block_cairo_steps_limit: self.args.block_cairo_steps_limit, + } + } + + pub fn rpc_config(&self) -> Result { + #[cfg(feature = "server")] + { + use std::time::Duration; + + #[allow(unused_mut)] + let mut modules = if let Some(modules_str) = &self.args.server.http_modules { + let modules = RpcModulesList::parse_from_iter(modules_str)?; + + // TODO: This check should be handled in the `katana-node` level. Right now if you + // instantiate katana programmatically, you can still add the dev module without + // enabling dev mode. + // + // We only allow the `dev` module in dev mode (ie `--dev` flag) + if !self.args.development.dev && modules.contains(&RpcModuleKind::Dev) { + anyhow::bail!( + "The `dev` module can only be enabled in dev mode (ie `--dev` flag)" + ) + } + + modules.clone() + } else { + // Expose the default modules if none is specified. + let mut modules = RpcModulesList::default(); + + // Ensures the `--dev` flag enabled the dev module. + if self.args.development.dev { + modules.add(RpcModuleKind::Dev); + } + + modules + }; + + // The cartridge rpc must be enabled if the paymaster is enabled. + // We put it here so that even when the individual api are explicitly specified + // (ie `--rpc.api`) we guarantee that the cartridge rpc is enabled. + #[cfg(feature = "cartridge")] + if self.args.cartridge.paymaster { + modules.add(RpcModuleKind::Cartridge); + } + + let cors_origins = self.args.server.http_cors_origins.clone(); + + Ok(RpcConfig { + apis: modules, + port: self.args.server.http_port, + addr: self.args.server.http_addr, + max_connections: self.args.server.max_connections, + max_concurrent_estimate_fee_requests: None, + max_request_body_size: None, + max_response_body_size: None, + timeout: self.args.server.timeout.map(Duration::from_secs), + cors_origins, + #[cfg(feature = "explorer")] + explorer: self.args.explorer.explorer, + max_event_page_size: Some(self.args.server.max_event_page_size), + max_proof_keys: Some(self.args.server.max_proof_keys), + max_call_gas: Some(self.args.server.max_call_gas), + }) + } + + #[cfg(not(feature = "server"))] + { + Ok(RpcConfig::default()) + } + } + + fn chain_spec(&self) -> Result<(Arc, Option)> { + if let Some(path) = &self.args.chain { + let mut cs = katana_chain_spec::rollup::read(path)?; + cs.genesis.sequencer_address = *DEFAULT_SEQUENCER_ADDRESS; + let messaging_config = MessagingConfig::from_chain_spec(&cs); + Ok((Arc::new(ChainSpec::Rollup(cs)), Some(messaging_config))) + } + // exclusively for development mode + else { + let mut chain_spec = katana_chain_spec::dev::DEV_UNALLOCATED.clone(); + + if let Some(id) = self.args.starknet.environment.chain_id { + chain_spec.id = id; + } + + if let Some(genesis) = &self.args.starknet.genesis { + chain_spec.genesis = genesis.clone(); + } else { + chain_spec.genesis.sequencer_address = *DEFAULT_SEQUENCER_ADDRESS; + } + + // Generate dev accounts. + // If `cartridge` is enabled, the first account will be the paymaster. + let accounts = DevAllocationsGenerator::new(self.args.development.total_accounts) + .with_seed(parse_seed(&self.args.development.seed)) + .with_balance(U256::from(DEFAULT_PREFUNDED_ACCOUNT_BALANCE)) + .generate(); + + chain_spec.genesis.extend_allocations(accounts.into_iter().map(|(k, v)| (k, v.into()))); + + #[cfg(feature = "cartridge")] + if self.args.cartridge.controllers || self.args.cartridge.paymaster { + katana_slot_controller::add_controller_classes(&mut chain_spec.genesis); + katana_slot_controller::add_vrf_provider_class(&mut chain_spec.genesis); + } + + Ok((Arc::new(ChainSpec::Dev(chain_spec)), None)) + } + } + + fn dev_config(&self) -> DevConfig { + let mut fixed_gas_prices = None; + + if let Some(eth) = self.args.gpo.l2_eth_gas_price { + let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); + prices.l2_gas_prices.eth = eth.into(); + } + + if let Some(strk) = self.args.gpo.l2_strk_gas_price { + let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); + prices.l2_gas_prices.strk = strk.into(); + } + + if let Some(eth) = self.args.gpo.l1_eth_gas_price { + let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); + prices.l1_gas_prices.eth = eth.into(); + } + + if let Some(strk) = self.args.gpo.l1_strk_gas_price { + let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); + prices.l1_gas_prices.strk = strk.into(); + } + + if let Some(eth) = self.args.gpo.l1_eth_data_gas_price { + let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); + prices.l1_data_gas_prices.eth = eth.into(); + } + + if let Some(strk) = self.args.gpo.l1_strk_data_gas_price { + let prices = fixed_gas_prices.get_or_insert(FixedL1GasPriceConfig::default()); + prices.l1_data_gas_prices.strk = strk.into(); + } + + DevConfig { + fixed_gas_prices, + fee: !self.args.development.no_fee, + account_validation: !self.args.development.no_account_validation, + } + } + + fn execution_config(&self) -> ExecutionConfig { + ExecutionConfig { + invocation_max_steps: self.args.starknet.environment.invoke_max_steps, + validation_max_steps: self.args.starknet.environment.validate_max_steps, + #[cfg(feature = "native")] + compile_native: self.args.starknet.environment.compile_native, + ..Default::default() + } + } + + fn forking_config(&self) -> Result> { + if let Some(ref url) = self.args.forking.fork_provider { + let cfg = ForkingConfig { url: url.clone(), block: self.args.forking.fork_block }; + return Ok(Some(cfg)); + } + + Ok(None) + } + + fn db_config(&self) -> DbConfig { + DbConfig { dir: self.args.db_dir.clone() } + } + + fn metrics_config(&self) -> Option { + #[cfg(feature = "server")] + if self.args.metrics.metrics { + Some(MetricsConfig { + addr: self.args.metrics.metrics_addr, + port: self.args.metrics.metrics_port, + }) + } else { + None + } + + #[cfg(not(feature = "server"))] + None + } + + #[cfg(feature = "cartridge")] + fn cartridge_config(&self) -> Option { + if self.args.cartridge.paymaster { + Some(PaymasterConfig { cartridge_api_url: self.args.cartridge.api.clone() }) + } else { + None + } + } + + fn tracer_config(&self) -> Option { + self.args.tracer.config() + } +} diff --git a/crates/cli/src/utils.rs b/crates/node/node-cli/src/utils.rs similarity index 55% rename from crates/cli/src/utils.rs rename to crates/node/node-cli/src/utils.rs index a1f6cde48..a2f28f26f 100644 --- a/crates/cli/src/utils.rs +++ b/crates/node/node-cli/src/utils.rs @@ -1,55 +1,16 @@ -use std::path::PathBuf; - -use anyhow::{anyhow, Context, Result}; use console::Style; -use katana_chain_spec::rollup::ChainConfigDir; use katana_chain_spec::ChainSpec; -use katana_primitives::block::{BlockHash, BlockHashOrNumber, BlockNumber}; -use katana_primitives::chain::ChainId; +use katana_node_cli_args::NodeArgs; use katana_primitives::class::ClassHash; use katana_primitives::contract::ContractAddress; use katana_primitives::genesis::allocation::GenesisAccountAlloc; use katana_primitives::genesis::constant::{ DEFAULT_LEGACY_ERC20_CLASS_HASH, DEFAULT_LEGACY_UDC_CLASS_HASH, DEFAULT_UDC_ADDRESS, }; -use katana_primitives::genesis::json::GenesisJson; -use katana_primitives::genesis::Genesis; -use katana_rpc::cors::HeaderValue; use katana_tracing::LogFormat; -use serde::{Deserialize, Deserializer, Serializer}; use tracing::info; -use crate::args::LOG_TARGET; -use crate::NodeArgs; - -pub fn parse_seed(seed: &str) -> [u8; 32] { - let seed = seed.as_bytes(); - - if seed.len() >= 32 { - unsafe { *(seed[..32].as_ptr() as *const [u8; 32]) } - } else { - let mut actual_seed = [0u8; 32]; - seed.iter().enumerate().for_each(|(i, b)| actual_seed[i] = *b); - actual_seed - } -} - -/// Used as clap value parser for [Genesis]. -pub fn parse_genesis(value: &str) -> Result { - let path = PathBuf::from(shellexpand::full(value)?.into_owned()); - let genesis = Genesis::try_from(GenesisJson::load(path)?)?; - Ok(genesis) -} - -/// If the value starts with `0x`, it is parsed as a [`BlockHash`], otherwise as a [`BlockNumber`]. -pub fn parse_block_hash_or_number(value: &str) -> Result { - if value.starts_with("0x") { - Ok(BlockHashOrNumber::Hash(BlockHash::from_hex(value)?)) - } else { - let num = value.parse::().context("could not parse block number")?; - Ok(BlockHashOrNumber::Num(num)) - } -} +use crate::LOG_TARGET; pub fn print_intro(args: &NodeArgs, chain: &ChainSpec) { let mut accounts = chain.genesis().accounts().peekable(); @@ -179,61 +140,3 @@ PREFUNDED ACCOUNTS } } } - -pub fn serialize_cors_origins(values: &[HeaderValue], serializer: S) -> Result -where - S: Serializer, -{ - let string = values - .iter() - .map(|v| v.to_str()) - .collect::, _>>() - .map_err(serde::ser::Error::custom)? - .join(","); - - serializer.serialize_str(&string) -} - -pub fn deserialize_cors_origins<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - String::deserialize(deserializer)? - .split(',') - .map(|s| s.trim()) - .filter(|s| !s.is_empty()) - .map(HeaderValue::from_str) - .collect::, _>>() - .map_err(serde::de::Error::custom) -} - -// Chain IDs can be arbitrary ASCII strings, making them indistinguishable from filesystem paths. -// To handle this ambiguity, we first try parsing single-component inputs as paths, then as chain -// IDs. Multi-component inputs are always treated as paths. -pub fn parse_chain_config_dir(value: &str) -> Result { - let path = PathBuf::from(value); - - if path.components().count() == 1 { - if path.exists() { - Ok(ChainConfigDir::open(path)?) - } else if let Ok(id) = ChainId::parse(value) { - Ok(ChainConfigDir::open_local(&id)?) - } else { - Err(anyhow!("Invalid path or chain id")) - } - } else { - let path = PathBuf::from(shellexpand::tilde(value).as_ref()); - Ok(ChainConfigDir::open(path)?) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_genesis_file() { - let path = "./test-data/genesis.json"; - parse_genesis(path).unwrap(); - } -} diff --git a/crates/cli/test-data/genesis.json b/crates/node/node-cli/test-data/genesis.json similarity index 100% rename from crates/cli/test-data/genesis.json rename to crates/node/node-cli/test-data/genesis.json diff --git a/crates/node/node-defaults/Cargo.toml b/crates/node/node-defaults/Cargo.toml new file mode 100644 index 000000000..16d835f6a --- /dev/null +++ b/crates/node/node-defaults/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "katana-node-defaults" +edition.workspace = true +license.workspace = true +license-file.workspace = true +repository.workspace = true +version.workspace = true + +[dependencies] diff --git a/crates/node/node-defaults/src/lib.rs b/crates/node/node-defaults/src/lib.rs new file mode 100644 index 000000000..63c579d43 --- /dev/null +++ b/crates/node/node-defaults/src/lib.rs @@ -0,0 +1,30 @@ +pub mod rpc { + use std::net::{IpAddr, Ipv4Addr}; + + /// Default RPC server address. + pub const DEFAULT_RPC_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST); + /// Default RPC server port. + pub const DEFAULT_RPC_PORT: u16 = 5050; + /// Default maximmum page size for the `starknet_getEvents` RPC method. + pub const DEFAULT_RPC_MAX_EVENT_PAGE_SIZE: u64 = 1024; + /// Default maximmum number of keys for the `starknet_getStorageProof` RPC method. + pub const DEFAULT_RPC_MAX_PROOF_KEYS: u64 = 100; + /// Default maximum gas for the `starknet_call` RPC method. + pub const DEFAULT_RPC_MAX_CALL_GAS: u64 = 1_000_000_000; +} + +pub mod metrics { + use std::net::{IpAddr, Ipv4Addr}; + + /// Metrics server default address. + pub const DEFAULT_METRICS_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST); + /// Metrics server default port. + pub const DEFAULT_METRICS_PORT: u16 = 9100; +} + +pub mod execution { + pub const MAX_RECURSION_DEPTH: usize = 1000; + pub const DEFAULT_INVOCATION_MAX_STEPS: u32 = 10_000_000; + pub const DEFAULT_VALIDATION_MAX_STEPS: u32 = 1_000_000; + pub const DEFAULT_ENABLE_NATIVE_COMPILATION: bool = false; +} diff --git a/crates/node/Cargo.toml b/crates/node/node/Cargo.toml similarity index 97% rename from crates/node/Cargo.toml rename to crates/node/node/Cargo.toml index ebf8b7211..9479962d9 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/node/Cargo.toml @@ -13,6 +13,7 @@ katana-executor.workspace = true katana-gas-price-oracle.workspace = true katana-messaging.workspace = true katana-metrics.workspace = true +katana-node-defaults.workspace = true katana-pipeline.workspace = true katana-pool.workspace = true katana-primitives.workspace = true diff --git a/crates/node/src/config/db.rs b/crates/node/node/src/config/db.rs similarity index 100% rename from crates/node/src/config/db.rs rename to crates/node/node/src/config/db.rs diff --git a/crates/node/src/config/dev.rs b/crates/node/node/src/config/dev.rs similarity index 100% rename from crates/node/src/config/dev.rs rename to crates/node/node/src/config/dev.rs diff --git a/crates/node/src/config/execution.rs b/crates/node/node/src/config/execution.rs similarity index 71% rename from crates/node/src/config/execution.rs rename to crates/node/node/src/config/execution.rs index 5e1b52620..ef2e05053 100644 --- a/crates/node/src/config/execution.rs +++ b/crates/node/node/src/config/execution.rs @@ -1,10 +1,4 @@ -pub const MAX_RECURSION_DEPTH: usize = 1000; - -pub const DEFAULT_INVOCATION_MAX_STEPS: u32 = 10_000_000; -pub const DEFAULT_VALIDATION_MAX_STEPS: u32 = 1_000_000; - -#[cfg(feature = "native")] -pub const DEFAULT_ENABLE_NATIVE_COMPILATION: bool = false; +pub use katana_node_defaults::execution::*; #[derive(Debug, Clone)] pub struct ExecutionConfig { diff --git a/crates/node/src/config/fork.rs b/crates/node/node/src/config/fork.rs similarity index 100% rename from crates/node/src/config/fork.rs rename to crates/node/node/src/config/fork.rs diff --git a/crates/node/src/config/metrics.rs b/crates/node/node/src/config/metrics.rs similarity index 64% rename from crates/node/src/config/metrics.rs rename to crates/node/node/src/config/metrics.rs index ddceb8480..aaeb9e8de 100644 --- a/crates/node/src/config/metrics.rs +++ b/crates/node/node/src/config/metrics.rs @@ -1,9 +1,6 @@ -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::net::{IpAddr, SocketAddr}; -/// Metrics server default address. -pub const DEFAULT_METRICS_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST); -/// Metrics server default port. -pub const DEFAULT_METRICS_PORT: u16 = 9100; +pub use katana_node_defaults::metrics::*; /// Node metrics configurations. #[derive(Debug, Copy, Clone)] diff --git a/crates/node/src/config/mod.rs b/crates/node/node/src/config/mod.rs similarity index 100% rename from crates/node/src/config/mod.rs rename to crates/node/node/src/config/mod.rs diff --git a/crates/node/src/config/paymaster.rs b/crates/node/node/src/config/paymaster.rs similarity index 100% rename from crates/node/src/config/paymaster.rs rename to crates/node/node/src/config/paymaster.rs diff --git a/crates/node/src/config/rpc.rs b/crates/node/node/src/config/rpc.rs similarity index 87% rename from crates/node/src/config/rpc.rs rename to crates/node/node/src/config/rpc.rs index 2299f3327..78e05c132 100644 --- a/crates/node/src/config/rpc.rs +++ b/crates/node/node/src/config/rpc.rs @@ -1,20 +1,11 @@ use std::collections::HashSet; -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::net::{IpAddr, SocketAddr}; use std::time::Duration; +pub use katana_node_defaults::rpc::*; use katana_rpc::cors::HeaderValue; use serde::{Deserialize, Serialize}; -pub const DEFAULT_RPC_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST); -pub const DEFAULT_RPC_PORT: u16 = 5050; - -/// Default maximmum page size for the `starknet_getEvents` RPC method. -pub const DEFAULT_RPC_MAX_EVENT_PAGE_SIZE: u64 = 1024; -/// Default maximmum number of keys for the `starknet_getStorageProof` RPC method. -pub const DEFAULT_RPC_MAX_PROOF_KEYS: u64 = 100; -/// Default maximum gas for the `starknet_call` RPC method. -pub const DEFAULT_RPC_MAX_CALL_GAS: u64 = 1_000_000_000; - /// List of RPC modules supported by Katana. #[derive( Debug, @@ -127,6 +118,30 @@ impl RpcModulesList { self.0.is_empty() } + /// Parses from an iterator of strings. + pub fn parse_from_iter(iter: I) -> Result + where + I: IntoIterator, + S: AsRef, + { + let mut modules = HashSet::new(); + for module_name in iter { + let trimmed_module_name = module_name.as_ref().trim(); + + if trimmed_module_name.is_empty() { + continue; + } + + let module: RpcModuleKind = trimmed_module_name + .parse() + .map_err(|_| InvalidRpcModuleError(trimmed_module_name.to_string()))?; + + modules.insert(module); + } + + Ok(Self(modules)) + } + /// Used as the value parser for `clap`. pub fn parse(value: &str) -> Result { if value.is_empty() { @@ -157,7 +172,6 @@ impl Default for RpcModulesList { Self(HashSet::from([RpcModuleKind::Starknet])) } } - #[cfg(test)] mod tests { use super::*; diff --git a/crates/node/src/config/sequencing.rs b/crates/node/node/src/config/sequencing.rs similarity index 100% rename from crates/node/src/config/sequencing.rs rename to crates/node/node/src/config/sequencing.rs diff --git a/crates/node/src/exit.rs b/crates/node/node/src/exit.rs similarity index 100% rename from crates/node/src/exit.rs rename to crates/node/node/src/exit.rs diff --git a/crates/node/src/full/exit.rs b/crates/node/node/src/full/exit.rs similarity index 100% rename from crates/node/src/full/exit.rs rename to crates/node/node/src/full/exit.rs diff --git a/crates/node/src/full/mod.rs b/crates/node/node/src/full/mod.rs similarity index 100% rename from crates/node/src/full/mod.rs rename to crates/node/node/src/full/mod.rs diff --git a/crates/node/src/full/node.rs b/crates/node/node/src/full/node.rs similarity index 100% rename from crates/node/src/full/node.rs rename to crates/node/node/src/full/node.rs diff --git a/crates/node/src/full/tip_watcher.rs b/crates/node/node/src/full/tip_watcher.rs similarity index 100% rename from crates/node/src/full/tip_watcher.rs rename to crates/node/node/src/full/tip_watcher.rs diff --git a/crates/node/src/lib.rs b/crates/node/node/src/lib.rs similarity index 100% rename from crates/node/src/lib.rs rename to crates/node/node/src/lib.rs diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 0d54e567f..895b19ce9 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -10,10 +10,7 @@ version.workspace = true anyhow.workspace = true arbitrary = { workspace = true, optional = true } base64.workspace = true -blockifier = { workspace = true, features = [ "testing" ] } # some Clone derives are gated behind 'testing' feature cainome-cairo-serde.workspace = true -cairo-lang-starknet-classes.workspace = true -cairo-vm.workspace = true derive_more.workspace = true heapless = { version = "0.8.0", features = [ "serde" ] } lazy_static.workspace = true @@ -25,7 +22,6 @@ serde_with.workspace = true starknet.workspace = true starknet-crypto.workspace = true starknet-types-core.workspace = true -starknet_api.workspace = true thiserror.workspace = true alloy-primitives = { workspace = true, features = [ "arbitrary" ] } @@ -34,6 +30,12 @@ serde_json_pythonic = "0.1.2" strum.workspace = true strum_macros.workspace = true +# some Clone derives are gated behind 'testing' feature +blockifier = { workspace = true, features = [ "testing" ] } +cairo-lang-starknet-classes.workspace = true +cairo-vm.workspace = true +starknet_api.workspace = true + [dev-dependencies] assert_matches.workspace = true postcard.workspace = true @@ -44,13 +46,12 @@ criterion.workspace = true pprof.workspace = true [features] -default = [ "serde" ] - arbitrary = [ "alloy-primitives/arbitrary", "cairo-vm/test_utils", "dep:arbitrary", ] +default = [ "serde" ] serde = [ "alloy-primitives/serde", "blockifier/transaction_serde" ] [[bench]] diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 72c4e8c47..eca9e7101 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -166,6 +166,12 @@ impl LowerHex for GasPrice { } } +impl From for GasPrice { + fn from(value: NonZeroU128) -> Self { + Self(value) + } +} + #[derive(thiserror::Error, Debug)] #[error("gas price cannot be zero")] pub struct GasPriceIsZeroError; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index dbca53362..1cdeddfe1 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -20,10 +20,10 @@ pub mod version; pub mod state; pub mod utils; +pub use ::starknet::macros::felt; pub use alloy_primitives::{B256, U256}; pub use contract::ContractAddress; pub use eth::address as eth_address; -pub use starknet::macros::felt; pub use starknet_types_core::felt::{Felt, FromStrError}; pub use starknet_types_core::hash; diff --git a/tests/db-compat/Cargo.toml b/tests/db-compat/Cargo.toml index f3d6045ee..9c4f7ecce 100644 --- a/tests/db-compat/Cargo.toml +++ b/tests/db-compat/Cargo.toml @@ -7,12 +7,13 @@ version.workspace = true [dependencies] katana-chain-spec.workspace = true -katana-cli.workspace = true katana-db.workspace = true katana-node.workspace = true +katana-node-cli.workspace = true katana-primitives.workspace = true katana-provider.workspace = true anyhow.workspace = true +clap.workspace = true starknet.workspace = true tokio = { workspace = true, features = [ "full" ] } diff --git a/tests/db-compat/src/main.rs b/tests/db-compat/src/main.rs index a8e0c43cc..f6a53d5be 100644 --- a/tests/db-compat/src/main.rs +++ b/tests/db-compat/src/main.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use katana_cli::args::Parser; use katana_db::version::CURRENT_DB_VERSION; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider, Url}; @@ -12,7 +11,7 @@ async fn main() -> Result<()> { const TEST_DB_DIR: &str = "tests/fixtures/db/v1_2_2"; - let node = katana_cli::NodeArgs::parse_from(["katana", "--db-dir", TEST_DB_DIR]); + let node = katana_node_cli::Cli::parse_from(["katana", "--db-dir", TEST_DB_DIR]); let addr = node.rpc_config().unwrap().socket_addr(); tokio::spawn(async move { node.execute().await });