From 922cd86f0a2b36b0c8d58e1763f68084f6d48ccb Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Wed, 11 Mar 2026 19:32:34 +0000 Subject: [PATCH 01/19] chore: migrate to protocol release/v0.14.0-beta Update all miden-protocol dependencies from 0.14.0-alpha.1 to 0.14.0-beta.1 (crates.io). Update miden-crypto from 0.19.7 to 0.22. Bump node workspace version to 0.14.0-beta.1. Key migration changes: - Serialization traits moved to utils::serde submodule - Felt::as_int() -> Felt::as_canonical_u64() - falcon512_rpo -> falcon512_poseidon2 - ProvenTransactionBuilder removed, use ProvenTransaction::new() - OutputNote variants: Full -> Public, Header -> Private - Asset is now key-value (two words instead of one) - MmrProof fields are now methods - account_id_to_smt_key -> AccountIdKey::from() - miden-air removed (replaced by miden-core 0.21) - SmtStorage trait methods now take &mut self - Various other API changes in miden-crypto 0.22 --- Cargo.lock | 708 +++++++++++++----- Cargo.toml | 44 +- bin/network-monitor/src/counter.rs | 15 +- bin/network-monitor/src/deploy/counter.rs | 4 +- bin/network-monitor/src/deploy/mod.rs | 4 +- bin/network-monitor/src/deploy/wallet.rs | 6 +- bin/network-monitor/src/remote_prover.rs | 6 +- bin/node/src/commands/bundled.rs | 2 +- bin/node/src/commands/mod.rs | 2 +- bin/node/src/commands/validator.rs | 2 +- bin/remote-prover/src/server/prover.rs | 10 +- bin/remote-prover/src/server/tests.rs | 14 +- bin/stress-test/Cargo.toml | 1 - bin/stress-test/src/seeding/mod.rs | 40 +- bin/stress-test/src/store/mod.rs | 2 +- .../block-producer/src/domain/transaction.rs | 2 +- crates/block-producer/src/errors.rs | 4 +- .../src/mempool/subscription.rs | 6 +- crates/block-producer/src/store/mod.rs | 2 +- crates/block-producer/src/test_utils/note.rs | 4 +- .../src/test_utils/proven_tx.rs | 27 +- crates/block-producer/src/validator/mod.rs | 2 +- crates/db/src/conv.rs | 2 +- crates/large-smt-backend-rocksdb/Cargo.toml | 1 - crates/large-smt-backend-rocksdb/src/lib.rs | 6 +- .../large-smt-backend-rocksdb/src/rocksdb.rs | 41 +- crates/ntx-builder/src/actor/execute.rs | 9 +- .../ntx-builder/src/clients/block_producer.rs | 2 +- crates/ntx-builder/src/clients/store.rs | 2 +- crates/ntx-builder/src/db/models/conv.rs | 2 +- .../ntx-builder/src/db/models/queries/mod.rs | 2 +- .../src/db/models/queries/notes.rs | 2 +- .../src/db/models/queries/tests.rs | 16 +- crates/proto/src/domain/account.rs | 30 +- crates/proto/src/domain/batch.rs | 2 +- crates/proto/src/domain/block.rs | 2 +- crates/proto/src/domain/digest.rs | 23 +- crates/proto/src/domain/mempool.rs | 2 +- crates/proto/src/domain/note.rs | 2 +- crates/proto/src/domain/proof_request.rs | 2 +- crates/proto/src/domain/transaction.rs | 2 +- crates/proto/src/errors/mod.rs | 2 +- .../src/remote_prover/batch_prover.rs | 4 +- .../src/remote_prover/block_prover.rs | 4 +- .../src/remote_prover/tx_prover.rs | 4 +- crates/rpc/Cargo.toml | 1 - crates/rpc/src/server/api.rs | 44 +- crates/rpc/src/tests.rs | 16 +- crates/store/Cargo.toml | 2 +- crates/store/benches/account_tree.rs | 4 +- crates/store/build.rs | 14 +- crates/store/src/account_state_forest/mod.rs | 270 ++++--- .../store/src/account_state_forest/tests.rs | 64 +- crates/store/src/accounts/tests.rs | 4 +- crates/store/src/blocks.rs | 2 +- crates/store/src/db/mod.rs | 4 +- crates/store/src/db/models/conv.rs | 2 +- .../store/src/db/models/queries/accounts.rs | 12 +- .../db/models/queries/accounts/at_block.rs | 4 +- .../src/db/models/queries/accounts/delta.rs | 2 +- .../db/models/queries/accounts/delta/tests.rs | 25 +- .../src/db/models/queries/accounts/tests.rs | 76 +- .../src/db/models/queries/block_headers.rs | 2 +- crates/store/src/db/models/queries/notes.rs | 2 +- .../store/src/db/models/queries/nullifiers.rs | 2 +- .../src/db/models/queries/transactions.rs | 2 +- crates/store/src/db/models/utils.rs | 4 +- crates/store/src/db/tests.rs | 91 ++- crates/store/src/genesis/config/errors.rs | 2 +- crates/store/src/genesis/config/mod.rs | 17 +- .../agglayer_faucet_eth.mac | Bin 11393 -> 11846 bytes .../agglayer_faucet_usdc.mac | Bin 11393 -> 11846 bytes .../samples/02-with-account-files/bridge.mac | Bin 19129 -> 19853 bytes crates/store/src/genesis/config/tests.rs | 12 +- crates/store/src/genesis/mod.rs | 7 +- crates/store/src/server/api.rs | 4 +- crates/store/src/server/block_producer.rs | 2 +- crates/store/src/server/ntx_builder.rs | 7 +- crates/store/src/server/rpc_api.rs | 2 +- crates/store/src/state/apply_block.rs | 15 +- crates/store/src/state/loader.rs | 16 +- crates/validator/src/db/mod.rs | 2 +- crates/validator/src/db/models.rs | 2 +- crates/validator/src/server/mod.rs | 2 +- crates/validator/src/signers/kms.rs | 146 +++- .../src/tx_validation/validated_tx.rs | 4 +- proto/proto/types/primitives.proto | 6 +- 87 files changed, 1225 insertions(+), 741 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a6b076df8..dd8824b1fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -693,6 +693,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.72.1" @@ -1575,7 +1584,7 @@ dependencies = [ "futures-core", "futures-sink", "nanorand", - "spin", + "spin 0.9.8", ] [[package]] @@ -2550,12 +2559,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -2681,9 +2684,9 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miden-agglayer" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e492a6044cf8875a64d7eec130d260f2eda1c783795261f00d5d52837ed027bd" +checksum = "8141fcf37987fabf0cbb80c27a34a9cccc4255df16c3a2131787a5d93fe6723c" dependencies = [ "fs-err", "miden-assembly", @@ -2701,22 +2704,22 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cca9632323bd4e32ae5b21b101ed417a646f5d72196b1bf3f1ca889a148322a" +checksum = "d8aa2b3bc95d9eece8b47edbc6621b5742e212b359ff6b82ebb813b3d9b28985" dependencies = [ "miden-core", + "miden-crypto", "miden-utils-indexing", "thiserror 2.0.18", - "winter-air", - "winter-prover", + "tracing", ] [[package]] name = "miden-assembly" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2395b2917aea613a285d3425d1ca07e6c45442e2b34febdea2081db555df62fc" +checksum = "89369e85051e14e21c52f8e38456b4db958151afb32a3cef0a522e04163ec5c2" dependencies = [ "env_logger", "log", @@ -2729,9 +2732,9 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f9bed037d137f209b9e7b28811ec78c0536b3f9259d6f4ceb5823c87513b346" +checksum = "9069e6fa110d918662ce77eecfc3d7f906050023fad899f414fc63122e31b771" dependencies = [ "aho-corasick", "env_logger", @@ -2753,9 +2756,9 @@ dependencies = [ [[package]] name = "miden-block-prover" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9564dfb23c529aad68369845b6897a6f62bacdeab7c00db432a5f16670764d4" +checksum = "ed58b050df5203c8bd848afccb1b6539d743da76891076349539d1a5de4f10cc" dependencies = [ "miden-protocol", "thiserror 2.0.18", @@ -2763,9 +2766,9 @@ dependencies = [ [[package]] name = "miden-core" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8714aa5f86c59e647b7417126b32adc4ef618f835964464f5425549df76b6d03" +checksum = "9a9ebf937ab3ebc6d540cc7c48dd5cfc08da8b19e38757f71229d6b50414268b" dependencies = [ "derive_more", "itertools 0.14.0", @@ -2774,20 +2777,19 @@ dependencies = [ "miden-formatting", "miden-utils-core-derive", "miden-utils-indexing", + "miden-utils-sync", "num-derive", "num-traits", "proptest", "proptest-derive", "thiserror 2.0.18", - "winter-math", - "winter-utils", ] [[package]] name = "miden-core-lib" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb16a4d39202c59a7964d3585cd5af21a46a759ff6452cb5f20723ed5af4362" +checksum = "fa496b3a7546c0022e8d5a92d88726907e380074f1fb634859b5e2094270dacf" dependencies = [ "env_logger", "fs-err", @@ -2796,15 +2798,14 @@ dependencies = [ "miden-crypto", "miden-processor", "miden-utils-sync", - "sha2", "thiserror 2.0.18", ] [[package]] name = "miden-crypto" -version = "0.19.8" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be59336a868de7c379eace9450563c2d7f4a0b7ab936835ec5a340dcd8d9a5ed" +checksum = "4b8fc3ec2033d3e17a40611f3ab7c20b0578ccf5e6ddcc9a1df9f26599e6ebdd" dependencies = [ "blake3", "cc", @@ -2817,8 +2818,26 @@ dependencies = [ "hkdf", "k256", "miden-crypto-derive", + "miden-field", + "miden-serde-utils", "num", "num-complex", + "p3-air", + "p3-blake3", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-goldilocks", + "p3-keccak", + "p3-matrix", + "p3-maybe-rayon", + "p3-merkle-tree", + "p3-miden-air", + "p3-miden-fri", + "p3-miden-prover", + "p3-symmetric", + "p3-util", "rand", "rand_chacha", "rand_core 0.9.5", @@ -2828,17 +2847,14 @@ dependencies = [ "sha3", "subtle", "thiserror 2.0.18", - "winter-crypto", - "winter-math", - "winter-utils", "x25519-dalek", ] [[package]] name = "miden-crypto-derive" -version = "0.19.6" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550b5656b791fec59c0b6089b4d0368db746a34749ccd47e59afb01aa877e9e" +checksum = "207828f24e358b4e1e0641c37802816b8730816ff92ddb4d271ef3a00f8696bb" dependencies = [ "quote", "syn 2.0.114", @@ -2846,9 +2862,9 @@ dependencies = [ [[package]] name = "miden-debug-types" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1494f102ad5b9fa43e391d2601186dc601f41ab7dcd8a23ecca9bf3ef930f4" +checksum = "6bbdee85c103fe0979ed05f888da8c0b078446b2feee17a67f56d75d6189adae" dependencies = [ "memchr", "miden-crypto", @@ -2862,6 +2878,23 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "miden-field" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f821a07c16cfa6e500d5a56d05c11523984e3cd562cfc80ef657e4264d708067" +dependencies = [ + "miden-serde-utils", + "num-bigint", + "p3-challenger", + "p3-field", + "p3-goldilocks", + "paste", + "rand", + "serde", + "thiserror 2.0.18", +] + [[package]] name = "miden-formatting" version = "0.1.1" @@ -2873,25 +2906,25 @@ dependencies = [ [[package]] name = "miden-large-smt-backend-rocksdb" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "miden-crypto", "miden-node-rocksdb-cxx-linkage-fix", "miden-protocol", "rayon", "rocksdb", - "winter-utils", ] [[package]] name = "miden-mast-package" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692185bfbe0ecdb28bf623f1f8c88282cd6727ba081a28e23b301bdde1b45be4" +checksum = "47f6dfbe2e3a2ca9977a46551d378cf4c5232624d50bd604c644eaa95342a5c1" dependencies = [ "derive_more", "miden-assembly-syntax", "miden-core", + "miden-debug-types", "thiserror 2.0.18", ] @@ -2901,8 +2934,6 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eef536978f24a179d94fa2a41e4f92b28e7d8aab14b8d23df28ad2a3d7098b20" dependencies = [ - "backtrace", - "backtrace-ext", "cfg-if", "futures", "indenter", @@ -2913,13 +2944,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin", + "spin 0.9.8", "strip-ansi-escapes", - "supports-color", - "supports-hyperlinks", - "supports-unicode", "syn 2.0.114", - "terminal_size 0.3.0", "textwrap", "thiserror 2.0.18", "trybuild", @@ -2939,7 +2966,7 @@ dependencies = [ [[package]] name = "miden-network-monitor" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "axum", @@ -2967,7 +2994,7 @@ dependencies = [ [[package]] name = "miden-node" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "clap", @@ -2987,7 +3014,7 @@ dependencies = [ [[package]] name = "miden-node-block-producer" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "assert_matches", @@ -3023,7 +3050,7 @@ dependencies = [ [[package]] name = "miden-node-db" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "deadpool", "deadpool-diesel", @@ -3036,7 +3063,7 @@ dependencies = [ [[package]] name = "miden-node-grpc-error-macro" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "quote", "syn 2.0.114", @@ -3044,7 +3071,7 @@ dependencies = [ [[package]] name = "miden-node-ntx-builder" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "build-rs", @@ -3074,7 +3101,7 @@ dependencies = [ [[package]] name = "miden-node-proto" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "assert_matches", @@ -3099,7 +3126,7 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "build-rs", "fs-err", @@ -3110,17 +3137,16 @@ dependencies = [ [[package]] name = "miden-node-rocksdb-cxx-linkage-fix" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" [[package]] name = "miden-node-rpc" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "futures", "http 1.4.0", "mediatype", - "miden-air", "miden-node-proto", "miden-node-proto-build", "miden-node-store", @@ -3146,7 +3172,7 @@ dependencies = [ [[package]] name = "miden-node-store" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "assert_matches", @@ -3193,12 +3219,11 @@ dependencies = [ [[package]] name = "miden-node-stress-test" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "clap", "fs-err", "futures", - "miden-air", "miden-node-block-producer", "miden-node-proto", "miden-node-store", @@ -3222,7 +3247,7 @@ dependencies = [ [[package]] name = "miden-node-utils" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "bytes", @@ -3253,7 +3278,7 @@ dependencies = [ [[package]] name = "miden-node-validator" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "aws-config", @@ -3278,9 +3303,9 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e09f7916b1e7505f74a50985a185fdea4c0ceb8f854a34c90db28e3f7da7ab6" +checksum = "13c83cc2f87364c88f6b7d7acb0c7908b63064ed94e0b2b68a0f5990f74a42c5" dependencies = [ "itertools 0.14.0", "miden-air", @@ -3293,14 +3318,13 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tracing", - "winter-prover", ] [[package]] name = "miden-protocol" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a88effeac994eb55b8dc4f93fbfd71a5d916dfaba1099896e27a0ee42c488c1" +checksum = "64b41308a7d7c031a571f4ee7bfb1a0a25f6e2a1fe4378fe8d4c0bfd5fe4cf56" dependencies = [ "bech32", "fs-err", @@ -3322,16 +3346,15 @@ dependencies = [ "semver 1.0.27", "serde", "thiserror 2.0.18", - "toml 0.9.11+spec-1.1.0", + "toml 1.0.3+spec-1.1.0", "walkdir", - "winter-rand-utils", ] [[package]] name = "miden-protocol-macros" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb28b730005e5f8b08d615ea9216f8cab77b3a7439fa54d5e39d2ec43ef53a3" +checksum = "6d4626a7e06401a2eae244d4b480ff9fd3518c1f3d839781919e9fb6c635fe33" dependencies = [ "proc-macro2", "quote", @@ -3340,21 +3363,24 @@ dependencies = [ [[package]] name = "miden-prover" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45e30526be72b8af0fd1d8b24c9cba8ac1187ca335dcee38b8e5e20234e7698" +checksum = "d0fe4c03cc2a5c0404596f10c076e8e265d87fb7a9c5fbe21b15bc12874f7855" dependencies = [ + "bincode", "miden-air", + "miden-core", + "miden-crypto", "miden-debug-types", "miden-processor", + "serde", + "tokio", "tracing", - "winter-maybe-async", - "winter-prover", ] [[package]] name = "miden-remote-prover" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "anyhow", "assert_matches", @@ -3391,7 +3417,7 @@ dependencies = [ [[package]] name = "miden-remote-prover-client" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" dependencies = [ "build-rs", "fs-err", @@ -3410,11 +3436,21 @@ dependencies = [ "tonic-web-wasm-client", ] +[[package]] +name = "miden-serde-utils" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fe74c2e7d8a8b8758e067de10665816928222c1d0561d95c12ac4bcaefc2a2a" +dependencies = [ + "p3-field", + "p3-goldilocks", +] + [[package]] name = "miden-standards" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cef036bbfec29acba92751a13d05844bbcf080140201097b419c9ad1927e367" +checksum = "396b3c71888c6f29a60c44ed55054ee1a095598e773bd10d21c5f7ce28fad28a" dependencies = [ "fs-err", "miden-assembly", @@ -3430,9 +3466,9 @@ dependencies = [ [[package]] name = "miden-testing" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e980777d0f7e6069942b14d4e7cb3d4d137b323ddfa15722a3bd21e9d13fdd2e" +checksum = "f7800cb840e276287dc1903994cd85b0f4d31ea9b53fc182dbe13bd4cea24a75" dependencies = [ "anyhow", "itertools 0.14.0", @@ -3449,14 +3485,13 @@ dependencies = [ "rand", "rand_chacha", "thiserror 2.0.18", - "winterfell", ] [[package]] name = "miden-tx" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c67e0df9adcf29c9111df65acf408ae05952b8bc6569f571963676f97668d83f" +checksum = "13c13cdc3710524abf2015cbc27019f4b9456f34e83c589d744904074d670738" dependencies = [ "miden-processor", "miden-protocol", @@ -3468,9 +3503,9 @@ dependencies = [ [[package]] name = "miden-tx-batch-prover" -version = "0.14.0-alpha.1" +version = "0.14.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba29f8f6ecae671eff8b52b4c19eca8db5964c0b45b5d68c3ce38a57a8367931" +checksum = "6f298662bcf40ae025ef7c0ffa4e2ac5515985fd23c962e359bf578824b52ed6" dependencies = [ "miden-protocol", "miden-tx", @@ -3478,9 +3513,9 @@ dependencies = [ [[package]] name = "miden-utils-core-derive" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b1d490e6d7b509622d3c2cc69ffd66ad48bf953dc614579b568fe956ce0a6c" +checksum = "ad5c364abe484d43d171afc320e7560db37ece00fe625569068c1053ed186540" dependencies = [ "proc-macro2", "quote", @@ -3489,9 +3524,9 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52658f6dc091c1c78e8b35ee3e7ff3dad53051971a3c514e461f581333758fe7" +checksum = "467d8eafd735ab1e0db7bf6a6a8b5bcf4c31a56c0cd7f80cba1932d4bb984b12" dependencies = [ "miden-crypto", "miden-debug-types", @@ -3502,35 +3537,38 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff7bcb7875b222424bdfb657a7cf21a55e036aa7558ebe1f5d2e413b440d0d" +checksum = "bc42cfa3aef68d21238b3ce4c2db00a1278f8075ef492c23c035ab6c75774790" dependencies = [ + "miden-crypto", "thiserror 2.0.18", ] [[package]] name = "miden-utils-sync" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d53d1ab5b275d8052ad9c4121071cb184bc276ee74354b0d8a2075e5c1d1f0" +checksum = "b7e09bb239449e63e9a81f9b4ca5db1762327f44fb50777527fdba6fdbcab890" dependencies = [ "lock_api", "loom", + "once_cell", "parking_lot", ] [[package]] name = "miden-verifier" -version = "0.20.6" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13816663794beb15c8a4721c15252eb21f3b3233525684f60c7888837a98ff4" +checksum = "fbb4d3120e2c9cce41b5dac7507cd86154951938b9effbc322c57983065bfa4a" dependencies = [ + "bincode", "miden-air", "miden-core", + "miden-crypto", "thiserror 2.0.18", "tracing", - "winter-verifier", ] [[package]] @@ -3558,7 +3596,7 @@ dependencies = [ "supports-color", "supports-hyperlinks", "supports-unicode", - "terminal_size 0.4.3", + "terminal_size", "textwrap", "unicode-width 0.1.14", ] @@ -3891,6 +3929,338 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" +[[package]] +name = "p3-air" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0141a56ed9924ce0265e7e91cd29bbcd230262744b7a7f0c448bfbf212f73182" +dependencies = [ + "p3-field", + "p3-matrix", +] + +[[package]] +name = "p3-blake3" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006330bae15fdda0d460e73e03e7ebf06e8848dfda8355f9d568a7fed7c37719" +dependencies = [ + "blake3", + "p3-symmetric", + "p3-util", +] + +[[package]] +name = "p3-challenger" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e42ba74a49c08c6e99f74cd9b343bfa31aa5721fea55079b18e3fd65f1dcbc" +dependencies = [ + "p3-field", + "p3-maybe-rayon", + "p3-monty-31", + "p3-symmetric", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-commit" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498211e7b9a0f8366b410b4a9283ae82ff2fc91f473b1c5816aa6e90e74b125d" +dependencies = [ + "itertools 0.14.0", + "p3-challenger", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-util", + "serde", +] + +[[package]] +name = "p3-dft" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63fa5eb1bd12a240089e72ae3fe10350944d9c166d00a3bfd2a1794db65cf5c" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "spin 0.10.0", + "tracing", +] + +[[package]] +name = "p3-field" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ebfdb6ef992ae64e9e8f449ac46516ffa584f11afbdf9ee244288c2a633cdf4" +dependencies = [ + "itertools 0.14.0", + "num-bigint", + "p3-maybe-rayon", + "p3-util", + "paste", + "rand", + "serde", + "tracing", +] + +[[package]] +name = "p3-goldilocks" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64716244b5612622d4e78a4f48b74f6d3bb7b4085b7b6b25364b1dfca7198c66" +dependencies = [ + "num-bigint", + "p3-challenger", + "p3-dft", + "p3-field", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "paste", + "rand", + "serde", +] + +[[package]] +name = "p3-interpolation" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d877565a94a527c89459fc8ccb0eb58769d8c86456575d1315a1651bd24616d" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", +] + +[[package]] +name = "p3-keccak" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57334537d10316e0f1cda622f0a5b3239f219a5dcd2a95ea87e41e00df6a92" +dependencies = [ + "p3-field", + "p3-symmetric", + "p3-util", + "tiny-keccak", +] + +[[package]] +name = "p3-matrix" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5542f96504dae8100c91398fb1e3f5ec669eb9c73d9e0b018a93b5fe32bad230" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand", + "serde", + "tracing", + "transpose", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5669ca75645f99cd001e9d0289a4eeff2bc2cd9dc3c6c3aaf22643966e83df" +dependencies = [ + "rayon", +] + +[[package]] +name = "p3-mds" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038763af23df9da653065867fd85b38626079031576c86fd537097e5be6a0da0" +dependencies = [ + "p3-dft", + "p3-field", + "p3-symmetric", + "p3-util", + "rand", +] + +[[package]] +name = "p3-merkle-tree" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d93625a3041effddc72ee2511c919f710b7f91fd0f9931ab8a70aeba586fd6e" +dependencies = [ + "itertools 0.14.0", + "p3-commit", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "rand", + "serde", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "p3-miden-air" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a88e6ee9c92ff6c0b64f1ec0d61eda72fb432bda45337d876c46bd43748508" +dependencies = [ + "p3-air", + "p3-field", + "p3-matrix", +] + +[[package]] +name = "p3-miden-fri" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e282998bc1d12dceaa0ed8979fa507b8369d663fa377da695d578f5f3a035935" +dependencies = [ + "itertools 0.14.0", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "rand", + "serde", + "tracing", +] + +[[package]] +name = "p3-miden-prover" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05a61c10cc2d6a73e192ac34a9884e4f26bd877f3eaea441d7b7ebfdffdf6c7" +dependencies = [ + "itertools 0.14.0", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-miden-air", + "p3-miden-uni-stark", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-miden-uni-stark" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a78b6a5b5f6bdc55439d343d2a0a2a8e7cb6544b03296f54d2214a84e91e130" +dependencies = [ + "itertools 0.14.0", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-uni-stark", + "p3-util", + "serde", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "p3-monty-31" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a981d60da3d8cbf8561014e2c186068578405fd69098fa75b43d4afb364a47" +dependencies = [ + "itertools 0.14.0", + "num-bigint", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "paste", + "rand", + "serde", + "spin 0.10.0", + "tracing", + "transpose", +] + +[[package]] +name = "p3-poseidon2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903b73e4f9a7781a18561c74dc169cf03333497b57a8dd02aaeb130c0f386599" +dependencies = [ + "p3-field", + "p3-mds", + "p3-symmetric", + "p3-util", + "rand", +] + +[[package]] +name = "p3-symmetric" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd788f04e86dd5c35dd87cad29eefdb6371d2fd5f7664451382eeacae3c3ed0" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "serde", +] + +[[package]] +name = "p3-uni-stark" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68d409704a8cbdb6c77f6b83a05c6b16a3c8a2c00d880146fa34181977a0d3ac" +dependencies = [ + "itertools 0.14.0", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "serde", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "p3-util" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "663b16021930bc600ecada915c6c3965730a3b9d6a6c23434ccf70bfc29d6881" +dependencies = [ + "rayon", + "serde", +] + [[package]] name = "page_size" version = "0.6.0" @@ -4658,19 +5028,6 @@ dependencies = [ "semver 1.0.27", ] -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", -] - [[package]] name = "rustix" version = "1.1.3" @@ -4680,7 +5037,7 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.11.0", + "linux-raw-sys", "windows-sys 0.61.2", ] @@ -5134,6 +5491,15 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +dependencies = [ + "lock_api", +] + [[package]] name = "spinning_top" version = "0.3.0" @@ -5177,6 +5543,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strength_reduce" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" + [[package]] name = "string_cache" version = "0.8.9" @@ -5309,7 +5681,7 @@ dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix 1.1.3", + "rustix", "windows-sys 0.61.2", ] @@ -5331,23 +5703,13 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "terminal_size" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" -dependencies = [ - "rustix 0.38.44", - "windows-sys 0.48.0", -] - [[package]] name = "terminal_size" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ - "rustix 1.1.3", + "rustix", "windows-sys 0.60.2", ] @@ -5448,6 +5810,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinystr" version = "0.8.2" @@ -5943,6 +6314,16 @@ dependencies = [ "tracing-serde", ] +[[package]] +name = "transpose" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" +dependencies = [ + "num-integer", + "strength_reduce", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -6412,15 +6793,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -6463,21 +6835,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -6517,12 +6874,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -6541,12 +6892,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -6565,12 +6910,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6601,12 +6940,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -6625,12 +6958,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -6649,12 +6976,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -6673,12 +6994,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -6770,24 +7085,11 @@ dependencies = [ "winter-utils", ] -[[package]] -name = "winter-rand-utils" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ff3b651754a7bd216f959764d0a5ab6f4b551c9a3a08fb9ccecbed594b614a" -dependencies = [ - "rand", - "winter-utils", -] - [[package]] name = "winter-utils" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9951263ef5317740cd0f49e618db00c72fabb70b75756ea26c4d5efe462c04dd" -dependencies = [ - "rayon", -] [[package]] name = "winter-verifier" diff --git a/Cargo.toml b/Cargo.toml index 2156ddf8f8..1dabe05c65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ license = "MIT" readme = "README.md" repository = "https://github.com/0xMiden/node" rust-version = "1.91" -version = "0.14.0-alpha.5" +version = "0.14.0-beta.1" # Optimize the cryptography for faster tests involving account creation. [profile.test.package.miden-crypto] @@ -46,35 +46,33 @@ debug = true [workspace.dependencies] # Workspace crates. -miden-large-smt-backend-rocksdb = { path = "crates/large-smt-backend-rocksdb", version = "=0.14.0-alpha.5" } -miden-node-block-producer = { path = "crates/block-producer", version = "=0.14.0-alpha.5" } -miden-node-db = { path = "crates/db", version = "=0.14.0-alpha.5" } -miden-node-grpc-error-macro = { path = "crates/grpc-error-macro", version = "=0.14.0-alpha.5" } -miden-node-ntx-builder = { path = "crates/ntx-builder", version = "=0.14.0-alpha.5" } -miden-node-proto = { path = "crates/proto", version = "=0.14.0-alpha.5" } -miden-node-proto-build = { path = "proto", version = "=0.14.0-alpha.5" } -miden-node-rpc = { path = "crates/rpc", version = "=0.14.0-alpha.5" } -miden-node-store = { path = "crates/store", version = "=0.14.0-alpha.5" } +miden-large-smt-backend-rocksdb = { path = "crates/large-smt-backend-rocksdb", version = "=0.14.0-beta.1" } +miden-node-block-producer = { path = "crates/block-producer", version = "=0.14.0-beta.1" } +miden-node-db = { path = "crates/db", version = "=0.14.0-beta.1" } +miden-node-grpc-error-macro = { path = "crates/grpc-error-macro", version = "=0.14.0-beta.1" } +miden-node-ntx-builder = { path = "crates/ntx-builder", version = "=0.14.0-beta.1" } +miden-node-proto = { path = "crates/proto", version = "=0.14.0-beta.1" } +miden-node-proto-build = { path = "proto", version = "=0.14.0-beta.1" } +miden-node-rpc = { path = "crates/rpc", version = "=0.14.0-beta.1" } +miden-node-store = { path = "crates/store", version = "=0.14.0-beta.1" } miden-node-test-macro = { path = "crates/test-macro" } -miden-node-utils = { path = "crates/utils", version = "=0.14.0-alpha.5" } -miden-node-validator = { path = "crates/validator", version = "=0.14.0-alpha.5" } -miden-remote-prover-client = { path = "crates/remote-prover-client", version = "=0.14.0-alpha.5" } +miden-node-utils = { path = "crates/utils", version = "=0.14.0-beta.1" } +miden-node-validator = { path = "crates/validator", version = "=0.14.0-beta.1" } +miden-remote-prover-client = { path = "crates/remote-prover-client", version = "=0.14.0-beta.1" } # Temporary workaround until # is part of `rocksdb-rust` release -miden-node-rocksdb-cxx-linkage-fix = { path = "crates/rocksdb-cxx-linkage-fix", version = "=0.14.0-alpha.5" } +miden-node-rocksdb-cxx-linkage-fix = { path = "crates/rocksdb-cxx-linkage-fix", version = "=0.14.0-beta.1" } # miden-base aka protocol dependencies. These should be updated in sync. -miden-block-prover = { version = "=0.14.0-alpha.1" } -miden-protocol = { default-features = false, version = "=0.14.0-alpha.1" } -miden-standards = { version = "=0.14.0-alpha.1" } -miden-testing = { version = "=0.14.0-alpha.1" } -miden-tx = { default-features = false, version = "=0.14.0-alpha.1" } -miden-tx-batch-prover = { version = "=0.14.0-alpha.1" } +miden-block-prover = { version = "=0.14.0-beta.1" } +miden-protocol = { default-features = false, version = "=0.14.0-beta.1" } +miden-standards = { version = "=0.14.0-beta.1" } +miden-testing = { version = "=0.14.0-beta.1" } +miden-tx = { default-features = false, version = "=0.14.0-beta.1" } +miden-tx-batch-prover = { version = "=0.14.0-beta.1" } # Other miden dependencies. These should align with those expected by miden-base. -miden-air = { features = ["std", "testing"], version = "0.20" } - -miden-crypto = { version = "0.19.7" } +miden-crypto = { version = "0.22" } # External dependencies anyhow = { version = "1.0" } diff --git a/bin/network-monitor/src/counter.rs b/bin/network-monitor/src/counter.rs index dd004ff0d0..80c1df6917 100644 --- a/bin/network-monitor/src/counter.rs +++ b/bin/network-monitor/src/counter.rs @@ -16,7 +16,7 @@ use miden_protocol::account::auth::AuthSecretKey; use miden_protocol::account::{Account, AccountFile, AccountHeader, AccountId}; use miden_protocol::assembly::Library; use miden_protocol::block::{BlockHeader, BlockNumber}; -use miden_protocol::crypto::dsa::falcon512_rpo::SecretKey; +use miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey; use miden_protocol::note::{ Note, NoteAssets, @@ -28,13 +28,13 @@ use miden_protocol::note::{ NoteType, }; use miden_protocol::transaction::{InputNotes, PartialBlockchain, TransactionArgs}; -use miden_protocol::utils::Deserializable; +use miden_protocol::utils::serde::Deserializable; use miden_protocol::{Felt, Word}; use miden_standards::account::interface::{AccountInterface, AccountInterfaceExt}; use miden_standards::code_builder::CodeBuilder; use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint}; use miden_tx::auth::BasicAuthenticator; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use miden_tx::{LocalTransactionProver, TransactionExecutor}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha20Rng; @@ -130,7 +130,7 @@ async fn fetch_counter_value( .try_into() .context("failed to convert slot value to word")?; - let value = slot_value.as_elements().last().expect("Word has 4 elements").as_int(); + let value = slot_value.as_elements().last().expect("Word has 4 elements").as_canonical_u64(); Ok(Some(value)) } @@ -321,7 +321,7 @@ async fn setup_increment_task( .await? .unwrap_or(wallet_account_file.account.clone()); - let AuthSecretKey::Falcon512Rpo(secret_key) = wallet_account_file + let AuthSecretKey::Falcon512Poseidon2(secret_key) = wallet_account_file .auth_secret_keys .first() .expect("wallet account file should have one auth secret key") @@ -821,7 +821,8 @@ async fn create_and_submit_network_note( rng: &mut ChaCha20Rng, ) -> Result<(String, AccountHeader, BlockNumber)> { // Create authenticator for transaction signing - let authenticator = BasicAuthenticator::new(&[AuthSecretKey::Falcon512Rpo(secret_key.clone())]); + let authenticator = + BasicAuthenticator::new(&[AuthSecretKey::Falcon512Poseidon2(secret_key.clone())]); let account_interface = AccountInterface::from_account(wallet_account); @@ -851,7 +852,7 @@ async fn create_and_submit_network_note( // Prove the transaction let prover = LocalTransactionProver::default(); - let proven_tx = prover.prove(executed_tx).context("Failed to prove transaction")?; + let proven_tx = prover.prove(executed_tx).await.context("Failed to prove transaction")?; // Submit the proven transaction let request = ProvenTransaction { diff --git a/bin/network-monitor/src/deploy/counter.rs b/bin/network-monitor/src/deploy/counter.rs index e517beb063..94fbe8b657 100644 --- a/bin/network-monitor/src/deploy/counter.rs +++ b/bin/network-monitor/src/deploy/counter.rs @@ -16,7 +16,7 @@ use miden_protocol::account::{ StorageSlotName, }; use miden_protocol::utils::sync::LazyLock; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Felt, Word}; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::IncrNonceAuthComponent; use tracing::instrument; @@ -54,7 +54,7 @@ pub fn create_counter_account(owner_account_id: AccountId) -> Result { let component_code = CodeBuilder::default().compile_component_code("counter::program", script)?; - let metadata = AccountComponentMetadata::new("counter::program").with_supports_all_types(); + let metadata = AccountComponentMetadata::new("counter::program", AccountType::all()); let account_code = AccountComponent::new(component_code, vec![counter_slot, owner_id_slot], metadata)?; diff --git a/bin/network-monitor/src/deploy/mod.rs b/bin/network-monitor/src/deploy/mod.rs index b89c09aa0c..8e427ec97f 100644 --- a/bin/network-monitor/src/deploy/mod.rs +++ b/bin/network-monitor/src/deploy/mod.rs @@ -32,7 +32,7 @@ use miden_protocol::transaction::{ }; use miden_protocol::{MastForest, Word}; use miden_tx::auth::BasicAuthenticator; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use miden_tx::{ DataStore, DataStoreError, @@ -203,7 +203,7 @@ pub async fn deploy_counter_account(counter_account: &Account, rpc_url: &Url) -> let prover = LocalTransactionProver::default(); - let proven_tx = prover.prove(executed_tx).context("Failed to prove transaction")?; + let proven_tx = prover.prove(executed_tx).await.context("Failed to prove transaction")?; let request = ProvenTransaction { transaction: proven_tx.to_bytes(), diff --git a/bin/network-monitor/src/deploy/wallet.rs b/bin/network-monitor/src/deploy/wallet.rs index ba074a60f8..9b9274440d 100644 --- a/bin/network-monitor/src/deploy/wallet.rs +++ b/bin/network-monitor/src/deploy/wallet.rs @@ -6,7 +6,7 @@ use anyhow::Result; use miden_node_utils::crypto::get_rpo_random_coin; use miden_protocol::account::auth::{AuthScheme, AuthSecretKey}; use miden_protocol::account::{Account, AccountFile, AccountStorageMode, AccountType}; -use miden_protocol::crypto::dsa::falcon512_rpo::SecretKey; +use miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey; use miden_standards::AuthMethod; use miden_standards::account::wallets::create_basic_wallet; use rand::{Rng, SeedableRng}; @@ -23,7 +23,7 @@ pub fn create_wallet_account() -> Result<(Account, SecretKey)> { let mut rng = ChaCha20Rng::from_seed(rand::random()); let secret_key = SecretKey::with_rng(&mut get_rpo_random_coin(&mut rng)); let auth = AuthMethod::SingleSig { - approver: (secret_key.public_key().into(), AuthScheme::Falcon512Rpo), + approver: (secret_key.public_key().into(), AuthScheme::Falcon512Poseidon2), }; let init_seed: [u8; 32] = rng.random(); @@ -43,7 +43,7 @@ pub fn save_wallet_account( secret_key: &SecretKey, file_path: &Path, ) -> Result<()> { - let auth_secret_key = AuthSecretKey::Falcon512Rpo(secret_key.clone()); + let auth_secret_key = AuthSecretKey::Falcon512Poseidon2(secret_key.clone()); let account_file = AccountFile::new(account.clone(), vec![auth_secret_key]); account_file.write(file_path)?; Ok(()) diff --git a/bin/network-monitor/src/remote_prover.rs b/bin/network-monitor/src/remote_prover.rs index b103a60c42..471da67739 100644 --- a/bin/network-monitor/src/remote_prover.rs +++ b/bin/network-monitor/src/remote_prover.rs @@ -14,7 +14,7 @@ use miden_protocol::note::NoteType; use miden_protocol::testing::account_id::{ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, ACCOUNT_ID_SENDER}; use miden_protocol::transaction::TransactionInputs; use miden_testing::{Auth, MockChainBuilder}; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use serde::{Deserialize, Serialize}; use tokio::sync::watch; use tokio::time::MissedTickBehavior; @@ -278,7 +278,9 @@ pub async fn generate_mock_transaction() -> anyhow::Result { // Create an account with basic authentication let account = mock_chain_builder - .add_existing_wallet(Auth::BasicAuth { auth_scheme: AuthScheme::Falcon512Rpo }) + .add_existing_wallet(Auth::BasicAuth { + auth_scheme: AuthScheme::Falcon512Poseidon2, + }) .context("Failed to add wallet to mock chain")?; // Create a fungible asset diff --git a/bin/node/src/commands/bundled.rs b/bin/node/src/commands/bundled.rs index 4f20d812bf..eba5343a3a 100644 --- a/bin/node/src/commands/bundled.rs +++ b/bin/node/src/commands/bundled.rs @@ -9,7 +9,7 @@ use miden_node_utils::clap::GrpcOptionsExternal; use miden_node_utils::grpc::UrlExt; use miden_node_validator::{Validator, ValidatorSigner}; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; -use miden_protocol::utils::Deserializable; +use miden_protocol::utils::serde::Deserializable; use tokio::net::TcpListener; use tokio::task::JoinSet; use url::Url; diff --git a/bin/node/src/commands/mod.rs b/bin/node/src/commands/mod.rs index 9d3951cf0c..5b49ecaf6f 100644 --- a/bin/node/src/commands/mod.rs +++ b/bin/node/src/commands/mod.rs @@ -13,7 +13,7 @@ use miden_node_block_producer::{ use miden_node_utils::clap::duration_to_human_readable_string; use miden_node_validator::ValidatorSigner; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; -use miden_protocol::utils::Deserializable; +use miden_protocol::utils::serde::Deserializable; use tokio::net::TcpListener; use url::Url; diff --git a/bin/node/src/commands/validator.rs b/bin/node/src/commands/validator.rs index 5659e55fb0..0917041a1c 100644 --- a/bin/node/src/commands/validator.rs +++ b/bin/node/src/commands/validator.rs @@ -6,7 +6,7 @@ use miden_node_utils::clap::GrpcOptionsInternal; use miden_node_utils::grpc::UrlExt; use miden_node_validator::{Validator, ValidatorSigner}; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; -use miden_protocol::utils::Deserializable; +use miden_protocol::utils::serde::Deserializable; use url::Url; use crate::commands::{ diff --git a/bin/remote-prover/src/server/prover.rs b/bin/remote-prover/src/server/prover.rs index 6ca76794e5..587d8571ca 100644 --- a/bin/remote-prover/src/server/prover.rs +++ b/bin/remote-prover/src/server/prover.rs @@ -52,8 +52,8 @@ impl Prover { /// Implementations of this trait only need to provide the input and outputs types, as well as the /// proof implementation. trait ProveRequest { - type Input: miden_protocol::utils::Deserializable; - type Output: miden_protocol::utils::Serializable; + type Input: miden_protocol::utils::serde::Deserializable; + type Output: miden_protocol::utils::serde::Serializable; fn prove(&self, input: Self::Input) -> Result; @@ -74,7 +74,7 @@ trait ProveRequest { #[instrument(target=COMPONENT, skip_all, err)] fn decode_request(request: proto::ProofRequest) -> Result { - use miden_protocol::utils::Deserializable; + use miden_protocol::utils::serde::Deserializable; Self::Input::read_from_bytes(&request.payload).map_err(|e| { tonic::Status::invalid_argument(e.as_report_context("failed to decode request")) @@ -83,7 +83,7 @@ trait ProveRequest { #[instrument(target=COMPONENT, skip_all)] fn encode_response(output: Self::Output) -> proto::Proof { - use miden_protocol::utils::Serializable; + use miden_protocol::utils::serde::Serializable; proto::Proof { payload: output.to_bytes() } } @@ -94,7 +94,7 @@ impl ProveRequest for LocalTransactionProver { type Output = ProvenTransaction; fn prove(&self, input: Self::Input) -> Result { - self.prove(input).map_err(|e| { + tokio::runtime::Handle::current().block_on(self.prove(input)).map_err(|e| { tonic::Status::internal(e.as_report_context("failed to prove transaction")) }) } diff --git a/bin/remote-prover/src/server/tests.rs b/bin/remote-prover/src/server/tests.rs index f1d526b16d..7ba10b23b1 100644 --- a/bin/remote-prover/src/server/tests.rs +++ b/bin/remote-prover/src/server/tests.rs @@ -12,7 +12,7 @@ use miden_protocol::note::NoteType; use miden_protocol::testing::account_id::{ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, ACCOUNT_ID_SENDER}; use miden_protocol::transaction::{ExecutedTransaction, ProvenTransaction}; use miden_testing::{Auth, MockChainBuilder}; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use miden_tx::{LocalTransactionProver, TransactionVerifier}; use miden_tx_batch_prover::LocalBatchProver; use serial_test::serial; @@ -64,7 +64,9 @@ impl ProofRequest { // Create a mock transaction to send to the server let mut mock_chain_builder = MockChainBuilder::new(); let account = mock_chain_builder - .add_existing_wallet(Auth::BasicAuth { auth_scheme: AuthScheme::Falcon512Rpo }) + .add_existing_wallet(Auth::BasicAuth { + auth_scheme: AuthScheme::Falcon512Poseidon2, + }) .unwrap(); let fungible_asset_1: Asset = @@ -96,7 +98,9 @@ impl ProofRequest { // Create a mock transaction to send to the server let mut mock_chain_builder = MockChainBuilder::new(); let account = mock_chain_builder - .add_existing_wallet(Auth::BasicAuth { auth_scheme: AuthScheme::Falcon512Rpo }) + .add_existing_wallet(Auth::BasicAuth { + auth_scheme: AuthScheme::Falcon512Poseidon2, + }) .unwrap(); let fungible_asset_1: Asset = @@ -123,7 +127,9 @@ impl ProofRequest { let tx = Box::pin(tx.execute()).await.unwrap(); let tx = tokio::task::block_in_place(|| { - LocalTransactionProver::default().prove(tx.tx_inputs().clone()).unwrap() + tokio::runtime::Handle::current() + .block_on(LocalTransactionProver::default().prove(tx.tx_inputs().clone())) + .unwrap() }); ProposedBatch::new( diff --git a/bin/stress-test/Cargo.toml b/bin/stress-test/Cargo.toml index 0be68877dc..452da58606 100644 --- a/bin/stress-test/Cargo.toml +++ b/bin/stress-test/Cargo.toml @@ -20,7 +20,6 @@ workspace = true clap = { features = ["derive"], version = "4.5" } fs-err = { workspace = true } futures = { workspace = true } -miden-air = { features = ["testing"], workspace = true } miden-node-block-producer = { workspace = true } miden-node-proto = { workspace = true } miden-node-store = { workspace = true } diff --git a/bin/stress-test/src/seeding/mod.rs b/bin/stress-test/src/seeding/mod.rs index 6621bf227d..bf4b559bca 100644 --- a/bin/stress-test/src/seeding/mod.rs +++ b/bin/stress-test/src/seeding/mod.rs @@ -4,7 +4,6 @@ use std::sync::{Arc, Mutex}; use std::time::Instant; use metrics::SeedingMetrics; -use miden_air::ExecutionProof; use miden_node_block_producer::store::StoreClient; use miden_node_proto::domain::batch::BatchInputs; use miden_node_proto::generated::store::rpc_client::RpcClient; @@ -33,20 +32,23 @@ use miden_protocol::block::{ SignedBlock, }; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey as EcdsaSecretKey; -use miden_protocol::crypto::dsa::falcon512_rpo::{PublicKey, SecretKey}; +use miden_protocol::crypto::dsa::falcon512_poseidon2::{PublicKey, SecretKey}; use miden_protocol::crypto::rand::RpoRandomCoin; use miden_protocol::errors::AssetError; use miden_protocol::note::{Note, NoteHeader, NoteId, NoteInclusionProof}; use miden_protocol::transaction::{ InputNote, + InputNoteCommitment, InputNotes, OrderedTransactionHeaders, OutputNote, ProvenTransaction, - ProvenTransactionBuilder, + PublicOutputNote, TransactionHeader, + TxAccountUpdate, }; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; +use miden_protocol::vm::ExecutionProof; use miden_protocol::{Felt, ONE, Word}; use miden_standards::account::auth::AuthSingleSig; use miden_standards::account::faucets::BasicFungibleFaucet; @@ -327,7 +329,7 @@ fn create_account(public_key: PublicKey, index: u64, storage_mode: AccountStorag AccountBuilder::new(init_seed.try_into().unwrap()) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(storage_mode) - .with_auth_component(AuthSingleSig::new(public_key.into(), AuthScheme::Falcon512Rpo)) + .with_auth_component(AuthSingleSig::new(public_key.into(), AuthScheme::Falcon512Poseidon2)) .with_component(BasicWallet) .build() .unwrap() @@ -347,7 +349,7 @@ fn create_faucet() -> Account { .with_component(BasicFungibleFaucet::new(token_symbol, 2, Felt::new(u64::MAX)).unwrap()) .with_auth_component(AuthSingleSig::new( key_pair.public_key().into(), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build() .unwrap() @@ -419,20 +421,24 @@ fn create_consume_note_tx( (AccountUpdateDetails::Private, Word::empty()) }; - ProvenTransactionBuilder::new( + let account_update = TxAccountUpdate::new( account.id(), init_hash, account.to_commitment(), account_delta_commitment, + details, + ) + .unwrap(); + ProvenTransaction::new( + account_update, + vec![InputNoteCommitment::from(input_note)], + Vec::::new(), block_ref.block_num(), block_ref.commitment(), fee_from_block(block_ref).unwrap(), u32::MAX.into(), ExecutionProof::new_dummy(), ) - .add_input_notes(vec![input_note]) - .account_update_details(details) - .build() .unwrap() } @@ -454,11 +460,21 @@ fn create_emit_note_tx( faucet.increment_nonce(ONE).unwrap(); - ProvenTransactionBuilder::new( + let account_update = TxAccountUpdate::new( faucet.id(), initial_account_hash, faucet.to_commitment(), Word::empty(), + AccountUpdateDetails::Private, + ) + .unwrap(); + ProvenTransaction::new( + account_update, + Vec::::new(), + output_notes + .into_iter() + .map(|note| OutputNote::Public(PublicOutputNote::new(note).unwrap())) + .collect::>(), block_ref.block_num(), block_ref.commitment(), FungibleAsset::new( @@ -469,8 +485,6 @@ fn create_emit_note_tx( u32::MAX.into(), ExecutionProof::new_dummy(), ) - .add_output_notes(output_notes.into_iter().map(OutputNote::Full).collect::>()) - .build() .unwrap() } diff --git a/bin/stress-test/src/store/mod.rs b/bin/stress-test/src/store/mod.rs index 314a5e95d0..ce5bf89452 100644 --- a/bin/stress-test/src/store/mod.rs +++ b/bin/stress-test/src/store/mod.rs @@ -8,7 +8,7 @@ use miden_node_store::state::State; use miden_node_utils::tracing::grpc::OtelInterceptor; use miden_protocol::account::AccountId; use miden_protocol::note::{NoteDetails, NoteTag}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use rand::Rng; use rand::seq::SliceRandom; use tokio::fs; diff --git a/crates/block-producer/src/domain/transaction.rs b/crates/block-producer/src/domain/transaction.rs index f581ca95e8..9b542f58ef 100644 --- a/crates/block-producer/src/domain/transaction.rs +++ b/crates/block-producer/src/domain/transaction.rs @@ -93,7 +93,7 @@ impl AuthenticatedTransaction { self.inner .output_notes() .iter() - .map(miden_protocol::transaction::OutputNote::commitment) + .map(miden_protocol::transaction::OutputNote::to_commitment) } pub fn output_notes(&self) -> impl Iterator + '_ { diff --git a/crates/block-producer/src/errors.rs b/crates/block-producer/src/errors.rs index b610b0534a..bb23cadc4f 100644 --- a/crates/block-producer/src/errors.rs +++ b/crates/block-producer/src/errors.rs @@ -119,7 +119,7 @@ pub enum AddTransactionError { }, #[error("transaction deserialization failed")] - TransactionDeserializationFailed(#[source] miden_protocol::utils::DeserializationError), + TransactionDeserializationFailed(#[source] miden_protocol::utils::serde::DeserializationError), #[error( "transaction expired at block height {expired_at} but the block height limit was {limit}" @@ -167,7 +167,7 @@ impl From for AddTransactionError { #[grpc(internal)] pub enum SubmitProvenBatchError { #[error("batch deserialization failed")] - Deserialization(#[source] miden_protocol::utils::DeserializationError), + Deserialization(#[source] miden_protocol::utils::serde::DeserializationError), } // Batch building errors diff --git a/crates/block-producer/src/mempool/subscription.rs b/crates/block-producer/src/mempool/subscription.rs index a09c1cc864..1da3bf03fe 100644 --- a/crates/block-producer/src/mempool/subscription.rs +++ b/crates/block-producer/src/mempool/subscription.rs @@ -68,8 +68,10 @@ impl SubscriptionProvider { let network_notes = tx .output_notes() .filter_map(|note| match note { - OutputNote::Full(inner) => inner.clone().into_account_target_network_note().ok(), - _ => None, + OutputNote::Public(inner) => { + inner.clone().into_note().into_account_target_network_note().ok() + }, + OutputNote::Private(_) => None, }) .collect(); let account_delta = diff --git a/crates/block-producer/src/store/mod.rs b/crates/block-producer/src/store/mod.rs index fb20bc160e..6b010df7e9 100644 --- a/crates/block-producer/src/store/mod.rs +++ b/crates/block-producer/src/store/mod.rs @@ -14,7 +14,7 @@ use miden_protocol::batch::OrderedBatches; use miden_protocol::block::{BlockHeader, BlockInputs, BlockNumber, SignedBlock}; use miden_protocol::note::Nullifier; use miden_protocol::transaction::ProvenTransaction; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use tracing::{debug, info, instrument}; use url::Url; diff --git a/crates/block-producer/src/test_utils/note.rs b/crates/block-producer/src/test_utils/note.rs index 6defeac83d..c2bd627a78 100644 --- a/crates/block-producer/src/test_utils/note.rs +++ b/crates/block-producer/src/test_utils/note.rs @@ -1,5 +1,5 @@ use miden_protocol::note::Note; -use miden_protocol::transaction::OutputNote; +use miden_protocol::transaction::{OutputNote, PublicOutputNote}; use miden_standards::testing::note::NoteBuilder; use rand_chacha::ChaCha20Rng; use rand_chacha::rand_core::SeedableRng; @@ -12,5 +12,5 @@ pub fn mock_note(num: u8) -> Note { } pub fn mock_output_note(num: u8) -> OutputNote { - OutputNote::Full(mock_note(num)) + OutputNote::Public(PublicOutputNote::new(mock_note(num)).unwrap()) } diff --git a/crates/block-producer/src/test_utils/proven_tx.rs b/crates/block-producer/src/test_utils/proven_tx.rs index b8d67e9fbe..6af29a0ac4 100644 --- a/crates/block-producer/src/test_utils/proven_tx.rs +++ b/crates/block-producer/src/test_utils/proven_tx.rs @@ -4,14 +4,17 @@ use std::sync::Arc; use itertools::Itertools; use miden_node_utils::fee::test_fee; use miden_protocol::account::AccountId; +use miden_protocol::account::delta::AccountUpdateDetails; use miden_protocol::asset::FungibleAsset; use miden_protocol::block::BlockNumber; use miden_protocol::note::{Note, Nullifier}; use miden_protocol::transaction::{ InputNote, + InputNoteCommitment, OutputNote, + PrivateNoteHeader, ProvenTransaction, - ProvenTransactionBuilder, + TxAccountUpdate, }; use miden_protocol::vm::ExecutionProof; use miden_protocol::{Felt, ONE, Word}; @@ -131,7 +134,7 @@ impl MockProvenTxBuilder { .map(|note_index| { let note = Note::mock_noop(Word::from([0, 0, 0, note_index])); - OutputNote::Header(note.header().clone()) + OutputNote::Private(PrivateNoteHeader::new(note.header().clone()).unwrap()) }) .collect(); @@ -139,21 +142,31 @@ impl MockProvenTxBuilder { } pub fn build(self) -> ProvenTransaction { - ProvenTransactionBuilder::new( + let account_update = TxAccountUpdate::new( self.account_id, self.initial_account_commitment, self.final_account_commitment, Word::empty(), + AccountUpdateDetails::Private, + ) + .unwrap(); + let input_notes: Vec = self + .input_notes + .unwrap_or_default() + .into_iter() + .map(InputNoteCommitment::from) + .chain(self.nullifiers.unwrap_or_default().into_iter().map(InputNoteCommitment::from)) + .collect(); + ProvenTransaction::new( + account_update, + input_notes, + self.output_notes.unwrap_or_default(), BlockNumber::GENESIS, Word::empty(), self.fee, self.expiration_block_num, ExecutionProof::new_dummy(), ) - .add_input_notes(self.input_notes.unwrap_or_default()) - .add_input_notes(self.nullifiers.unwrap_or_default()) - .add_output_notes(self.output_notes.unwrap_or_default()) - .build() .unwrap() } } diff --git a/crates/block-producer/src/validator/mod.rs b/crates/block-producer/src/validator/mod.rs index 9844e2d9b3..085ea61f12 100644 --- a/crates/block-producer/src/validator/mod.rs +++ b/crates/block-producer/src/validator/mod.rs @@ -2,7 +2,7 @@ use miden_node_proto::clients::{Builder, ValidatorClient}; use miden_node_proto::generated as proto; use miden_protocol::block::ProposedBlock; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::Signature; -use miden_protocol::utils::{Deserializable, DeserializationError, Serializable}; +use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; use thiserror::Error; use tracing::{info, instrument}; use url::Url; diff --git a/crates/db/src/conv.rs b/crates/db/src/conv.rs index 64c853c73d..8da9b50d38 100644 --- a/crates/db/src/conv.rs +++ b/crates/db/src/conv.rs @@ -151,7 +151,7 @@ pub(crate) fn raw_sql_to_nonce(raw: i64) -> Felt { } #[inline(always)] pub(crate) fn nonce_to_raw_sql(nonce: Felt) -> i64 { - nonce.as_int() as i64 + nonce.as_canonical_u64() as i64 } #[inline(always)] diff --git a/crates/large-smt-backend-rocksdb/Cargo.toml b/crates/large-smt-backend-rocksdb/Cargo.toml index d1226512d0..5109ecc9c3 100644 --- a/crates/large-smt-backend-rocksdb/Cargo.toml +++ b/crates/large-smt-backend-rocksdb/Cargo.toml @@ -19,7 +19,6 @@ miden-crypto = { features = ["concurrent", "std"], workspace = true } miden-protocol = { features = ["std"], workspace = true } rayon = { version = "1.10" } rocksdb = { default-features = false, features = ["bindgen-runtime", "lz4"], version = "0.24" } -winter-utils = { version = "0.13" } [build-dependencies] miden-node-rocksdb-cxx-linkage-fix = { workspace = true } diff --git a/crates/large-smt-backend-rocksdb/src/lib.rs b/crates/large-smt-backend-rocksdb/src/lib.rs index 563439c9f4..4cee18c8c9 100644 --- a/crates/large-smt-backend-rocksdb/src/lib.rs +++ b/crates/large-smt-backend-rocksdb/src/lib.rs @@ -26,8 +26,10 @@ extern crate alloc; mod helpers; #[expect(clippy::doc_markdown, clippy::inline_always)] mod rocksdb; -// Re-export from miden-protocol. -pub use miden_protocol::crypto::merkle::smt::{ +// Re-export from miden-crypto's merkle::smt module. +// NOTE: StorageError and SubtreeUpdate were missing from the re-exports in miden-crypto 0.22.4 +// (fixed on miden-crypto main in commit c6b23f0). We import directly from miden-crypto here. +pub use miden_crypto::merkle::smt::{ InnerNode, LargeSmt, LargeSmtError, diff --git a/crates/large-smt-backend-rocksdb/src/rocksdb.rs b/crates/large-smt-backend-rocksdb/src/rocksdb.rs index 92f187c4d9..4f0b93908d 100644 --- a/crates/large-smt-backend-rocksdb/src/rocksdb.rs +++ b/crates/large-smt-backend-rocksdb/src/rocksdb.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use miden_crypto::Map; use miden_crypto::merkle::NodeIndex; use miden_crypto::merkle::smt::{InnerNode, SmtLeaf, Subtree}; +use miden_crypto::utils::{Deserializable, Serializable}; use rocksdb::{ BlockBasedOptions, Cache, @@ -20,7 +21,6 @@ use rocksdb::{ ReadOptions, WriteBatch, }; -use winter_utils::{Deserializable, Serializable}; use super::{SmtStorage, StorageError, StorageUpdateParts, StorageUpdates, SubtreeUpdate}; use crate::helpers::{insert_into_leaf, map_rocksdb_err, remove_from_leaf}; @@ -261,17 +261,19 @@ impl RocksDbStorage { let name = cf_for_depth(index.depth()); self.cf_handle(name).expect("CF handle missing") } -} -impl SmtStorage for RocksDbStorage { /// Retrieves the SMT root hash from the `METADATA_CF` column family. /// + /// Note: In miden-crypto 0.22+, `get_root` is no longer part of the `SmtStorage` trait. + /// The root is managed in-memory by `LargeSmt`. This method is retained for backward + /// compatibility and direct database inspection. + /// /// # Errors /// - `StorageError::Backend`: If the metadata column family is missing or a RocksDB error /// occurs. /// - `StorageError::DeserializationError`: If the retrieved root hash bytes cannot be /// deserialized. - fn get_root(&self) -> Result, StorageError> { + pub fn get_root(&self) -> Result, StorageError> { let cf = self.cf_handle(METADATA_CF)?; match self.db.get_cf(cf, ROOT_KEY).map_err(map_rocksdb_err)? { Some(bytes) => { @@ -284,15 +286,21 @@ impl SmtStorage for RocksDbStorage { /// Stores the SMT root hash in the `METADATA_CF` column family. /// + /// Note: In miden-crypto 0.22+, `set_root` is no longer part of the `SmtStorage` trait. + /// The root is managed in-memory by `LargeSmt`. This method is retained for backward + /// compatibility and direct database operations. + /// /// # Errors /// - `StorageError::Backend`: If the metadata column family is missing or a RocksDB error /// occurs. - fn set_root(&self, root: Word) -> Result<(), StorageError> { + pub fn set_root(&self, root: Word) -> Result<(), StorageError> { let cf = self.cf_handle(METADATA_CF)?; self.db.put_cf(cf, ROOT_KEY, root.to_bytes()).map_err(map_rocksdb_err)?; Ok(()) } +} +impl SmtStorage for RocksDbStorage { /// Retrieves the total count of non-empty leaves from the `METADATA_CF` column family. /// Returns 0 if the count is not found. /// @@ -355,7 +363,7 @@ impl SmtStorage for RocksDbStorage { /// - `StorageError::DeserializationError`: If existing leaf data is corrupt. #[expect(clippy::single_match_else)] fn insert_value( - &self, + &mut self, index: u64, key: Word, value: Word, @@ -428,7 +436,7 @@ impl SmtStorage for RocksDbStorage { /// # Errors /// - `StorageError::Backend`: If column families are missing or a RocksDB error occurs. /// - `StorageError::DeserializationError`: If existing leaf data is corrupt. - fn remove_value(&self, index: u64, key: Word) -> Result, StorageError> { + fn remove_value(&mut self, index: u64, key: Word) -> Result, StorageError> { let Some(mut leaf) = self.get_leaf(index)? else { return Ok(None); }; @@ -488,7 +496,7 @@ impl SmtStorage for RocksDbStorage { /// /// # Errors /// - `StorageError::Backend`: If column families are missing or a RocksDB error occurs. - fn set_leaves(&self, leaves: Map) -> Result<(), StorageError> { + fn set_leaves(&mut self, leaves: Map) -> Result<(), StorageError> { let cf = self.cf_handle(LEAVES_CF)?; let leaf_count: usize = leaves.len(); let entry_count: usize = leaves.values().map(|leaf| leaf.entries().len()).sum(); @@ -519,7 +527,7 @@ impl SmtStorage for RocksDbStorage { /// - `StorageError::Backend`: If the leaves column family is missing or a RocksDB error occurs. /// - `StorageError::DeserializationError`: If the retrieved (to be returned) leaf data is /// corrupt. - fn remove_leaf(&self, index: u64) -> Result, StorageError> { + fn remove_leaf(&mut self, index: u64) -> Result, StorageError> { let key = Self::index_db_key(index); let cf = self.cf_handle(LEAVES_CF)?; let old_bytes = self.db.get_cf(cf, key).map_err(map_rocksdb_err)?; @@ -676,7 +684,7 @@ impl SmtStorage for RocksDbStorage { /// # Errors /// - Returns `StorageError` if column family lookup, serialization, or the write operation /// fails. - fn set_subtree(&self, subtree: &Subtree) -> Result<(), StorageError> { + fn set_subtree(&mut self, subtree: &Subtree) -> Result<(), StorageError> { let subtrees_cf = self.subtree_cf(subtree.root_index()); let mut batch = WriteBatch::default(); @@ -714,7 +722,7 @@ impl SmtStorage for RocksDbStorage { /// /// # Errors /// - Returns `StorageError::Backend` if any column family lookup or RocksDB write fails. - fn set_subtrees(&self, subtrees: Vec) -> Result<(), StorageError> { + fn set_subtrees(&mut self, subtrees: Vec) -> Result<(), StorageError> { let depth24_cf = self.cf_handle(DEPTH_24_CF)?; let mut batch = WriteBatch::default(); @@ -741,7 +749,7 @@ impl SmtStorage for RocksDbStorage { /// # Errors /// - `StorageError::Backend`: If the subtrees column family is missing or a RocksDB error /// occurs. - fn remove_subtree(&self, index: NodeIndex) -> Result<(), StorageError> { + fn remove_subtree(&mut self, index: NodeIndex) -> Result<(), StorageError> { let subtrees_cf = self.subtree_cf(index); let mut batch = WriteBatch::default(); @@ -790,7 +798,7 @@ impl SmtStorage for RocksDbStorage { /// - `StorageError::Backend`: If `index.depth() < IN_MEMORY_DEPTH`, or if RocksDB errors occur. /// - `StorageError::Value`: If existing Subtree data is corrupt. fn set_inner_node( - &self, + &mut self, index: NodeIndex, node: InnerNode, ) -> Result, StorageError> { @@ -818,7 +826,7 @@ impl SmtStorage for RocksDbStorage { /// # Errors /// - `StorageError::Backend`: If `index.depth() < IN_MEMORY_DEPTH`, or if RocksDB errors occur. /// - `StorageError::Value`: If existing Subtree data is corrupt. - fn remove_inner_node(&self, index: NodeIndex) -> Result, StorageError> { + fn remove_inner_node(&mut self, index: NodeIndex) -> Result, StorageError> { if index.depth() < IN_MEMORY_DEPTH { return Err(StorageError::Unsupported( "Cannot remove inner node from upper part of the tree".into(), @@ -856,7 +864,7 @@ impl SmtStorage for RocksDbStorage { /// /// # Errors /// - `StorageError::Backend`: If any column family is missing or a RocksDB write error occurs. - fn apply(&self, updates: StorageUpdates) -> Result<(), StorageError> { + fn apply(&mut self, updates: StorageUpdates) -> Result<(), StorageError> { use rayon::prelude::*; let mut batch = WriteBatch::default(); @@ -868,7 +876,6 @@ impl SmtStorage for RocksDbStorage { let StorageUpdateParts { leaf_updates, subtree_updates, - new_root, leaf_count_delta, entry_count_delta, } = updates.into_parts(); @@ -943,8 +950,6 @@ impl SmtStorage for RocksDbStorage { batch.put_cf(metadata_cf, ENTRY_COUNT_KEY, new_entry_count.to_be_bytes()); } - batch.put_cf(metadata_cf, ROOT_KEY, new_root.to_bytes()); - let mut write_opts = rocksdb::WriteOptions::default(); // Disable immediate WAL sync to disk for better performance write_opts.set_sync(false); diff --git a/crates/ntx-builder/src/actor/execute.rs b/crates/ntx-builder/src/actor/execute.rs index d06c283c14..d21a62384c 100644 --- a/crates/ntx-builder/src/actor/execute.rs +++ b/crates/ntx-builder/src/actor/execute.rs @@ -35,7 +35,7 @@ use miden_protocol::transaction::{ use miden_protocol::vm::FutureMaybeSend; use miden_remote_prover_client::RemoteTransactionProver; use miden_tx::auth::UnreachableAuth; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use miden_tx::{ DataStore, DataStoreError, @@ -74,6 +74,7 @@ pub enum NtxError { #[error("failed to submit transaction")] Submission(#[source] tonic::Status), #[error("the ntx task panicked")] + #[expect(dead_code)] Panic(#[source] JoinError), } @@ -302,11 +303,9 @@ impl NtxContext { if let Some(remote) = &self.prover { remote.prove(tx_inputs).await } else { - // Only perform tx inptus clone for local proving. + // Only perform tx inputs clone for local proving. let tx_inputs = tx_inputs.clone(); - tokio::task::spawn_blocking(move || LocalTransactionProver::default().prove(tx_inputs)) - .await - .map_err(NtxError::Panic)? + LocalTransactionProver::default().prove(tx_inputs).await } .map_err(NtxError::Proving) } diff --git a/crates/ntx-builder/src/clients/block_producer.rs b/crates/ntx-builder/src/clients/block_producer.rs index 94227ba22d..8b5d3ffad4 100644 --- a/crates/ntx-builder/src/clients/block_producer.rs +++ b/crates/ntx-builder/src/clients/block_producer.rs @@ -6,7 +6,7 @@ use miden_node_proto::domain::mempool::MempoolEvent; use miden_node_proto::generated::{self as proto}; use miden_node_utils::FlattenResult; use miden_protocol::transaction::ProvenTransaction; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use tokio_stream::StreamExt; use tonic::Status; use tracing::{info, instrument}; diff --git a/crates/ntx-builder/src/clients/store.rs b/crates/ntx-builder/src/clients/store.rs index 1f8c7b5f72..06c26f48b5 100644 --- a/crates/ntx-builder/src/clients/store.rs +++ b/crates/ntx-builder/src/clients/store.rs @@ -27,7 +27,7 @@ use miden_protocol::crypto::merkle::smt::SmtProof; use miden_protocol::note::NoteScript; use miden_protocol::transaction::AccountInputs; use miden_standards::note::AccountTargetNetworkNote; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use thiserror::Error; use tracing::{info, instrument}; use url::Url; diff --git a/crates/ntx-builder/src/db/models/conv.rs b/crates/ntx-builder/src/db/models/conv.rs index b32a292538..c50e4f6ac2 100644 --- a/crates/ntx-builder/src/db/models/conv.rs +++ b/crates/ntx-builder/src/db/models/conv.rs @@ -7,7 +7,7 @@ use miden_protocol::account::{Account, AccountId}; use miden_protocol::block::{BlockHeader, BlockNumber}; use miden_protocol::note::{NoteScript, Nullifier}; use miden_protocol::transaction::TransactionId; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; // SERIALIZATION (domain → DB) // ================================================================================================ diff --git a/crates/ntx-builder/src/db/models/queries/mod.rs b/crates/ntx-builder/src/db/models/queries/mod.rs index 7b6329396d..bd1d25dc5b 100644 --- a/crates/ntx-builder/src/db/models/queries/mod.rs +++ b/crates/ntx-builder/src/db/models/queries/mod.rs @@ -10,7 +10,7 @@ use miden_protocol::block::{BlockHeader, BlockNumber}; use miden_protocol::note::Nullifier; use miden_protocol::transaction::TransactionId; use miden_standards::note::AccountTargetNetworkNote; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use super::account_effect::NetworkAccountEffect; use crate::db::models::conv as conversions; diff --git a/crates/ntx-builder/src/db/models/queries/notes.rs b/crates/ntx-builder/src/db/models/queries/notes.rs index b986953a1f..9d8e328e56 100644 --- a/crates/ntx-builder/src/db/models/queries/notes.rs +++ b/crates/ntx-builder/src/db/models/queries/notes.rs @@ -6,7 +6,7 @@ use miden_node_proto::domain::account::NetworkAccountId; use miden_protocol::block::BlockNumber; use miden_protocol::note::{Note, Nullifier}; use miden_standards::note::AccountTargetNetworkNote; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use crate::db::models::conv as conversions; use crate::db::schema; diff --git a/crates/ntx-builder/src/db/models/queries/tests.rs b/crates/ntx-builder/src/db/models/queries/tests.rs index b41336c209..b35b413daf 100644 --- a/crates/ntx-builder/src/db/models/queries/tests.rs +++ b/crates/ntx-builder/src/db/models/queries/tests.rs @@ -11,6 +11,7 @@ use miden_protocol::account::{ }; use miden_protocol::block::BlockNumber; use miden_protocol::testing::account_id::{ + ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, ACCOUNT_ID_REGULAR_NETWORK_ACCOUNT_IMMUTABLE_CODE, AccountIdBuilder, }; @@ -51,7 +52,9 @@ fn mock_network_account_id_seeded(seed: u8) -> NetworkAccountId { /// Creates a unique `TransactionId` from a seed value. fn mock_tx_id(seed: u64) -> TransactionId { let w = |n: u64| Word::try_from([n, 0, 0, 0]).unwrap(); - TransactionId::new(w(seed), w(seed + 1), w(seed + 2), w(seed + 3)) + let faucet_id = AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET).unwrap(); + let fee = miden_protocol::asset::FungibleAsset::new(faucet_id, 0).unwrap(); + TransactionId::new(w(seed), w(seed + 1), w(seed + 2), w(seed + 3), fee) } /// Creates a `SingleTargetNetworkNote` targeting the given network account. @@ -551,12 +554,9 @@ fn mock_account(_account_id: NetworkAccountId) -> miden_protocol::account::Accou .compile_component_code("test::interface", "pub proc test_proc push.1.2 add end") .unwrap(); - let component = AccountComponent::new( - component_code, - vec![], - AccountComponentMetadata::mock("test").with_supports_all_types(), - ) - .unwrap(); + let component = + AccountComponent::new(component_code, vec![], AccountComponentMetadata::mock("test")) + .unwrap(); AccountBuilder::new([0u8; 32]) .account_type(AccountType::RegularAccountImmutableCode) @@ -564,7 +564,7 @@ fn mock_account(_account_id: NetworkAccountId) -> miden_protocol::account::Accou .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(Word::default()), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap() diff --git a/crates/proto/src/domain/account.rs b/crates/proto/src/domain/account.rs index aeec888328..3772241c95 100644 --- a/crates/proto/src/domain/account.rs +++ b/crates/proto/src/domain/account.rs @@ -20,7 +20,7 @@ use miden_protocol::block::account_tree::AccountWitness; use miden_protocol::crypto::merkle::SparseMerklePath; use miden_protocol::crypto::merkle::smt::SmtProof; use miden_protocol::note::NoteAttachment; -use miden_protocol::utils::{Deserializable, DeserializationError, Serializable}; +use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; use miden_standards::note::{NetworkAccountTarget, NetworkAccountTargetError}; use thiserror::Error; @@ -298,7 +298,7 @@ impl From for proto::account::AccountHeader { vault_root: Some(header.vault_root().into()), storage_commitment: Some(header.storage_commitment().into()), code_commitment: Some(header.code_commitment().into()), - nonce: header.nonce().as_int(), + nonce: header.nonce().as_canonical_u64(), } } } @@ -373,14 +373,9 @@ impl TryFrom for AccountVaultDetails { if too_many_assets { Ok(Self::LimitExceeded) } else { - let parsed_assets = - Result::, ConversionError>::from_iter(assets.into_iter().map(|asset| { - let asset = asset - .asset - .ok_or(proto::primitives::Asset::missing_field(stringify!(asset)))?; - let asset = Word::try_from(asset)?; - Asset::try_from(asset).map_err(ConversionError::AssetError) - }))?; + let parsed_assets = Result::, ConversionError>::from_iter( + assets.into_iter().map(Asset::try_from), + )?; Ok(Self::Assets(parsed_assets)) } } @@ -395,9 +390,7 @@ impl From for proto::rpc::AccountVaultDetails { }, AccountVaultDetails::Assets(assets) => Self { too_many_assets: false, - assets: Vec::from_iter(assets.into_iter().map(|asset| proto::primitives::Asset { - asset: Some(proto::primitives::Digest::from(Word::from(asset))), - })), + assets: Vec::from_iter(assets.into_iter().map(proto::primitives::Asset::from)), }, } } @@ -1008,17 +1001,20 @@ impl TryFrom for Asset { type Error = ConversionError; fn try_from(value: proto::primitives::Asset) -> Result { - let inner = value.asset.ok_or(proto::primitives::Asset::missing_field("asset"))?; - let word = Word::try_from(inner)?; + let key = value.key.ok_or(proto::primitives::Asset::missing_field("key"))?; + let key_word = Word::try_from(key)?; + let value = value.value.ok_or(proto::primitives::Asset::missing_field("value"))?; + let value_word = Word::try_from(value)?; - Asset::try_from(word).map_err(ConversionError::AssetError) + Asset::from_key_value_words(key_word, value_word).map_err(ConversionError::AssetError) } } impl From for proto::primitives::Asset { fn from(asset_from: Asset) -> Self { proto::primitives::Asset { - asset: Some(Word::from(asset_from).into()), + key: Some(asset_from.to_key_word().into()), + value: Some(asset_from.to_value_word().into()), } } } diff --git a/crates/proto/src/domain/batch.rs b/crates/proto/src/domain/batch.rs index 1cccf6ab8b..0c17a7eadf 100644 --- a/crates/proto/src/domain/batch.rs +++ b/crates/proto/src/domain/batch.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use miden_protocol::block::BlockHeader; use miden_protocol::note::{NoteId, NoteInclusionProof}; use miden_protocol::transaction::PartialBlockchain; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use crate::errors::{ConversionError, MissingFieldHelper}; use crate::generated as proto; diff --git a/crates/proto/src/domain/block.rs b/crates/proto/src/domain/block.rs index 112f84e50b..6383c255db 100644 --- a/crates/proto/src/domain/block.rs +++ b/crates/proto/src/domain/block.rs @@ -14,7 +14,7 @@ use miden_protocol::block::{ use miden_protocol::crypto::dsa::ecdsa_k256_keccak::{PublicKey, Signature}; use miden_protocol::note::{NoteId, NoteInclusionProof}; use miden_protocol::transaction::PartialBlockchain; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use thiserror::Error; use crate::errors::{ConversionError, MissingFieldHelper}; diff --git a/crates/proto/src/domain/digest.rs b/crates/proto/src/domain/digest.rs index 08d8c3f9a1..d411c100fd 100644 --- a/crates/proto/src/domain/digest.rs +++ b/crates/proto/src/domain/digest.rs @@ -3,7 +3,7 @@ use std::fmt::{Debug, Display, Formatter}; use hex::{FromHex, ToHex}; use miden_protocol::account::StorageMapKey; use miden_protocol::note::NoteId; -use miden_protocol::{Felt, StarkField, Word}; +use miden_protocol::{Felt, Word}; use crate::errors::ConversionError; use crate::generated as proto; @@ -106,10 +106,10 @@ impl From<&[u64; 4]> for proto::primitives::Digest { impl From<[Felt; 4]> for proto::primitives::Digest { fn from(value: [Felt; 4]) -> Self { Self { - d0: value[0].as_int(), - d1: value[1].as_int(), - d2: value[2].as_int(), - d3: value[3].as_int(), + d0: value[0].as_canonical_u64(), + d1: value[1].as_canonical_u64(), + d2: value[2].as_canonical_u64(), + d3: value[3].as_canonical_u64(), } } } @@ -123,10 +123,10 @@ impl From<&[Felt; 4]> for proto::primitives::Digest { impl From for proto::primitives::Digest { fn from(value: Word) -> Self { Self { - d0: value[0].as_int(), - d1: value[1].as_int(), - d2: value[2].as_int(), - d3: value[3].as_int(), + d0: value[0].as_canonical_u64(), + d1: value[1].as_canonical_u64(), + d2: value[2].as_canonical_u64(), + d3: value[3].as_canonical_u64(), } } } @@ -174,10 +174,7 @@ impl TryFrom for [Felt; 4] { type Error = ConversionError; fn try_from(value: proto::primitives::Digest) -> Result { - if [value.d0, value.d1, value.d2, value.d3] - .iter() - .any(|v| *v >= ::MODULUS) - { + if [value.d0, value.d1, value.d2, value.d3].iter().any(|v| *v >= Felt::ORDER) { return Err(ConversionError::NotAValidFelt); } diff --git a/crates/proto/src/domain/mempool.rs b/crates/proto/src/domain/mempool.rs index c9bf76bfc9..e6b01bd61c 100644 --- a/crates/proto/src/domain/mempool.rs +++ b/crates/proto/src/domain/mempool.rs @@ -4,7 +4,7 @@ use miden_protocol::account::delta::AccountUpdateDetails; use miden_protocol::block::BlockHeader; use miden_protocol::note::Nullifier; use miden_protocol::transaction::TransactionId; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_standards::note::AccountTargetNetworkNote; use crate::errors::{ConversionError, MissingFieldHelper}; diff --git a/crates/proto/src/domain/note.rs b/crates/proto/src/domain/note.rs index 6a750a6582..90ba7b95d9 100644 --- a/crates/proto/src/domain/note.rs +++ b/crates/proto/src/domain/note.rs @@ -13,7 +13,7 @@ use miden_protocol::note::{ NoteTag, NoteType, }; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_protocol::{MastForest, MastNodeId, Word}; use miden_standards::note::AccountTargetNetworkNote; diff --git a/crates/proto/src/domain/proof_request.rs b/crates/proto/src/domain/proof_request.rs index f6a40d7537..2b92bb935e 100644 --- a/crates/proto/src/domain/proof_request.rs +++ b/crates/proto/src/domain/proof_request.rs @@ -3,7 +3,7 @@ use miden_protocol::batch::OrderedBatches; use miden_protocol::block::{BlockHeader, BlockInputs}; -use miden_protocol::utils::{ +use miden_protocol::utils::serde::{ ByteReader, ByteWriter, Deserializable, diff --git a/crates/proto/src/domain/transaction.rs b/crates/proto/src/domain/transaction.rs index 62052eb633..ee7d24bf20 100644 --- a/crates/proto/src/domain/transaction.rs +++ b/crates/proto/src/domain/transaction.rs @@ -1,7 +1,7 @@ use miden_protocol::Word; use miden_protocol::note::Nullifier; use miden_protocol::transaction::{InputNoteCommitment, TransactionId}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use crate::errors::{ConversionError, MissingFieldHelper}; use crate::generated as proto; diff --git a/crates/proto/src/errors/mod.rs b/crates/proto/src/errors/mod.rs index 04493e6960..75d5bf8701 100644 --- a/crates/proto/src/errors/mod.rs +++ b/crates/proto/src/errors/mod.rs @@ -5,7 +5,7 @@ use std::num::TryFromIntError; pub use miden_node_grpc_error_macro::GrpcError; use miden_protocol::crypto::merkle::smt::{SmtLeafError, SmtProofError}; use miden_protocol::errors::{AccountError, AssetError, FeeError, NoteError, StorageSlotNameError}; -use miden_protocol::utils::DeserializationError; +use miden_protocol::utils::serde::DeserializationError; use miden_standards::note::NetworkAccountTargetError; use thiserror::Error; diff --git a/crates/remote-prover-client/src/remote_prover/batch_prover.rs b/crates/remote-prover-client/src/remote_prover/batch_prover.rs index b0d472656a..dd9d4cab5b 100644 --- a/crates/remote-prover-client/src/remote_prover/batch_prover.rs +++ b/crates/remote-prover-client/src/remote_prover/batch_prover.rs @@ -10,7 +10,7 @@ use miden_protocol::transaction::{ TransactionHeader, TransactionId, }; -use miden_protocol::utils::{Deserializable, DeserializationError, Serializable}; +use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; use tokio::sync::Mutex; use super::generated::api_client::ApiClient; @@ -110,7 +110,7 @@ impl RemoteBatchProver { &self, proposed_batch: ProposedBatch, ) -> Result { - use miden_protocol::utils::Serializable; + use miden_protocol::utils::serde::Serializable; self.connect().await?; let mut client = self diff --git a/crates/remote-prover-client/src/remote_prover/block_prover.rs b/crates/remote-prover-client/src/remote_prover/block_prover.rs index c1562e5975..fff6bcc092 100644 --- a/crates/remote-prover-client/src/remote_prover/block_prover.rs +++ b/crates/remote-prover-client/src/remote_prover/block_prover.rs @@ -6,7 +6,7 @@ use core::time::Duration; use miden_protocol::batch::{OrderedBatches, ProvenBatch}; use miden_protocol::block::{BlockHeader, BlockInputs, BlockProof, ProposedBlock, ProvenBlock}; use miden_protocol::transaction::{OrderedTransactionHeaders, TransactionHeader}; -use miden_protocol::utils::{Deserializable, DeserializationError, Serializable}; +use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; use tokio::sync::Mutex; use super::generated::api_client::ApiClient; @@ -108,7 +108,7 @@ impl RemoteBlockProver { block_header: &BlockHeader, block_inputs: BlockInputs, ) -> Result { - use miden_protocol::utils::Serializable; + use miden_protocol::utils::serde::Serializable; self.connect().await?; let mut client = self diff --git a/crates/remote-prover-client/src/remote_prover/tx_prover.rs b/crates/remote-prover-client/src/remote_prover/tx_prover.rs index 3bee6199fa..360798b09f 100644 --- a/crates/remote-prover-client/src/remote_prover/tx_prover.rs +++ b/crates/remote-prover-client/src/remote_prover/tx_prover.rs @@ -4,7 +4,7 @@ use alloc::sync::Arc; use core::time::Duration; use miden_protocol::transaction::{ProvenTransaction, TransactionInputs}; -use miden_protocol::utils::{Deserializable, DeserializationError, Serializable}; +use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; use miden_protocol::vm::FutureMaybeSend; use miden_tx::TransactionProverError; use tokio::sync::Mutex; @@ -107,7 +107,7 @@ impl RemoteTransactionProver { tx_inputs: &TransactionInputs, ) -> impl FutureMaybeSend> { async move { - use miden_protocol::utils::Serializable; + use miden_protocol::utils::serde::Serializable; self.connect().await.map_err(|err| { TransactionProverError::other_with_source( "failed to connect to the remote prover", diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index 537173e67d..60e48c3ded 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -37,7 +37,6 @@ tracing = { workspace = true } url = { workspace = true } [dev-dependencies] -miden-air = { features = ["testing"], workspace = true } miden-node-store = { features = ["rocksdb"], workspace = true } miden-node-utils = { features = ["testing", "tracing-forest"], workspace = true } miden-protocol = { default-features = true, features = ["testing"], workspace = true } diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index a0ec88859a..8b58a67c5d 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, LazyLock}; +use std::sync::LazyLock; use std::time::Duration; use anyhow::Context; @@ -19,8 +19,7 @@ use miden_node_utils::limiter::{ }; use miden_protocol::batch::ProvenBatch; use miden_protocol::block::{BlockHeader, BlockNumber}; -use miden_protocol::note::{Note, NoteRecipient, NoteScript}; -use miden_protocol::transaction::{OutputNote, ProvenTransaction, ProvenTransactionBuilder}; +use miden_protocol::transaction::{OutputNote, ProvenTransaction, TxAccountUpdate}; use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_protocol::{MIN_PROOF_SECURITY_LEVEL, Word}; use miden_tx::TransactionVerifier; @@ -337,23 +336,27 @@ impl api_server::Api for RpcService { })?; // Rebuild a new ProvenTransaction with decorators removed from output notes - let mut builder = ProvenTransactionBuilder::new( + let account_update = TxAccountUpdate::new( tx.account_id(), tx.account_update().initial_state_commitment(), tx.account_update().final_state_commitment(), tx.account_update().account_delta_commitment(), + tx.account_update().details().clone(), + ) + .map_err(|e| Status::invalid_argument(e.to_string()))?; + + let stripped_outputs = strip_output_note_decorators(tx.output_notes().iter()); + let rebuilt_tx = ProvenTransaction::new( + account_update, + tx.input_notes().iter().cloned(), + stripped_outputs, tx.ref_block_num(), tx.ref_block_commitment(), tx.fee(), tx.expiration_block_num(), tx.proof().clone(), ) - .account_update_details(tx.account_update().details().clone()) - .add_input_notes(tx.input_notes().iter().cloned()); - - let stripped_outputs = strip_output_note_decorators(tx.output_notes().iter()); - builder = builder.add_output_notes(stripped_outputs); - let rebuilt_tx = builder.build().map_err(|e| Status::invalid_argument(e.to_string()))?; + .map_err(|e| Status::invalid_argument(e.to_string()))?; let mut request = request; request.transaction = rebuilt_tx.to_bytes(); @@ -492,23 +495,26 @@ impl api_server::Api for RpcService { // HELPERS // ================================================================================================ -/// Strips decorators from full output notes' scripts. +/// Strips decorators from public output notes' scripts. /// /// This removes MAST decorators from note scripts before forwarding to the block producer, /// as decorators are not needed for transaction processing. +/// +/// Note: `PublicOutputNote::new()` already calls `note.minify_script()` internally, so +/// reconstructing the public note through it handles decorator stripping automatically. fn strip_output_note_decorators<'a>( notes: impl Iterator + 'a, ) -> impl Iterator + 'a { + use miden_protocol::transaction::PublicOutputNote; + notes.map(|note| match note { - OutputNote::Full(note) => { - let mut mast = note.script().mast().clone(); - Arc::make_mut(&mut mast).strip_decorators(); - let script = NoteScript::from_parts(mast, note.script().entrypoint()); - let recipient = NoteRecipient::new(note.serial_num(), script, note.storage().clone()); - let new_note = Note::new(note.assets().clone(), note.metadata().clone(), recipient); - OutputNote::Full(new_note) + OutputNote::Public(public_note) => { + // Reconstruct via PublicOutputNote::new which calls minify_script() internally. + let rebuilt = PublicOutputNote::new(public_note.as_note().clone()) + .expect("rebuilding an already-valid public output note should not fail"); + OutputNote::Public(rebuilt) }, - other => other.clone(), + OutputNote::Private(header) => OutputNote::Private(header.clone()), }) } diff --git a/crates/rpc/src/tests.rs b/crates/rpc/src/tests.rs index 4e2b4a5074..75c8e5e21d 100644 --- a/crates/rpc/src/tests.rs +++ b/crates/rpc/src/tests.rs @@ -30,8 +30,8 @@ use miden_protocol::account::{ }; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; use miden_protocol::testing::noop_auth_component::NoopAuthComponent; -use miden_protocol::transaction::{ProvenTransaction, ProvenTransactionBuilder}; -use miden_protocol::utils::Serializable; +use miden_protocol::transaction::{ProvenTransaction, TxAccountUpdate}; +use miden_protocol::utils::serde::Serializable; use miden_protocol::vm::ExecutionProof; use miden_standards::account::wallets::BasicWallet; use tempfile::TempDir; @@ -74,19 +74,25 @@ fn build_test_proven_tx(account: &Account, delta: &AccountDelta) -> ProvenTransa AccountStorageMode::Public, ); - ProvenTransactionBuilder::new( + let account_update = TxAccountUpdate::new( account_id, [8; 32].try_into().unwrap(), account.to_commitment(), delta.to_commitment(), + AccountUpdateDetails::Delta(delta.clone()), + ) + .unwrap(); + + ProvenTransaction::new( + account_update, + std::iter::empty::(), + std::iter::empty::(), 0.into(), Word::default(), test_fee(), u32::MAX.into(), ExecutionProof::new_dummy(), ) - .account_update_details(AccountUpdateDetails::Delta(delta.clone())) - .build() .unwrap() } diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index f22555e10a..31b001ce8d 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -53,7 +53,7 @@ url = { workspace = true } [build-dependencies] build-rs = { workspace = true } fs-err = { workspace = true } -miden-agglayer = { features = ["testing"], version = "=0.14.0-alpha.1" } +miden-agglayer = { features = ["testing"], version = "=0.14.0-beta.1" } miden-protocol = { features = ["std"], workspace = true } miden-standards = { workspace = true } diff --git a/crates/store/benches/account_tree.rs b/crates/store/benches/account_tree.rs index e69da7714d..005a3780ec 100644 --- a/crates/store/benches/account_tree.rs +++ b/crates/store/benches/account_tree.rs @@ -8,7 +8,7 @@ use miden_node_store::AccountTreeWithHistory; use miden_protocol::Word; use miden_protocol::account::AccountId; use miden_protocol::block::BlockNumber; -use miden_protocol::block::account_tree::{AccountTree, account_id_to_smt_key}; +use miden_protocol::block::account_tree::{AccountIdKey, AccountTree}; use miden_protocol::crypto::hash::rpo::Rpo256; use miden_protocol::crypto::merkle::smt::LargeSmt; use miden_protocol::testing::account_id::AccountIdBuilder; @@ -79,7 +79,7 @@ fn setup_vanilla_account_tree( let account_id = generate_account_id(&mut seed); let commitment = generate_word(&mut seed); account_ids.push(account_id); - entries.push((account_id_to_smt_key(account_id), commitment)); + entries.push((AccountIdKey::from(account_id).as_word(), commitment)); } let storage = setup_storage(base_path); diff --git a/crates/store/build.rs b/crates/store/build.rs index 5cc15e4db0..bb3f41169d 100644 --- a/crates/store/build.rs +++ b/crates/store/build.rs @@ -11,7 +11,7 @@ use miden_agglayer::{ }; use miden_protocol::account::auth::AuthScheme; use miden_protocol::account::{Account, AccountCode, AccountFile, AccountStorageMode, AccountType}; -use miden_protocol::crypto::dsa::falcon512_rpo::SecretKey; +use miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey; use miden_protocol::crypto::rand::RpoRandomCoin; use miden_protocol::{Felt, Word}; use miden_standards::AuthMethod; @@ -59,7 +59,7 @@ fn generate_agglayer_sample_accounts() { let bridge_admin = create_basic_wallet( [4u8; 32], AuthMethod::SingleSig { - approver: (bridge_admin_key.public_key().into(), AuthScheme::Falcon512Rpo), + approver: (bridge_admin_key.public_key().into(), AuthScheme::Falcon512Poseidon2), }, AccountType::RegularAccountImmutableCode, AccountStorageMode::Public, @@ -69,7 +69,7 @@ fn generate_agglayer_sample_accounts() { let ger_manager = create_basic_wallet( [5u8; 32], AuthMethod::SingleSig { - approver: (ger_manager_key.public_key().into(), AuthScheme::Falcon512Rpo), + approver: (ger_manager_key.public_key().into(), AuthScheme::Falcon512Poseidon2), }, AccountType::RegularAccountImmutableCode, AccountStorageMode::Public, @@ -139,17 +139,17 @@ fn generate_agglayer_sample_accounts() { .expect("Failed to write agglayer_faucet_usdc.mac"); } -/// Strips source location decorators from an account's code MAST forest. +/// Clears debug info from an account's code MAST forest. /// /// This is necessary because the MAST forest embeds absolute file paths from the Cargo build -/// directory, which include a hash that differs between `cargo check` and `cargo build`. Stripping -/// decorators ensures the serialized `.mac` files are identical regardless of which cargo command +/// directory, which include a hash that differs between `cargo check` and `cargo build`. Clearing +/// debug info ensures the serialized `.mac` files are identical regardless of which cargo command /// is used (CI or local builds or tests). fn strip_code_decorators(account: Account) -> Account { let (id, vault, storage, code, nonce, seed) = account.into_parts(); let mut mast = code.mast(); - Arc::make_mut(&mut mast).strip_decorators(); + Arc::make_mut(&mut mast).clear_debug_info(); let code = AccountCode::from_parts(mast, code.procedures().to_vec()); Account::new_unchecked(id, vault, storage, code, nonce, seed) diff --git a/crates/store/src/account_state_forest/mod.rs b/crates/store/src/account_state_forest/mod.rs index 3d11b508c3..b00f31bb04 100644 --- a/crates/store/src/account_state_forest/mod.rs +++ b/crates/store/src/account_state_forest/mod.rs @@ -1,9 +1,8 @@ -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use miden_crypto::hash::rpo::Rpo256; -use miden_crypto::merkle::smt::ForestInMemoryBackend; +use miden_crypto::merkle::smt::{SMT_DEPTH, SmtForest}; use miden_node_proto::domain::account::AccountStorageMapDetails; -use miden_node_utils::ErrorReport; use miden_protocol::account::delta::{AccountDelta, AccountStorageDelta, AccountVaultDelta}; use miden_protocol::account::{ AccountId, @@ -12,21 +11,11 @@ use miden_protocol::account::{ StorageMapWitness, StorageSlotName, }; -use miden_protocol::asset::{Asset, AssetVaultKey, AssetWitness, FungibleAsset}; +use miden_protocol::asset::{AssetVaultKey, AssetWitness, FungibleAsset}; use miden_protocol::block::BlockNumber; -use miden_protocol::crypto::merkle::smt::{ - ForestOperation, - LargeSmtForest, - LargeSmtForestError, - LineageId, - RootInfo, - SMT_DEPTH, - SmtUpdateBatch, - TreeId, -}; use miden_protocol::crypto::merkle::{EmptySubtreeRoots, MerkleError}; use miden_protocol::errors::{AssetError, StorageMapError}; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use miden_protocol::{EMPTY_WORD, Word}; use thiserror::Error; use tracing::instrument; @@ -45,7 +34,7 @@ pub enum AccountStateForestError { #[error(transparent)] Asset(#[from] AssetError), #[error(transparent)] - Forest(#[from] LargeSmtForestError), + Merkle(#[from] MerkleError), } #[derive(Debug, Error)] @@ -63,21 +52,37 @@ pub enum WitnessError { // ACCOUNT STATE FOREST // ================================================================================================ +/// A lineage identifier for trees in the forest. +/// +/// This is a local replacement for the removed `LineageId` type. It uniquely identifies +/// a lineage of SMT trees (e.g., per-account vault or per-account-slot storage map). +#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +struct LineageId([u8; 32]); + +impl LineageId { + fn new(bytes: [u8; 32]) -> Self { + Self(bytes) + } +} + /// Container for forest-related state that needs to be updated atomically. pub(crate) struct AccountStateForest { - /// `LargeSmtForest` for efficient account storage reconstruction. + /// `SmtForest` for efficient account storage reconstruction. /// Populated during block import with storage and vault SMTs. - forest: LargeSmtForest, + forest: SmtForest, + + /// Maps lineage IDs to a version-ordered list of (version, root) pairs. + /// This replaces the lineage/version tracking that was previously internal to + /// `LargeSmtForest`. + lineage_versions: BTreeMap>, } impl AccountStateForest { pub(crate) fn new() -> Self { - Self { forest: Self::create_forest() } - } - - fn create_forest() -> LargeSmtForest { - let backend = ForestInMemoryBackend::new(); - LargeSmtForest::new(backend).expect("in-memory backend should initialize") + Self { + forest: SmtForest::new(), + lineage_versions: BTreeMap::new(), + } } // HELPERS @@ -93,21 +98,20 @@ impl AccountStateForest { &self, account_id: AccountId, slot_name: &StorageSlotName, - block_num: BlockNumber, - ) -> TreeId { + _block_num: BlockNumber, + ) -> Option { let lineage = Self::storage_lineage_id(account_id, slot_name); - self.lookup_tree_id(lineage, block_num) + self.latest_root(lineage) } #[cfg(test)] - fn tree_id_for_vault_root(&self, account_id: AccountId, block_num: BlockNumber) -> TreeId { + fn tree_id_for_vault_root( + &self, + account_id: AccountId, + _block_num: BlockNumber, + ) -> Option { let lineage = Self::vault_lineage_id(account_id); - self.lookup_tree_id(lineage, block_num) - } - - #[expect(clippy::unused_self)] - fn lookup_tree_id(&self, lineage: LineageId, block_num: BlockNumber) -> TreeId { - TreeId::new(lineage, block_num.as_u64()) + self.latest_root(lineage) } fn storage_lineage_id(account_id: AccountId, slot_name: &StorageSlotName) -> LineageId { @@ -121,86 +125,68 @@ impl AccountStateForest { LineageId::new(Rpo256::hash(&account_id.to_bytes()).as_bytes()) } - fn build_forest_operations( - entries: impl IntoIterator, - ) -> Vec { - entries - .into_iter() - .map(|(key, value)| { - if value == EMPTY_WORD { - ForestOperation::remove(key) - } else { - ForestOperation::insert(key, value) - } - }) - .collect() + /// Returns the latest root for a lineage, or `None` if the lineage is not tracked. + fn latest_root(&self, lineage: LineageId) -> Option { + self.lineage_versions + .get(&lineage) + .and_then(|versions| versions.last().map(|(_, root)| *root)) } + /// Returns the latest version number for a lineage, or `None` if not tracked. + fn latest_version(&self, lineage: LineageId) -> Option { + self.lineage_versions + .get(&lineage) + .and_then(|versions| versions.last().map(|(v, _)| *v)) + } + + /// Applies forest updates for a lineage at a given block number. + /// + /// Returns the new root. fn apply_forest_updates( &mut self, lineage: LineageId, block_num: BlockNumber, - operations: Vec, + entries: Vec<(Word, Word)>, ) -> Word { - let updates = if operations.is_empty() { - SmtUpdateBatch::empty() - } else { - SmtUpdateBatch::new(operations.into_iter()) - }; let version = block_num.as_u64(); - let tree = if self.forest.latest_version(lineage).is_some() { - self.forest - .update_tree(lineage, version, updates) - .expect("forest update should succeed") + + // Get the current root for this lineage (or empty root). + let current_root = self.latest_root(lineage).unwrap_or_else(Self::empty_smt_root); + + // Apply all entries via batch_insert on the SmtForest. + let new_root = if entries.is_empty() { + current_root } else { self.forest - .add_lineage(lineage, version, updates) + .batch_insert(current_root, entries) .expect("forest update should succeed") }; - tree.root() - } - fn map_forest_error(error: LargeSmtForestError) -> MerkleError { - match error { - LargeSmtForestError::Merkle(merkle) => merkle, - other => MerkleError::InternalError(other.as_report()), - } + // Record the new version. + self.lineage_versions.entry(lineage).or_default().push((version, new_root)); + + new_root } - fn map_forest_error_to_witness(error: LargeSmtForestError) -> WitnessError { - match error { - LargeSmtForestError::Merkle(merkle) => WitnessError::MerkleError(merkle), - other => WitnessError::MerkleError(MerkleError::InternalError(other.as_report())), + /// Finds the root for a lineage at or before the given block number. + fn get_root_at_block(&self, lineage: LineageId, block_num: BlockNumber) -> Option { + let versions = self.lineage_versions.get(&lineage)?; + let target = block_num.as_u64(); + // Find the latest version <= target. + let mut result = None; + for &(v, root) in versions { + if v <= target { + result = Some(root); + } else { + break; + } } + result } // ACCESSORS // -------------------------------------------------------------------------------------------- - fn get_tree_id(&self, lineage: LineageId, block_num: BlockNumber) -> Option { - let tree = self.lookup_tree_id(lineage, block_num); - match self.forest.root_info(tree) { - RootInfo::LatestVersion(_) | RootInfo::HistoricalVersion(_) => Some(tree), - RootInfo::Missing => { - let latest_version = self.forest.latest_version(lineage)?; - if latest_version <= block_num.as_u64() { - Some(TreeId::new(lineage, latest_version)) - } else { - None - } - }, - } - } - - #[cfg(test)] - fn get_tree_root(&self, lineage: LineageId, block_num: BlockNumber) -> Option { - let tree = self.get_tree_id(lineage, block_num)?; - match self.forest.root_info(tree) { - RootInfo::LatestVersion(root) | RootInfo::HistoricalVersion(root) => Some(root), - RootInfo::Missing => None, - } - } - /// Retrieves a vault root for the specified account and block. #[cfg(test)] pub(crate) fn get_vault_root( @@ -209,7 +195,7 @@ impl AccountStateForest { block_num: BlockNumber, ) -> Option { let lineage = Self::vault_lineage_id(account_id); - self.get_tree_root(lineage, block_num) + self.get_root_at_block(lineage, block_num) } /// Retrieves the storage map root for an account slot at the specified block. @@ -221,7 +207,7 @@ impl AccountStateForest { block_num: BlockNumber, ) -> Option { let lineage = Self::storage_lineage_id(account_id, slot_name); - self.get_tree_root(lineage, block_num) + self.get_root_at_block(lineage, block_num) } // WITNESSES and PROOFS @@ -239,9 +225,9 @@ impl AccountStateForest { raw_key: StorageMapKey, ) -> Result { let lineage = Self::storage_lineage_id(account_id, slot_name); - let tree = self.get_tree_id(lineage, block_num).ok_or(WitnessError::RootNotFound)?; + let root = self.get_root_at_block(lineage, block_num).ok_or(WitnessError::RootNotFound)?; let key = raw_key.hash().into(); - let proof = self.forest.open(tree, key).map_err(Self::map_forest_error_to_witness)?; + let proof = self.forest.open(root, key)?; Ok(StorageMapWitness::new(proof, vec![raw_key])?) } @@ -255,13 +241,10 @@ impl AccountStateForest { asset_keys: BTreeSet, ) -> Result, WitnessError> { let lineage = Self::vault_lineage_id(account_id); - let tree = self.get_tree_id(lineage, block_num).ok_or(WitnessError::RootNotFound)?; + let root = self.get_root_at_block(lineage, block_num).ok_or(WitnessError::RootNotFound)?; let witnessees: Result, WitnessError> = Result::from_iter(asset_keys.into_iter().map(|key| { - let proof = self - .forest - .open(tree, key.into()) - .map_err(Self::map_forest_error_to_witness)?; + let proof = self.forest.open(root, key.into())?; let asset = AssetWitness::new(proof)?; Ok(asset) })); @@ -280,11 +263,11 @@ impl AccountStateForest { raw_keys: &[StorageMapKey], ) -> Option> { let lineage = Self::storage_lineage_id(account_id, &slot_name); - let tree = self.get_tree_id(lineage, block_num)?; + let root = self.get_root_at_block(lineage, block_num)?; let proofs = Result::from_iter(raw_keys.iter().map(|raw_key| { let key_hashed = raw_key.hash().into(); - self.forest.open(tree, key_hashed).map_err(Self::map_forest_error) + self.forest.open(root, key_hashed) })); Some(proofs.map(|proofs| AccountStorageMapDetails::from_proofs(slot_name, proofs))) @@ -373,7 +356,7 @@ impl AccountStateForest { /// account, returns an empty SMT root. fn get_latest_vault_root(&self, account_id: AccountId) -> Word { let lineage = Self::vault_lineage_id(account_id); - self.forest.latest_root(lineage).unwrap_or_else(Self::empty_smt_root) + self.latest_root(lineage).unwrap_or_else(Self::empty_smt_root) } /// Inserts asset vault data into the forest for the specified account. Assumes that asset @@ -387,10 +370,7 @@ impl AccountStateForest { let prev_root = self.get_latest_vault_root(account_id); let lineage = Self::vault_lineage_id(account_id); assert_eq!(prev_root, Self::empty_smt_root(), "account should not be in the forest"); - assert!( - self.forest.latest_version(lineage).is_none(), - "account should not be in the forest" - ); + assert!(self.latest_version(lineage).is_none(), "account should not be in the forest"); if vault_delta.is_empty() { let lineage = Self::vault_lineage_id(account_id); @@ -413,14 +393,16 @@ impl AccountStateForest { let amount = (*amount_delta).try_into().expect("full-state amount should be non-negative"); let asset = FungibleAsset::new(*faucet_id, amount)?; - entries.push((asset.vault_key().into(), asset.into())); + entries.push((asset.to_key_word(), asset.to_value_word())); } // process non-fungible assets for (&asset, action) in vault_delta.non_fungible().iter() { - let asset_vault_key = asset.vault_key().into(); + let asset_vault_key: Word = asset.vault_key().into(); match action { - NonFungibleDeltaAction::Add => entries.push((asset_vault_key, asset.into())), + NonFungibleDeltaAction::Add => { + entries.push((asset_vault_key, asset.to_value_word())); + }, NonFungibleDeltaAction::Remove => entries.push((asset_vault_key, EMPTY_WORD)), } } @@ -428,8 +410,7 @@ impl AccountStateForest { let num_entries = entries.len(); let lineage = Self::vault_lineage_id(account_id); - let operations = Self::build_forest_operations(entries); - let new_root = self.apply_forest_updates(lineage, block_num, operations); + let new_root = self.apply_forest_updates(lineage, block_num, entries); tracing::debug!( target: crate::COMPONENT, @@ -477,12 +458,8 @@ impl AccountStateForest { ); let lineage = Self::storage_lineage_id(account_id, slot_name); - assert!( - self.forest.latest_version(lineage).is_none(), - "account should not be in the forest" - ); - let operations = Self::build_forest_operations(hashed_entries); - let new_root = self.apply_forest_updates(lineage, block_num, operations); + assert!(self.latest_version(lineage).is_none(), "account should not be in the forest"); + let new_root = self.apply_forest_updates(lineage, block_num, hashed_entries); let num_entries = raw_map_entries.len(); @@ -528,8 +505,7 @@ impl AccountStateForest { // get the previous vault root; the root could be for an empty or non-empty SMT let lineage = Self::vault_lineage_id(account_id); - let prev_tree = - self.forest.latest_version(lineage).map(|version| TreeId::new(lineage, version)); + let prev_root = self.latest_root(lineage); let mut entries: Vec<(Word, Word)> = Vec::new(); @@ -537,13 +513,16 @@ impl AccountStateForest { for (faucet_id, amount_delta) in vault_delta.fungible().iter() { let delta_abs = amount_delta.unsigned_abs(); let delta = FungibleAsset::new(*faucet_id, delta_abs)?; - let key = Word::from(delta.vault_key()); + let key = delta.to_key_word(); let empty = FungibleAsset::new(*faucet_id, 0)?; - let asset = if let Some(tree) = prev_tree { - self.forest - .get(tree, key)? - .map(FungibleAsset::try_from) + let asset = if let Some(root) = prev_root { + // Open the proof at the key to get the current value + let proof = self.forest.open(root, key)?; + let (_path, leaf) = proof.into_parts(); + let value = leaf.entries().iter().find(|(k, _)| *k == key).map(|(_, v)| *v); + value + .map(|v| FungibleAsset::from_key_value_words(key, v)) .transpose()? .unwrap_or(empty) } else { @@ -559,7 +538,7 @@ impl AccountStateForest { let value = if updated.amount() == 0 { EMPTY_WORD } else { - Word::from(updated) + updated.to_value_word() }; entries.push((key, value)); } @@ -567,7 +546,7 @@ impl AccountStateForest { // Process non-fungible assets for (asset, action) in vault_delta.non_fungible().iter() { let value = match action { - NonFungibleDeltaAction::Add => Word::from(Asset::NonFungible(*asset)), + NonFungibleDeltaAction::Add => asset.to_value_word(), NonFungibleDeltaAction::Remove => EMPTY_WORD, }; entries.push((asset.vault_key().into(), value)); @@ -576,8 +555,7 @@ impl AccountStateForest { let vault_entries = entries.len(); let lineage = Self::vault_lineage_id(account_id); - let operations = Self::build_forest_operations(entries); - let new_root = self.apply_forest_updates(lineage, block_num, operations); + let new_root = self.apply_forest_updates(lineage, block_num, entries); tracing::debug!( target: crate::COMPONENT, @@ -600,7 +578,7 @@ impl AccountStateForest { slot_name: &StorageSlotName, ) -> Word { let lineage = Self::storage_lineage_id(account_id, slot_name); - self.forest.latest_root(lineage).map_or_else(Self::empty_smt_root, |root| root) + self.latest_root(lineage).unwrap_or_else(Self::empty_smt_root) } /// Updates the forest with storage map changes from a delta. @@ -635,8 +613,7 @@ impl AccountStateForest { delta_entries.iter().map(|(raw_key, value)| (raw_key.hash().into(), *value)), ); - let operations = Self::build_forest_operations(hashed_entries); - let new_root = self.apply_forest_updates(lineage, block_num, operations); + let new_root = self.apply_forest_updates(lineage, block_num, hashed_entries); tracing::debug!( target: crate::COMPONENT, @@ -663,11 +640,28 @@ impl AccountStateForest { let cutoff_block = chain_tip .checked_sub(HISTORICAL_BLOCK_RETENTION) .unwrap_or(BlockNumber::GENESIS); - let before = self.forest.roots().count(); + let cutoff_version = cutoff_block.as_u64(); + + let mut pruned_count = 0; + let mut roots_to_prune = Vec::new(); + + for versions in self.lineage_versions.values_mut() { + // Keep only versions after the cutoff. We need at least one version (the latest + // at or before cutoff) to serve as the base state. + let split_idx = + versions.partition_point(|(v, _)| *v < cutoff_version).saturating_sub(1); + if split_idx > 0 { + let removed: Vec<_> = versions.drain(..split_idx).collect(); + for (_, root) in &removed { + roots_to_prune.push(*root); + } + pruned_count += removed.len(); + } + } - self.forest.truncate(cutoff_block.as_u64()); + // Remove old roots from the SmtForest to free memory. + self.forest.pop_smts(roots_to_prune); - let after = self.forest.roots().count(); - before.saturating_sub(after) + pruned_count } } diff --git a/crates/store/src/account_state_forest/tests.rs b/crates/store/src/account_state_forest/tests.rs index 9d72151bc6..daaff21c58 100644 --- a/crates/store/src/account_state_forest/tests.rs +++ b/crates/store/src/account_state_forest/tests.rs @@ -1,14 +1,14 @@ use assert_matches::assert_matches; use miden_node_proto::domain::account::StorageMapEntries; +use miden_protocol::Felt; use miden_protocol::account::{AccountCode, StorageMapKey}; -use miden_protocol::asset::{Asset, AssetVault, AssetVaultKey, FungibleAsset}; +use miden_protocol::asset::{Asset, AssetVault, FungibleAsset}; use miden_protocol::crypto::merkle::smt::SmtProof; use miden_protocol::testing::account_id::{ ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE_2, }; -use miden_protocol::{Felt, FieldElement}; use super::*; @@ -66,8 +66,7 @@ fn empty_smt_root_is_recognized() { #[test] fn account_state_forest_basic_initialization() { let forest = AccountStateForest::new(); - assert_eq!(forest.forest.lineage_count(), 0); - assert_eq!(forest.forest.tree_count(), 0); + assert_eq!(forest.lineage_versions.len(), 0); } #[test] @@ -85,7 +84,7 @@ fn update_account_with_empty_deltas() { forest.update_account(block_num, &delta).unwrap(); assert!(forest.get_vault_root(account_id, block_num).is_none()); - assert_eq!(forest.forest.lineage_count(), 0); + assert_eq!(forest.lineage_versions.len(), 0); } // VAULT TESTS @@ -191,11 +190,11 @@ fn forest_versions_are_continuous_for_sequential_updates() { let delta = dummy_partial_delta(account_id, vault_delta, storage_delta); forest.update_account(block_num, &delta).unwrap(); - let vault_tree = forest.tree_id_for_vault_root(account_id, block_num); - let storage_tree = forest.tree_id_for_root(account_id, &slot_name, block_num); + let vault_root = forest.tree_id_for_vault_root(account_id, block_num).unwrap(); + let storage_root = forest.tree_id_for_root(account_id, &slot_name, block_num).unwrap(); - assert_matches!(forest.forest.open(vault_tree, asset_key), Ok(_)); - assert_matches!(forest.forest.open(storage_tree, storage_key), Ok(_)); + assert_matches!(forest.forest.open(vault_root, asset_key), Ok(_)); + assert_matches!(forest.forest.open(storage_root, storage_key), Ok(_)); } } @@ -279,7 +278,7 @@ fn witness_queries_work_with_sparse_lineage_updates() { assert_matches!( forest .forest - .open(forest.tree_id_for_vault_root(account_id, block_3), asset_key.into()), + .open(forest.tree_id_for_vault_root(account_id, block_3).unwrap(), asset_key.into(),), Ok(_) ); assert_ne!(vault_root_at_3, AccountStateForest::empty_smt_root()); @@ -324,7 +323,7 @@ fn vault_shared_root_retained_when_one_entry_pruned() { let asset_amount = u64::from(HISTORICAL_BLOCK_RETENTION); let amount_increment = asset_amount / u64::from(HISTORICAL_BLOCK_RETENTION); let asset = dummy_fungible_asset(faucet_id, asset_amount); - let asset_key = AssetVaultKey::new_unchecked(asset.vault_key().into()); + let asset_key = asset.vault_key(); let mut vault_delta_1 = AccountVaultDelta::default(); vault_delta_1.add_asset(asset).unwrap(); @@ -455,15 +454,15 @@ fn test_storage_map_removals() { let delta_2 = dummy_partial_delta(account_id, AccountVaultDelta::default(), storage_delta_2); forest.update_account(block_2, &delta_2).unwrap(); - let tree = forest.tree_id_for_root(account_id, &slot_name, block_2); + let root = forest.tree_id_for_root(account_id, &slot_name, block_2).unwrap(); let key_2_hash = key_2.hash().into(); let key_1_hash = key_1.hash().into(); - let proof_key_2 = forest.forest.open(tree, key_2_hash).unwrap(); + let proof_key_2 = forest.forest.open(root, key_2_hash).unwrap(); assert_eq!(proof_key_2.get(&key_2_hash), Some(value_2)); - let proof_key_1 = forest.forest.open(tree, key_1_hash).unwrap(); + let proof_key_1 = forest.forest.open(root, key_1_hash).unwrap(); assert_eq!(proof_key_1.get(&key_1_hash), Some(EMPTY_WORD)); } @@ -545,7 +544,7 @@ fn storage_map_empty_entries_query() { let account_component = AccountComponent::new( component_code, component_storage, - AccountComponentMetadata::new("test").with_supports_all_types(), + AccountComponentMetadata::new("test", AccountType::all()), ) .unwrap(); @@ -555,7 +554,7 @@ fn storage_map_empty_entries_query() { .with_component(account_component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -700,14 +699,19 @@ fn prune_removes_smt_roots_from_forest() { assert!(forest.get_storage_map_root(account_id, &slot_name, retained_block).is_some()); let asset_key: Word = FungibleAsset::new(faucet_id, 0).unwrap().vault_key().into(); - let retained_tree = forest.tree_id_for_vault_root(account_id, retained_block); - let pruned_tree = forest.tree_id_for_vault_root(account_id, pruned_block); - assert_matches!(forest.forest.open(retained_tree, asset_key), Ok(_)); - assert_matches!(forest.forest.open(pruned_tree, asset_key), Err(_)); + let retained_root = forest.tree_id_for_vault_root(account_id, retained_block).unwrap(); + let pruned_root = forest.tree_id_for_vault_root(account_id, pruned_block); + assert_matches!(forest.forest.open(retained_root, asset_key), Ok(_)); + // Pruned root may not exist + if let Some(root) = pruned_root { + assert_matches!(forest.forest.open(root, asset_key), Err(_)); + } let storage_key = StorageMapKey::new(Word::from([1u32, 0, 0, 0])).hash().into(); - let storage_tree = forest.tree_id_for_root(account_id, &slot_name, pruned_block); - assert_matches!(forest.forest.open(storage_tree, storage_key), Err(_)); + let storage_root = forest.tree_id_for_root(account_id, &slot_name, pruned_block); + if let Some(root) = storage_root { + assert_matches!(forest.forest.open(root, storage_key), Err(_)); + } } #[test] @@ -729,7 +733,7 @@ fn prune_respects_retention_boundary() { let total_roots_removed = forest.prune(BlockNumber::from(HISTORICAL_BLOCK_RETENTION)); assert_eq!(total_roots_removed, 0); - assert_eq!(forest.forest.tree_count(), 11); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 11); } #[test] @@ -759,13 +763,13 @@ fn prune_roots_removes_old_entries() { forest.update_account(block_num, &delta).unwrap(); } - assert_eq!(forest.forest.tree_count(), 22); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); let total_roots_removed = forest.prune(BlockNumber::from(TEST_CHAIN_LENGTH)); assert_eq!(total_roots_removed, 0); - assert_eq!(forest.forest.tree_count(), 22); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); } #[test] @@ -790,7 +794,7 @@ fn prune_handles_multiple_accounts() { forest.update_account(block_num, &delta2).unwrap(); } - assert_eq!(forest.forest.tree_count(), 22); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); let total_roots_removed = forest.prune(BlockNumber::from(TEST_CHAIN_LENGTH)); @@ -798,7 +802,7 @@ fn prune_handles_multiple_accounts() { assert_eq!(total_roots_removed, 0); assert!(total_roots_removed <= expected_removed_per_account * 2); - assert_eq!(forest.forest.tree_count(), 22); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); } #[test] @@ -827,14 +831,14 @@ fn prune_handles_multiple_slots() { forest.update_account(block_num, &delta).unwrap(); } - assert_eq!(forest.forest.tree_count(), 22); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); let chain_tip = BlockNumber::from(TEST_CHAIN_LENGTH); let total_roots_removed = forest.prune(chain_tip); assert_eq!(total_roots_removed, 0); - assert_eq!(forest.forest.tree_count(), 22); + assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); } #[test] @@ -953,7 +957,7 @@ fn shared_vault_root_retained_when_one_account_changes() { let block_1 = BlockNumber::GENESIS.child(); let initial_amount = 1000u64; let asset = dummy_fungible_asset(faucet_id, initial_amount); - let asset_key = AssetVaultKey::new_unchecked(asset.vault_key().into()); + let asset_key = asset.vault_key(); let mut vault_delta_1 = AccountVaultDelta::default(); vault_delta_1.add_asset(asset).unwrap(); diff --git a/crates/store/src/accounts/tests.rs b/crates/store/src/accounts/tests.rs index 9f7b5dcbd8..8e489e2ea1 100644 --- a/crates/store/src/accounts/tests.rs +++ b/crates/store/src/accounts/tests.rs @@ -8,7 +8,7 @@ mod account_tree_with_history_tests { use miden_protocol::Word; use miden_protocol::account::AccountId; use miden_protocol::block::BlockNumber; - use miden_protocol::block::account_tree::{AccountTree, account_id_to_smt_key}; + use miden_protocol::block::account_tree::{AccountIdKey, AccountTree}; use miden_protocol::crypto::merkle::smt::{LargeSmt, MemoryStorage}; use miden_protocol::testing::account_id::AccountIdBuilder; @@ -20,7 +20,7 @@ mod account_tree_with_history_tests { ) -> InMemoryAccountTree { let smt_entries = entries .into_iter() - .map(|(id, commitment)| (account_id_to_smt_key(id), commitment)); + .map(|(id, commitment)| (AccountIdKey::from(id).as_word(), commitment)); let smt = LargeSmt::with_entries(MemoryStorage::default(), smt_entries) .expect("Failed to create LargeSmt from entries"); AccountTree::new(smt).expect("Failed to create AccountTree") diff --git a/crates/store/src/blocks.rs b/crates/store/src/blocks.rs index e771332ba9..10319214ac 100644 --- a/crates/store/src/blocks.rs +++ b/crates/store/src/blocks.rs @@ -3,7 +3,7 @@ use std::ops::Not; use std::path::PathBuf; use miden_protocol::block::BlockNumber; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use tracing::instrument; use crate::COMPONENT; diff --git a/crates/store/src/db/mod.rs b/crates/store/src/db/mod.rs index 43df59d5e3..6fb5fd35cb 100644 --- a/crates/store/src/db/mod.rs +++ b/crates/store/src/db/mod.rs @@ -24,7 +24,7 @@ use miden_protocol::note::{ Nullifier, }; use miden_protocol::transaction::{InputNoteCommitment, TransactionId}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use tokio::sync::oneshot; use tracing::{info, instrument}; @@ -117,7 +117,7 @@ impl AccountVaultValue { let vault_key = Word::read_from_bytes(&vault_key)?; Ok(Self { block_num: BlockNumber::from_raw_sql(block_num)?, - vault_key: AssetVaultKey::new_unchecked(vault_key), + vault_key: AssetVaultKey::try_from(vault_key)?, asset: asset.map(|b| Asset::read_from_bytes(&b)).transpose()?, }) } diff --git a/crates/store/src/db/models/conv.rs b/crates/store/src/db/models/conv.rs index 2176ea0d46..25b6047f9e 100644 --- a/crates/store/src/db/models/conv.rs +++ b/crates/store/src/db/models/conv.rs @@ -204,7 +204,7 @@ pub(crate) fn raw_sql_to_nonce(raw: i64) -> Felt { } #[inline(always)] pub(crate) fn nonce_to_raw_sql(nonce: Felt) -> i64 { - nonce.as_int() as i64 + nonce.as_canonical_u64() as i64 } #[inline(always)] diff --git a/crates/store/src/db/models/queries/accounts.rs b/crates/store/src/db/models/queries/accounts.rs index 514bad31f3..5b86c79ac6 100644 --- a/crates/store/src/db/models/queries/accounts.rs +++ b/crates/store/src/db/models/queries/accounts.rs @@ -36,7 +36,7 @@ use miden_protocol::account::{ }; use miden_protocol::asset::{Asset, AssetVault, AssetVaultKey, FungibleAsset}; use miden_protocol::block::{BlockAccountUpdate, BlockNumber}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_protocol::{Felt, Word}; use crate::COMPONENT; @@ -297,7 +297,7 @@ pub(crate) fn select_account_commitments_paged( page_size: NonZeroUsize, after_account_id: Option, ) -> Result { - use miden_protocol::utils::Serializable; + use miden_protocol::utils::serde::Serializable; // Fetch one extra to determine if there are more results #[expect(clippy::cast_possible_wrap)] @@ -373,7 +373,7 @@ pub(crate) fn select_public_account_ids_paged( page_size: NonZeroUsize, after_account_id: Option, ) -> Result { - use miden_protocol::utils::Serializable; + use miden_protocol::utils::serde::Serializable; #[expect(clippy::cast_possible_wrap)] let limit = (page_size.get() + 1) as i64; @@ -900,7 +900,7 @@ impl TryFrom for AccountVaultValue { type Error = DatabaseError; fn try_from(raw: AccountVaultUpdateRaw) -> Result { - let vault_key = AssetVaultKey::new_unchecked(Word::read_from_bytes(&raw.vault_key)?); + let vault_key = AssetVaultKey::try_from(Word::read_from_bytes(&raw.vault_key)?)?; let asset = raw.asset.map(|bytes| Asset::read_from_bytes(&bytes)).transpose()?; let block_num = BlockNumber::from_raw_sql(raw.block_num)?; @@ -1153,8 +1153,8 @@ fn prepare_partial_account_update( // Apply nonce delta. let new_nonce_value = state_headers .nonce - .as_int() - .checked_add(delta.nonce_delta().as_int()) + .as_canonical_u64() + .checked_add(delta.nonce_delta().as_canonical_u64()) .ok_or_else(|| { DatabaseError::DataCorrupted(format!("Nonce overflow for account {account_id}")) })?; diff --git a/crates/store/src/db/models/queries/accounts/at_block.rs b/crates/store/src/db/models/queries/accounts/at_block.rs index 41ec035f3f..fc2ddb00e6 100644 --- a/crates/store/src/db/models/queries/accounts/at_block.rs +++ b/crates/store/src/db/models/queries/accounts/at_block.rs @@ -4,8 +4,8 @@ use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, Sqlite use miden_protocol::account::{AccountHeader, AccountId, AccountStorageHeader}; use miden_protocol::asset::Asset; use miden_protocol::block::BlockNumber; -use miden_protocol::utils::{Deserializable, Serializable}; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; +use miden_protocol::{Felt, Word}; use crate::db::models::conv::{SqlTypeConvert, raw_sql_to_nonce}; use crate::db::schema; diff --git a/crates/store/src/db/models/queries/accounts/delta.rs b/crates/store/src/db/models/queries/accounts/delta.rs index 8bab2b1220..460e3fbbd4 100644 --- a/crates/store/src/db/models/queries/accounts/delta.rs +++ b/crates/store/src/db/models/queries/accounts/delta.rs @@ -23,7 +23,7 @@ use miden_protocol::account::{ StorageSlotName, }; use miden_protocol::asset::{Asset, FungibleAsset}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_protocol::{EMPTY_WORD, Felt, Word}; use crate::db::models::conv::raw_sql_to_nonce; diff --git a/crates/store/src/db/models/queries/accounts/delta/tests.rs b/crates/store/src/db/models/queries/accounts/delta/tests.rs index 7f31003259..4bb32e8cc2 100644 --- a/crates/store/src/db/models/queries/accounts/delta/tests.rs +++ b/crates/store/src/db/models/queries/accounts/delta/tests.rs @@ -35,7 +35,7 @@ use miden_protocol::testing::account_id::{ ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1, }; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use miden_protocol::{EMPTY_WORD, Felt, Word}; use miden_standards::account::auth::AuthSingleSig; use miden_standards::code_builder::CodeBuilder; @@ -142,8 +142,7 @@ fn optimized_delta_matches_full_account_method() { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -153,7 +152,7 @@ fn optimized_delta_matches_full_account_method() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -227,7 +226,8 @@ fn optimized_delta_matches_full_account_method() { assert!(!partial_delta.is_full_state(), "Delta should be partial, not full state"); // Construct the expected final account by applying the delta - let expected_nonce = Felt::new(full_account_before.nonce().as_int() + nonce_delta.as_int()); + let expected_nonce = + Felt::new(full_account_before.nonce().as_canonical_u64() + nonce_delta.as_canonical_u64()); let expected_code_commitment = full_account_before.code().commitment(); let mut expected_account = full_account_before.clone(); @@ -336,8 +336,7 @@ fn optimized_delta_updates_non_empty_vault() { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -347,7 +346,7 @@ fn optimized_delta_updates_non_empty_vault() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .with_assets([initial_asset]) .build_existing() @@ -461,8 +460,7 @@ fn optimized_delta_updates_storage_map_header() { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -472,7 +470,7 @@ fn optimized_delta_updates_storage_map_header() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -635,8 +633,7 @@ fn upsert_full_state_delta() { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -646,7 +643,7 @@ fn upsert_full_state_delta() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); diff --git a/crates/store/src/db/models/queries/accounts/tests.rs b/crates/store/src/db/models/queries/accounts/tests.rs index 572cab258c..9691a4163f 100644 --- a/crates/store/src/db/models/queries/accounts/tests.rs +++ b/crates/store/src/db/models/queries/accounts/tests.rs @@ -40,8 +40,8 @@ use miden_protocol::account::{ }; use miden_protocol::block::{BlockAccountUpdate, BlockHeader, BlockNumber}; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; -use miden_protocol::utils::{Deserializable, Serializable}; -use miden_protocol::{EMPTY_WORD, Felt, FieldElement, Word}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; +use miden_protocol::{EMPTY_WORD, Felt, Word}; use miden_standards::account::auth::AuthSingleSig; use miden_standards::code_builder::CodeBuilder; @@ -154,8 +154,7 @@ fn create_test_account_with_storage() -> (Account, AccountId) { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -165,7 +164,7 @@ fn create_test_account_with_storage() -> (Account, AccountId) { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -218,8 +217,7 @@ fn create_account_with_map_storage( let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -229,7 +227,7 @@ fn create_account_with_map_storage( .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap() @@ -474,8 +472,7 @@ fn test_upsert_accounts_updates_is_latest_flag() { let component_2 = AccountComponent::new( account_component_code, component_storage_modified, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -485,7 +482,7 @@ fn test_upsert_accounts_updates_is_latest_flag() { .with_component(component_2) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -574,8 +571,7 @@ fn test_upsert_accounts_with_multiple_storage_slots() { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -585,7 +581,7 @@ fn test_upsert_accounts_with_multiple_storage_slots() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -644,8 +640,7 @@ fn test_upsert_accounts_with_empty_storage() { let component = AccountComponent::new( account_component_code, vec![], - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -655,7 +650,7 @@ fn test_upsert_accounts_with_empty_storage() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -781,8 +776,7 @@ fn test_select_latest_account_storage_multiple_slots() { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountImmutableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountImmutableCode]), ) .unwrap(); @@ -792,7 +786,7 @@ fn test_select_latest_account_storage_multiple_slots() { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -883,8 +877,11 @@ fn test_select_latest_account_storage_slot_updates() { #[test] fn test_select_account_vault_at_block_historical_with_updates() { use assert_matches::assert_matches; - use miden_protocol::asset::{AssetVaultKey, FungibleAsset}; - use miden_protocol::testing::account_id::ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET; + use miden_protocol::asset::FungibleAsset; + use miden_protocol::testing::account_id::{ + ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, + ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1, + }; let mut conn = setup_test_db(); let (account, _) = create_test_account_with_storage(); @@ -915,13 +912,8 @@ fn test_select_account_vault_at_block_historical_with_updates() { } // Insert vault asset at block 1: vault_key_1 = 1000 tokens - let vault_key_1 = AssetVaultKey::new_unchecked(Word::from([ - Felt::new(1), - Felt::ZERO, - Felt::ZERO, - Felt::ZERO, - ])); let asset_v1 = Asset::Fungible(FungibleAsset::new(faucet_id, 1000).unwrap()); + let vault_key_1 = asset_v1.vault_key(); insert_account_vault_asset(&mut conn, account_id, block_1, vault_key_1, Some(asset_v1)) .expect("insert vault asset failed"); @@ -931,14 +923,10 @@ fn test_select_account_vault_at_block_historical_with_updates() { insert_account_vault_asset(&mut conn, account_id, block_2, vault_key_1, Some(asset_v2)) .expect("insert vault asset update failed"); - // Add a second vault_key at block 2 - let vault_key_2 = AssetVaultKey::new_unchecked(Word::from([ - Felt::new(2), - Felt::ZERO, - Felt::ZERO, - Felt::ZERO, - ])); - let asset_key2 = Asset::Fungible(FungibleAsset::new(faucet_id, 500).unwrap()); + // Add a second vault_key at block 2 (different faucet for different vault key) + let faucet_id_2 = AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1).unwrap(); + let asset_key2 = Asset::Fungible(FungibleAsset::new(faucet_id_2, 500).unwrap()); + let vault_key_2 = asset_key2.vault_key(); insert_account_vault_asset(&mut conn, account_id, block_2, vault_key_2, Some(asset_key2)) .expect("insert second vault asset failed"); @@ -1017,12 +1005,7 @@ fn test_select_account_vault_at_block_exponential_updates() { .expect("upsert_accounts failed"); } - let vault_key = AssetVaultKey::new_unchecked(Word::from([ - Felt::new(3), - Felt::ZERO, - Felt::ZERO, - Felt::ZERO, - ])); + let vault_key = AssetVaultKey::new_fungible(faucet_id).unwrap(); for (index, block) in blocks.iter().enumerate() { let amount = 1u64 << index; @@ -1049,7 +1032,7 @@ fn test_select_account_vault_at_block_exponential_updates() { #[test] fn test_select_account_vault_at_block_with_deletion() { use assert_matches::assert_matches; - use miden_protocol::asset::{AssetVaultKey, FungibleAsset}; + use miden_protocol::asset::FungibleAsset; use miden_protocol::testing::account_id::ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET; let mut conn = setup_test_db(); @@ -1081,13 +1064,8 @@ fn test_select_account_vault_at_block_with_deletion() { } // Insert vault asset at block 1 - let vault_key = AssetVaultKey::new_unchecked(Word::from([ - Felt::new(1), - Felt::ZERO, - Felt::ZERO, - Felt::ZERO, - ])); let asset = Asset::Fungible(FungibleAsset::new(faucet_id, 1000).unwrap()); + let vault_key = asset.vault_key(); insert_account_vault_asset(&mut conn, account_id, block_1, vault_key, Some(asset)) .expect("insert vault asset failed"); diff --git a/crates/store/src/db/models/queries/block_headers.rs b/crates/store/src/db/models/queries/block_headers.rs index bfcd34ee7a..59c4ce530b 100644 --- a/crates/store/src/db/models/queries/block_headers.rs +++ b/crates/store/src/db/models/queries/block_headers.rs @@ -15,7 +15,7 @@ use miden_crypto::Word; use miden_crypto::dsa::ecdsa_k256_keccak::Signature; use miden_node_utils::limiter::{QueryParamBlockLimit, QueryParamLimiter}; use miden_protocol::block::{BlockHeader, BlockNumber}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use super::DatabaseError; use crate::COMPONENT; diff --git a/crates/store/src/db/models/queries/notes.rs b/crates/store/src/db/models/queries/notes.rs index 49bdce4198..cf42ceb58d 100644 --- a/crates/store/src/db/models/queries/notes.rs +++ b/crates/store/src/db/models/queries/notes.rs @@ -49,7 +49,7 @@ use miden_protocol::note::{ NoteType, Nullifier, }; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_standards::note::NetworkAccountTarget; use crate::COMPONENT; diff --git a/crates/store/src/db/models/queries/nullifiers.rs b/crates/store/src/db/models/queries/nullifiers.rs index 84e89ebad5..89f62b4ab3 100644 --- a/crates/store/src/db/models/queries/nullifiers.rs +++ b/crates/store/src/db/models/queries/nullifiers.rs @@ -20,7 +20,7 @@ use miden_node_utils::limiter::{ }; use miden_protocol::block::BlockNumber; use miden_protocol::note::Nullifier; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use super::DatabaseError; use crate::COMPONENT; diff --git a/crates/store/src/db/models/queries/transactions.rs b/crates/store/src/db/models/queries/transactions.rs index 69b3986f15..79d2bdfeb0 100644 --- a/crates/store/src/db/models/queries/transactions.rs +++ b/crates/store/src/db/models/queries/transactions.rs @@ -21,7 +21,7 @@ use miden_protocol::account::AccountId; use miden_protocol::block::BlockNumber; use miden_protocol::note::NoteHeader; use miden_protocol::transaction::{InputNoteCommitment, OrderedTransactionHeaders, TransactionId}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use super::DatabaseError; use crate::COMPONENT; diff --git a/crates/store/src/db/models/utils.rs b/crates/store/src/db/models/utils.rs index ef74e86fac..80dc1e9197 100644 --- a/crates/store/src/db/models/utils.rs +++ b/crates/store/src/db/models/utils.rs @@ -1,6 +1,6 @@ use diesel::{Connection, RunQueryDsl, SqliteConnection}; use miden_protocol::note::Nullifier; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use crate::errors::DatabaseError; @@ -23,7 +23,7 @@ pub(crate) fn serialize_vec<'a, D: Serializable + 'a>( /// Returns the high 16 bits of the provided nullifier. pub fn get_nullifier_prefix(nullifier: &Nullifier) -> u16 { - (nullifier.most_significant_felt().as_int() >> 48) as u16 + (nullifier.most_significant_felt().as_canonical_u64() >> 48) as u16 } /// Converts a slice of length `N` to an array, returns `None` if invariant diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index f0744eae32..ebd071f7f4 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -26,7 +26,7 @@ use miden_protocol::account::{ StorageSlotDelta, StorageSlotName, }; -use miden_protocol::asset::{Asset, AssetVaultKey, FungibleAsset}; +use miden_protocol::asset::{Asset, FungibleAsset}; use miden_protocol::block::{ BlockAccountUpdate, BlockHeader, @@ -52,6 +52,9 @@ use miden_protocol::note::{ use miden_protocol::testing::account_id::{ ACCOUNT_ID_PRIVATE_SENDER, ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, + ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1, + ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2, + ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_3, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE_2, }; @@ -63,8 +66,8 @@ use miden_protocol::transaction::{ TransactionHeader, TransactionId, }; -use miden_protocol::utils::{Deserializable, Serializable}; -use miden_protocol::{EMPTY_WORD, Felt, FieldElement, Word}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; +use miden_protocol::{EMPTY_WORD, Felt, Word}; use miden_standards::account::auth::AuthSingleSig; use miden_standards::code_builder::CodeBuilder; use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint, P2idNote}; @@ -476,11 +479,12 @@ fn sync_account_vault_basic_validation() { .unwrap(); } - // Create some test vault assets - let vault_key_1 = AssetVaultKey::new_unchecked(num_to_word(100)); - let vault_key_2 = AssetVaultKey::new_unchecked(num_to_word(200)); + // Create test vault assets from two different faucets to get different vault keys. + let faucet_id_2 = AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1).unwrap(); let fungible_asset_1 = Asset::Fungible(FungibleAsset::new(public_account_id, 1000).unwrap()); - let fungible_asset_2 = Asset::Fungible(FungibleAsset::new(public_account_id, 2000).unwrap()); + let fungible_asset_2 = Asset::Fungible(FungibleAsset::new(faucet_id_2, 2000).unwrap()); + let vault_key_1 = fungible_asset_1.vault_key(); + let vault_key_2 = fungible_asset_2.vault_key(); // Insert vault assets for the public account at different blocks queries::insert_account_vault_asset( @@ -1317,8 +1321,7 @@ fn create_account_with_code(code_str: &str, seed: [u8; 32]) -> Account { let component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test") - .with_supported_type(AccountType::RegularAccountUpdatableCode), + AccountComponentMetadata::new("test", [AccountType::RegularAccountUpdatableCode]), ) .unwrap(); @@ -1328,7 +1331,7 @@ fn create_account_with_code(code_str: &str, seed: [u8; 32]) -> Account { .with_component(component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap() @@ -1357,6 +1360,8 @@ fn mock_block_transaction(account_id: AccountId, num: u64) -> TransactionHeader final_account_commitment, input_notes_commitment, output_notes_commitment, + FungibleAsset::new(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET).unwrap(), 0) + .unwrap(), ), account_id, initial_state_commitment, @@ -1418,7 +1423,7 @@ fn mock_account_code_and_storage( let account_component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("counter_contract").with_supports_all_types(), + AccountComponentMetadata::new("counter_contract", AccountType::all()), ) .unwrap(); @@ -1429,7 +1434,7 @@ fn mock_account_code_and_storage( .with_component(account_component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap() @@ -1582,7 +1587,7 @@ async fn genesis_with_account_assets() { let account_component = AccountComponent::new( account_component_code, Vec::new(), - AccountComponentMetadata::new("foo").with_supports_all_types(), + AccountComponentMetadata::new("foo", AccountType::all()), ) .unwrap(); @@ -1596,7 +1601,7 @@ async fn genesis_with_account_assets() { .with_assets([fungible_asset.into()]) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -1641,7 +1646,7 @@ async fn genesis_with_account_storage_map() { let account_component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("foo").with_supports_all_types(), + AccountComponentMetadata::new("foo", AccountType::all()), ) .unwrap(); @@ -1651,7 +1656,7 @@ async fn genesis_with_account_storage_map() { .with_component(account_component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -1693,7 +1698,7 @@ async fn genesis_with_account_assets_and_storage() { let account_component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("foo").with_supports_all_types(), + AccountComponentMetadata::new("foo", AccountType::all()), ) .unwrap(); @@ -1704,7 +1709,7 @@ async fn genesis_with_account_assets_and_storage() { .with_assets([fungible_asset.into()]) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -1731,7 +1736,7 @@ async fn genesis_with_multiple_accounts() { let account_component1 = AccountComponent::new( account_component_code, Vec::new(), - AccountComponentMetadata::new("foo").with_supports_all_types(), + AccountComponentMetadata::new("foo", AccountType::all()), ) .unwrap(); @@ -1741,7 +1746,7 @@ async fn genesis_with_multiple_accounts() { .with_component(account_component1) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -1755,7 +1760,7 @@ async fn genesis_with_multiple_accounts() { let account_component2 = AccountComponent::new( account_component_code, Vec::new(), - AccountComponentMetadata::new("bar").with_supports_all_types(), + AccountComponentMetadata::new("bar", AccountType::all()), ) .unwrap(); @@ -1766,7 +1771,7 @@ async fn genesis_with_multiple_accounts() { .with_assets([fungible_asset.into()]) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -1785,7 +1790,7 @@ async fn genesis_with_multiple_accounts() { let account_component3 = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("baz").with_supports_all_types(), + AccountComponentMetadata::new("baz", AccountType::all()), ) .unwrap(); @@ -1795,7 +1800,7 @@ async fn genesis_with_multiple_accounts() { .with_component(account_component3) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -1885,7 +1890,14 @@ fn serialization_symmetry_core_types() { assert_eq!(nullifier, restored, "Nullifier serialization must be symmetric"); // TransactionId - let tx_id = TransactionId::new(num_to_word(1), num_to_word(2), num_to_word(3), num_to_word(4)); + let tx_id = TransactionId::new( + num_to_word(1), + num_to_word(2), + num_to_word(3), + num_to_word(4), + FungibleAsset::new(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET).unwrap(), 0) + .unwrap(), + ); let bytes = tx_id.to_bytes(); let restored = TransactionId::read_from_bytes(&bytes).unwrap(); assert_eq!(tx_id, restored, "TransactionId serialization must be symmetric"); @@ -2253,7 +2265,7 @@ fn db_roundtrip_account_storage_with_maps() { let account_component = AccountComponent::new( account_component_code, component_storage, - AccountComponentMetadata::new("test").with_supports_all_types(), + AccountComponentMetadata::new("test", AccountType::all()), ) .unwrap(); @@ -2263,7 +2275,7 @@ fn db_roundtrip_account_storage_with_maps() { .with_component(account_component) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthScheme::Falcon512Rpo, + AuthScheme::Falcon512Poseidon2, )) .build_existing() .unwrap(); @@ -2416,13 +2428,15 @@ fn test_prune_history() { .unwrap(); } - // Insert vault assets at different blocks - let vault_key_old = AssetVaultKey::new_unchecked(num_to_word(100)); - let vault_key_cutoff = AssetVaultKey::new_unchecked(num_to_word(200)); - let vault_key_recent = AssetVaultKey::new_unchecked(num_to_word(300)); + // Insert vault assets at different blocks - use different faucets for different vault keys. + let faucet_2 = AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1).unwrap(); + let faucet_3 = AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2).unwrap(); let asset_1 = Asset::Fungible(FungibleAsset::new(public_account_id, 1000).unwrap()); - let asset_2 = Asset::Fungible(FungibleAsset::new(public_account_id, 2000).unwrap()); - let asset_3 = Asset::Fungible(FungibleAsset::new(public_account_id, 3000).unwrap()); + let asset_2 = Asset::Fungible(FungibleAsset::new(faucet_2, 2000).unwrap()); + let asset_3 = Asset::Fungible(FungibleAsset::new(faucet_3, 3000).unwrap()); + let vault_key_old = asset_1.vault_key(); + let vault_key_cutoff = asset_2.vault_key(); + let vault_key_recent = asset_3.vault_key(); // Old entry at block_old (should be deleted when cutoff is at block_cutoff for // chain_tip=block_tip) @@ -2607,8 +2621,9 @@ fn test_prune_history() { // Test that is_latest=true entries are never deleted, even if old // Insert an old entry marked as latest - let vault_key_old_latest = AssetVaultKey::new_unchecked(num_to_word(999)); - let asset_old = Asset::Fungible(FungibleAsset::new(public_account_id, 9999).unwrap()); + let faucet_4 = AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_3).unwrap(); + let asset_old = Asset::Fungible(FungibleAsset::new(faucet_4, 9999).unwrap()); + let vault_key_old_latest = asset_old.vault_key(); queries::insert_account_vault_asset( conn, public_account_id, @@ -3151,11 +3166,7 @@ fn account_state_forest_preserves_most_recent_vault_only() { // Verify we can get witnesses for the vault and verify against vault root let witnesses = forest - .get_vault_asset_witnesses( - account_id, - block_1, - [AssetVaultKey::new_unchecked(asset.vault_key().into())].into(), - ) + .get_vault_asset_witnesses(account_id, block_1, [asset.vault_key()].into()) .expect("Should be able to get vault witness after pruning"); assert_eq!(witnesses.len(), 1, "Should have one witness"); diff --git a/crates/store/src/genesis/config/errors.rs b/crates/store/src/genesis/config/errors.rs index 3ea497d547..3a9721c8b4 100644 --- a/crates/store/src/genesis/config/errors.rs +++ b/crates/store/src/genesis/config/errors.rs @@ -8,7 +8,7 @@ use miden_protocol::errors::{ FeeError, TokenSymbolError, }; -use miden_protocol::utils::DeserializationError; +use miden_protocol::utils::serde::DeserializationError; use miden_standards::account::faucets::FungibleFaucetError; use miden_standards::account::wallets::BasicWalletError; diff --git a/crates/store/src/genesis/config/mod.rs b/crates/store/src/genesis/config/mod.rs index f2cfe40b8f..93b137ea81 100644 --- a/crates/store/src/genesis/config/mod.rs +++ b/crates/store/src/genesis/config/mod.rs @@ -23,9 +23,9 @@ use miden_protocol::account::{ }; use miden_protocol::asset::{FungibleAsset, TokenSymbol}; use miden_protocol::block::FeeParameters; -use miden_protocol::crypto::dsa::falcon512_rpo::SecretKey as RpoSecretKey; +use miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey as RpoSecretKey; use miden_protocol::errors::TokenSymbolError; -use miden_protocol::{Felt, FieldElement, ONE}; +use miden_protocol::{Felt, ONE}; use miden_standards::AuthMethod; use miden_standards::account::auth::AuthSingleSig; use miden_standards::account::faucets::{BasicFungibleFaucet, TokenMetadata}; @@ -222,7 +222,7 @@ impl GenesisConfig { let mut rng = ChaCha20Rng::from_seed(rand::random()); let secret_key = RpoSecretKey::with_rng(&mut get_rpo_random_coin(&mut rng)); let auth = AuthMethod::SingleSig { - approver: (secret_key.public_key().into(), AuthScheme::Falcon512Rpo), + approver: (secret_key.public_key().into(), AuthScheme::Falcon512Poseidon2), }; let init_seed: [u8; 32] = rng.random(); @@ -311,7 +311,7 @@ impl GenesisConfig { // sanity check the total issuance against let basic = BasicFungibleFaucet::try_from(&faucet_account)?; - let max_supply = basic.max_supply().inner(); + let max_supply = basic.max_supply().as_canonical_u64(); if max_supply < total_issuance { return Err(GenesisConfigError::MaxIssuanceExceeded { max_supply, @@ -431,7 +431,8 @@ impl FungibleFaucetConfig { } = self; let mut rng = ChaCha20Rng::from_seed(rand::random()); let secret_key = RpoSecretKey::with_rng(&mut get_rpo_random_coin(&mut rng)); - let auth = AuthSingleSig::new(secret_key.public_key().into(), AuthScheme::Falcon512Rpo); + let auth = + AuthSingleSig::new(secret_key.public_key().into(), AuthScheme::Falcon512Poseidon2); let init_seed: [u8; 32] = rng.random(); let max_supply = Felt::try_from(max_supply) @@ -535,8 +536,10 @@ impl AccountSecrets { let account = account_lut .get(&account_id) .ok_or(GenesisConfigError::MissingGenesisAccount { account_id })?; - let account_file = - AccountFile::new(account.clone(), vec![AuthSecretKey::Falcon512Rpo(secret_key)]); + let account_file = AccountFile::new( + account.clone(), + vec![AuthSecretKey::Falcon512Poseidon2(secret_key)], + ); Ok(AccountFileWithName { name, account_file }) }) } diff --git a/crates/store/src/genesis/config/samples/02-with-account-files/agglayer_faucet_eth.mac b/crates/store/src/genesis/config/samples/02-with-account-files/agglayer_faucet_eth.mac index b76116b5740b069ba4065aaaef0fccbc60a84fe2..5e4c51cdfc6ca528e2fd106225908c04fda0d889 100644 GIT binary patch literal 11846 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 diff --git a/crates/store/src/genesis/config/samples/02-with-account-files/agglayer_faucet_usdc.mac b/crates/store/src/genesis/config/samples/02-with-account-files/agglayer_faucet_usdc.mac index 8e0c2650be4dcbad07a83758a16ffcd3b1b78ebd..263adbaae03b8ca0b3280f1909f055bc73dbba8c 100644 GIT binary patch literal 11846 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 literal 19129 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 diff --git a/crates/store/src/genesis/config/tests.rs b/crates/store/src/genesis/config/tests.rs index 0e02125cbf..2b27f3726f 100644 --- a/crates/store/src/genesis/config/tests.rs +++ b/crates/store/src/genesis/config/tests.rs @@ -96,11 +96,11 @@ fn parsing_account_from_file() -> TestResult { // Create a test wallet account and save it to a .mac file let init_seed: [u8; 32] = rand::random(); let mut rng = rand_chacha::ChaCha20Rng::from_seed(rand::random()); - let secret_key = miden_protocol::crypto::dsa::falcon512_rpo::SecretKey::with_rng( + let secret_key = miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey::with_rng( &mut miden_node_utils::crypto::get_rpo_random_coin(&mut rng), ); let auth = AuthMethod::SingleSig { - approver: (secret_key.public_key().into(), AuthScheme::Falcon512Rpo), + approver: (secret_key.public_key().into(), AuthScheme::Falcon512Poseidon2), }; let test_account = create_basic_wallet( @@ -154,10 +154,10 @@ fn parsing_native_faucet_from_file() -> TestResult { // Create a faucet account and save it to a .mac file let init_seed: [u8; 32] = rand::random(); let mut rng = rand_chacha::ChaCha20Rng::from_seed(rand::random()); - let secret_key = miden_protocol::crypto::dsa::falcon512_rpo::SecretKey::with_rng( + let secret_key = miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey::with_rng( &mut miden_node_utils::crypto::get_rpo_random_coin(&mut rng), ); - let auth = AuthSingleSig::new(secret_key.public_key().into(), AuthScheme::Falcon512Rpo); + let auth = AuthSingleSig::new(secret_key.public_key().into(), AuthScheme::Falcon512Poseidon2); let faucet_component = BasicFungibleFaucet::new(TokenSymbol::new("MIDEN").unwrap(), 6, Felt::new(1_000_000_000))?; @@ -216,11 +216,11 @@ fn native_faucet_from_file_must_be_faucet_type() -> TestResult { // Create a regular wallet account (not a faucet) and try to use it as native faucet let init_seed: [u8; 32] = rand::random(); let mut rng = rand_chacha::ChaCha20Rng::from_seed(rand::random()); - let secret_key = miden_protocol::crypto::dsa::falcon512_rpo::SecretKey::with_rng( + let secret_key = miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey::with_rng( &mut miden_node_utils::crypto::get_rpo_random_coin(&mut rng), ); let auth = AuthMethod::SingleSig { - approver: (secret_key.public_key().into(), AuthScheme::Falcon512Rpo), + approver: (secret_key.public_key().into(), AuthScheme::Falcon512Poseidon2), }; let regular_account = create_basic_wallet( diff --git a/crates/store/src/genesis/mod.rs b/crates/store/src/genesis/mod.rs index 2feea38ccf..f0f4541c40 100644 --- a/crates/store/src/genesis/mod.rs +++ b/crates/store/src/genesis/mod.rs @@ -2,7 +2,7 @@ use miden_node_utils::signer::BlockSigner; use miden_protocol::Word; use miden_protocol::account::delta::AccountUpdateDetails; use miden_protocol::account::{Account, AccountDelta}; -use miden_protocol::block::account_tree::{AccountTree, account_id_to_smt_key}; +use miden_protocol::block::account_tree::{AccountIdKey, AccountTree}; use miden_protocol::block::{ BlockAccountUpdate, BlockBody, @@ -89,7 +89,10 @@ impl GenesisState { // Convert account updates to SMT entries using account_id_to_smt_key let smt_entries = accounts.iter().map(|update| { - (account_id_to_smt_key(update.account_id()), update.final_state_commitment()) + ( + AccountIdKey::from(update.account_id()).as_word(), + update.final_state_commitment(), + ) }); // Create LargeSmt with MemoryStorage diff --git a/crates/store/src/server/api.rs b/crates/store/src/server/api.rs index 56bfcafb49..25ac5537ae 100644 --- a/crates/store/src/server/api.rs +++ b/crates/store/src/server/api.rs @@ -42,8 +42,8 @@ impl StoreApi { Ok(Response::new(proto::rpc::BlockHeaderByNumberResponse { block_header: block_header.map(Into::into), - chain_length: mmr_proof.as_ref().map(|p| p.forest.num_leaves() as u32), - mmr_path: mmr_proof.map(|p| Into::into(&p.merkle_path)), + chain_length: mmr_proof.as_ref().map(|p| p.forest().num_leaves() as u32), + mmr_path: mmr_proof.map(|p| Into::into(p.merkle_path())), })) } diff --git a/crates/store/src/server/block_producer.rs b/crates/store/src/server/block_producer.rs index 25f6b05f60..92b3652cd8 100644 --- a/crates/store/src/server/block_producer.rs +++ b/crates/store/src/server/block_producer.rs @@ -11,7 +11,7 @@ use miden_node_utils::tracing::OpenTelemetrySpanExt; use miden_protocol::Word; use miden_protocol::batch::OrderedBatches; use miden_protocol::block::{BlockBody, BlockHeader, BlockNumber, SignedBlock}; -use miden_protocol::utils::Deserializable; +use miden_protocol::utils::serde::Deserializable; use tonic::{Request, Response, Status}; use tracing::Instrument; diff --git a/crates/store/src/server/ntx_builder.rs b/crates/store/src/server/ntx_builder.rs index f6e8d4a7a5..4c6251d131 100644 --- a/crates/store/src/server/ntx_builder.rs +++ b/crates/store/src/server/ntx_builder.rs @@ -3,6 +3,7 @@ use std::num::{NonZero, TryFromIntError}; use miden_crypto::merkle::smt::SmtProof; use miden_node_proto::domain::account::AccountInfo; +use miden_node_proto::errors::ConversionError; use miden_node_proto::generated as proto; use miden_node_proto::generated::rpc::BlockRange; use miden_node_proto::generated::store::ntx_builder_server; @@ -216,7 +217,11 @@ impl ntx_builder_server::NtxBuilder for StoreApi { .map(|key_digest| { let word = read_root::(Some(key_digest), "VaultKey") .map_err(invalid_argument)?; - Ok(AssetVaultKey::new_unchecked(word)) + AssetVaultKey::try_from(word).map_err(|e| { + invalid_argument(GetWitnessesError::DeserializationFailed( + ConversionError::from(e), + )) + }) }) .collect::, Status>>()?; diff --git a/crates/store/src/server/rpc_api.rs b/crates/store/src/server/rpc_api.rs index a12fcafae7..2e70876826 100644 --- a/crates/store/src/server/rpc_api.rs +++ b/crates/store/src/server/rpc_api.rs @@ -148,7 +148,7 @@ impl rpc_server::Rpc for StoreApi { block_num: last_block_included.as_u32(), }), block_header: Some(state.block_header.into()), - mmr_path: Some(mmr_proof.merkle_path.into()), + mmr_path: Some(mmr_proof.merkle_path().clone().into()), notes, })) } diff --git a/crates/store/src/state/apply_block.rs b/crates/store/src/state/apply_block.rs index 7949fcbeb6..43d3d406a5 100644 --- a/crates/store/src/state/apply_block.rs +++ b/crates/store/src/state/apply_block.rs @@ -5,7 +5,7 @@ use miden_protocol::account::delta::AccountUpdateDetails; use miden_protocol::block::SignedBlock; use miden_protocol::note::NoteDetails; use miden_protocol::transaction::OutputNote; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use tokio::sync::oneshot; use tracing::{Instrument, info, info_span, instrument}; @@ -179,15 +179,10 @@ impl State { .output_notes() .map(|(note_index, note)| { let (details, nullifier) = match note { - OutputNote::Full(note) => { - (Some(NoteDetails::from(note)), Some(note.nullifier())) - }, - OutputNote::Header(_) => (None, None), - note @ OutputNote::Partial(_) => { - return Err(InvalidBlockError::InvalidOutputNoteType(Box::new( - note.clone(), - ))); + OutputNote::Public(note) => { + (Some(NoteDetails::from(note.as_note())), Some(note.as_note().nullifier())) }, + OutputNote::Private(_) => (None, None), }; let inclusion_path = note_tree.open(note_index); @@ -196,7 +191,7 @@ impl State { block_num, note_index, note_id: note.id().as_word(), - note_commitment: note.commitment(), + note_commitment: note.to_commitment(), metadata: note.metadata().clone(), details, inclusion_path, diff --git a/crates/store/src/state/loader.rs b/crates/store/src/state/loader.rs index d632a1c0c4..cebe410ff9 100644 --- a/crates/store/src/state/loader.rs +++ b/crates/store/src/state/loader.rs @@ -15,13 +15,13 @@ use std::path::Path; use miden_crypto::merkle::mmr::Mmr; #[cfg(feature = "rocksdb")] use miden_large_smt_backend_rocksdb::{RocksDbConfig, RocksDbStorage}; -use miden_protocol::block::account_tree::{AccountTree, account_id_to_smt_key}; +use miden_protocol::block::account_tree::{AccountIdKey, AccountTree}; use miden_protocol::block::nullifier_tree::NullifierTree; use miden_protocol::block::{BlockNumber, Blockchain}; #[cfg(not(feature = "rocksdb"))] use miden_protocol::crypto::merkle::smt::MemoryStorage; use miden_protocol::crypto::merkle::smt::{LargeSmt, LargeSmtError, SmtStorage}; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Felt, Word}; #[cfg(feature = "rocksdb")] use tracing::info; use tracing::instrument; @@ -75,6 +75,14 @@ pub fn account_tree_large_smt_error_to_init_error(e: LargeSmtError) -> StateInit LargeSmtError::Storage(err) => { StateInitializationError::AccountTreeIoError(err.as_report()) }, + LargeSmtError::RootMismatch { expected, actual } => { + StateInitializationError::AccountTreeIoError(format!( + "root mismatch: expected {expected:?}, got {actual:?}" + )) + }, + LargeSmtError::StorageNotEmpty => { + StateInitializationError::AccountTreeIoError("storage is not empty".to_string()) + }, } } @@ -146,7 +154,7 @@ impl StorageLoader for MemoryStorage { let entries = page .commitments .into_iter() - .map(|(id, commitment)| (account_id_to_smt_key(id), commitment)); + .map(|(id, commitment)| (AccountIdKey::from(id).as_word(), commitment)); let mutations = smt .compute_mutations(entries) @@ -251,7 +259,7 @@ impl StorageLoader for RocksDbStorage { let entries = page .commitments .into_iter() - .map(|(id, commitment)| (account_id_to_smt_key(id), commitment)); + .map(|(id, commitment)| (AccountIdKey::from(id).as_word(), commitment)); let mutations = smt .compute_mutations(entries) diff --git a/crates/validator/src/db/mod.rs b/crates/validator/src/db/mod.rs index 4c8fe665be..70fa432b3b 100644 --- a/crates/validator/src/db/mod.rs +++ b/crates/validator/src/db/mod.rs @@ -9,7 +9,7 @@ use diesel::dsl::exists; use diesel::prelude::*; use miden_node_db::{DatabaseError, Db}; use miden_protocol::transaction::TransactionId; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use tracing::instrument; use crate::COMPONENT; diff --git a/crates/validator/src/db/models.rs b/crates/validator/src/db/models.rs index cb41197b77..0b1e1825c5 100644 --- a/crates/validator/src/db/models.rs +++ b/crates/validator/src/db/models.rs @@ -1,6 +1,6 @@ use diesel::prelude::*; use miden_node_db::SqlTypeConvert; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use crate::db::schema; use crate::tx_validation::ValidatedTransaction; diff --git a/crates/validator/src/server/mod.rs b/crates/validator/src/server/mod.rs index bd636bc95e..359d338bfb 100644 --- a/crates/validator/src/server/mod.rs +++ b/crates/validator/src/server/mod.rs @@ -14,7 +14,7 @@ use miden_node_utils::tracing::OpenTelemetrySpanExt; use miden_node_utils::tracing::grpc::grpc_trace_fn; use miden_protocol::block::ProposedBlock; use miden_protocol::transaction::{ProvenTransaction, TransactionInputs}; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use tokio::net::TcpListener; use tokio_stream::wrappers::TcpListenerStream; use tonic::Status; diff --git a/crates/validator/src/signers/kms.rs b/crates/validator/src/signers/kms.rs index d6bd285679..01aa7d7898 100644 --- a/crates/validator/src/signers/kms.rs +++ b/crates/validator/src/signers/kms.rs @@ -5,7 +5,7 @@ use miden_node_utils::signer::BlockSigner; use miden_protocol::block::BlockHeader; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::{PublicKey, Signature}; use miden_protocol::crypto::hash::keccak::Keccak256; -use miden_tx::utils::{DeserializationError, Serializable}; +use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; // KMS SIGNER ERROR // ================================================================================================ @@ -70,8 +70,10 @@ impl KmsSigner { let pub_key_output = client.get_public_key().key_id(key_id.clone()).send().await?; let spki_der = pub_key_output.public_key().ok_or(KmsSignerError::EmptyBlob)?.as_ref(); - // Decode the compressed SPKI as a Miden public key. - let pub_key = PublicKey::from_der(spki_der)?; + // Extract the raw SEC1 public key bytes from the SPKI DER encoding and decode as a + // Miden public key. + let sec1_bytes = extract_sec1_from_spki_der(spki_der)?; + let pub_key = PublicKey::read_from_bytes(sec1_bytes)?; Ok(Self { key_id, pub_key, client }) } } @@ -105,7 +107,9 @@ impl BlockSigner for KmsSigner { let sig_der = sign_output.signature().ok_or(KmsSignerError::EmptyBlob)?; // Recovery id is not used by verify(pk), so 0 is fine. let recovery_id = 0; - let sig = Signature::from_der(sig_der.as_ref(), recovery_id) + let sig_bytes = parse_der_ecdsa_signature(sig_der.as_ref()) + .map_err(KmsSignerError::SignatureFormatError)?; + let sig = Signature::from_sec1_bytes_and_recovery_id(sig_bytes, recovery_id) .map_err(KmsSignerError::SignatureFormatError)?; // Check the returned signature. @@ -120,3 +124,137 @@ impl BlockSigner for KmsSigner { self.pub_key.clone() } } + +// HELPERS +// ================================================================================================ + +/// Extracts the raw SEC1 public key bytes from a DER-encoded `SubjectPublicKeyInfo` (SPKI) +/// structure. +/// +/// SPKI DER layout: +/// SEQUENCE { +/// SEQUENCE { algorithm OID, parameters } +/// BIT STRING { 0x00 (unused bits), } +/// } +fn extract_sec1_from_spki_der(der: &[u8]) -> Result<&[u8], DeserializationError> { + // Skip the outer SEQUENCE tag + length. + let rest = skip_der_tag_and_length(der, 0x30)?; + // Skip the inner SEQUENCE (algorithm identifier) tag + length + content. + let rest = skip_der_tlv(rest, 0x30)?; + // Parse the BIT STRING. + let content = read_der_content(rest, 0x03)?; + // The first byte of BIT STRING content is the "unused bits" count (must be 0 for keys). + if content.is_empty() || content[0] != 0 { + return Err(DeserializationError::InvalidValue( + "Invalid SPKI BIT STRING padding".to_string(), + )); + } + Ok(&content[1..]) +} + +/// Parses a DER-encoded ECDSA signature (ASN.1: SEQUENCE { INTEGER r, INTEGER s }) into a +/// 64-byte r||s array. +fn parse_der_ecdsa_signature(der: &[u8]) -> Result<[u8; 64], DeserializationError> { + let rest = skip_der_tag_and_length(der, 0x30)?; + let (r_bytes, rest) = read_der_integer(rest)?; + let (s_bytes, _) = read_der_integer(rest)?; + + let mut out = [0u8; 64]; + copy_integer_to_fixed(r_bytes, &mut out[..32])?; + copy_integer_to_fixed(s_bytes, &mut out[32..])?; + Ok(out) +} + +/// Copies a variable-length big-endian integer into a fixed-size buffer, right-aligned. +/// Strips leading zero padding if present. +fn copy_integer_to_fixed(src: &[u8], dst: &mut [u8]) -> Result<(), DeserializationError> { + // Strip leading zeros. + let src = match src.iter().position(|&b| b != 0) { + Some(pos) => &src[pos..], + None => &[0], + }; + if src.len() > dst.len() { + return Err(DeserializationError::InvalidValue( + "DER integer too large for target".to_string(), + )); + } + let offset = dst.len() - src.len(); + dst[offset..].copy_from_slice(src); + Ok(()) +} + +/// Skips a DER tag byte and its length field, returning the content slice. +fn skip_der_tag_and_length(data: &[u8], expected_tag: u8) -> Result<&[u8], DeserializationError> { + if data.is_empty() || data[0] != expected_tag { + return Err(DeserializationError::InvalidValue(format!( + "Expected DER tag 0x{expected_tag:02x}, got 0x{:02x}", + data.first().copied().unwrap_or(0) + ))); + } + let (_, rest) = read_der_length(&data[1..])?; + Ok(rest) +} + +/// Skips an entire DER TLV (tag + length + value), returning the remaining data after it. +fn skip_der_tlv(data: &[u8], expected_tag: u8) -> Result<&[u8], DeserializationError> { + if data.is_empty() || data[0] != expected_tag { + return Err(DeserializationError::InvalidValue(format!( + "Expected DER tag 0x{expected_tag:02x}, got 0x{:02x}", + data.first().copied().unwrap_or(0) + ))); + } + let (len, rest) = read_der_length(&data[1..])?; + if rest.len() < len { + return Err(DeserializationError::InvalidValue("DER content truncated".to_string())); + } + Ok(&rest[len..]) +} + +/// Reads a DER element's content bytes given its expected tag. +fn read_der_content(data: &[u8], expected_tag: u8) -> Result<&[u8], DeserializationError> { + if data.is_empty() || data[0] != expected_tag { + return Err(DeserializationError::InvalidValue(format!( + "Expected DER tag 0x{expected_tag:02x}, got 0x{:02x}", + data.first().copied().unwrap_or(0) + ))); + } + let (len, rest) = read_der_length(&data[1..])?; + if rest.len() < len { + return Err(DeserializationError::InvalidValue("DER content truncated".to_string())); + } + Ok(&rest[..len]) +} + +/// Reads a DER INTEGER element, returning (value bytes, remaining data). +fn read_der_integer(data: &[u8]) -> Result<(&[u8], &[u8]), DeserializationError> { + if data.is_empty() || data[0] != 0x02 { + return Err(DeserializationError::InvalidValue("Expected DER INTEGER tag".to_string())); + } + let (len, rest) = read_der_length(&data[1..])?; + if rest.len() < len { + return Err(DeserializationError::InvalidValue("DER INTEGER truncated".to_string())); + } + Ok((&rest[..len], &rest[len..])) +} + +/// Reads a DER length field, returning (length value, remaining data after length). +fn read_der_length(data: &[u8]) -> Result<(usize, &[u8]), DeserializationError> { + if data.is_empty() { + return Err(DeserializationError::InvalidValue("DER length missing".to_string())); + } + if data[0] < 0x80 { + Ok((data[0] as usize, &data[1..])) + } else { + let num_bytes = (data[0] & 0x7f) as usize; + if num_bytes == 0 || num_bytes > 4 || data.len() < 1 + num_bytes { + return Err(DeserializationError::InvalidValue( + "Invalid DER length encoding".to_string(), + )); + } + let mut len = 0usize; + for &b in &data[1..=num_bytes] { + len = (len << 8) | b as usize; + } + Ok((len, &data[1 + num_bytes..])) + } +} diff --git a/crates/validator/src/tx_validation/validated_tx.rs b/crates/validator/src/tx_validation/validated_tx.rs index 0233c7e8f3..301ac2be28 100644 --- a/crates/validator/src/tx_validation/validated_tx.rs +++ b/crates/validator/src/tx_validation/validated_tx.rs @@ -6,7 +6,7 @@ use miden_protocol::transaction::{ ExecutedTransaction, InputNote, InputNotes, - OutputNotes, + RawOutputNotes, TransactionId, }; @@ -49,7 +49,7 @@ impl ValidatedTransaction { } /// Returns the notes created in this transaction. - pub fn output_notes(&self) -> &OutputNotes { + pub fn output_notes(&self) -> &RawOutputNotes { self.0.output_notes() } diff --git a/proto/proto/types/primitives.proto b/proto/proto/types/primitives.proto index 3c8d279b02..a0c30b812a 100644 --- a/proto/proto/types/primitives.proto +++ b/proto/proto/types/primitives.proto @@ -5,8 +5,10 @@ package primitives; // ================================================================================================ message Asset { - // Asset represented as a word. - primitives.Digest asset = 1; + // Asset vault key represented as a word. + primitives.Digest key = 1; + // Asset value represented as a word. + primitives.Digest value = 2; } // SMT (Sparse Merkle Tree) From bc85d59b94d42f01a652a0508a529d53fb720fc1 Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Wed, 11 Mar 2026 17:12:35 -0300 Subject: [PATCH 02/19] chore: block_on --- bin/remote-prover/src/server/prover.rs | 54 ++++++++++++++----------- bin/remote-prover/src/server/service.rs | 9 +---- crates/rpc/src/server/api.rs | 12 +++--- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/bin/remote-prover/src/server/prover.rs b/bin/remote-prover/src/server/prover.rs index 587d8571ca..2931cc70fe 100644 --- a/bin/remote-prover/src/server/prover.rs +++ b/bin/remote-prover/src/server/prover.rs @@ -8,7 +8,7 @@ use miden_protocol::block::BlockProof; use miden_protocol::transaction::{ProvenTransaction, TransactionInputs}; use miden_tx::LocalTransactionProver; use miden_tx_batch_prover::LocalBatchProver; -use tracing::instrument; +use tracing::{Instrument, instrument}; use crate::COMPONENT; use crate::generated::{self as proto}; @@ -33,11 +33,11 @@ impl Prover { /// Proves a [`proto::ProofRequest`] using the appropriate prover implementation as specified /// during construction. - pub fn prove(&self, request: proto::ProofRequest) -> Result { + pub async fn prove(&self, request: proto::ProofRequest) -> Result { match self { - Prover::Transaction(prover) => prover.prove_request(request), - Prover::Batch(prover) => prover.prove_request(request), - Prover::Block(prover) => prover.prove_request(request), + Prover::Transaction(prover) => prover.prove_request(request).await, + Prover::Batch(prover) => prover.prove_request(request).await, + Prover::Block(prover) => prover.prove_request(request).await, } } } @@ -51,25 +51,30 @@ impl Prover { /// /// Implementations of this trait only need to provide the input and outputs types, as well as the /// proof implementation. -trait ProveRequest { - type Input: miden_protocol::utils::serde::Deserializable; - type Output: miden_protocol::utils::serde::Serializable; +#[async_trait::async_trait] +trait ProveRequest: Send + Sync { + type Input: miden_protocol::utils::serde::Deserializable + Send; + type Output: miden_protocol::utils::serde::Serializable + Send; - fn prove(&self, input: Self::Input) -> Result; + async fn prove(&self, input: Self::Input) -> Result; /// Entry-point to the proof request handling. /// /// Decodes the request, proves it, and encodes the response. - fn prove_request(&self, request: proto::ProofRequest) -> Result { - Self::decode_request(request) - .and_then(|input| { - // We cannot #[instrument] the trait's prove method because it lacks an - // implementation, so we do it manually. - tracing::info_span!("prove", target = COMPONENT).in_scope(|| { - self.prove(input).inspect_err(|e| tracing::Span::current().set_error(e)) - }) - }) - .map(|output| Self::encode_response(output)) + async fn prove_request( + &self, + request: proto::ProofRequest, + ) -> Result { + let input = Self::decode_request(request)?; + + let prove_span = tracing::info_span!("prove", target = COMPONENT); + let result = self.prove(input).instrument(prove_span).await; + + if let Err(e) = &result { + tracing::Span::current().set_error(e); + } + + result.map(|output| Self::encode_response(output)) } #[instrument(target=COMPONENT, skip_all, err)] @@ -89,32 +94,35 @@ trait ProveRequest { } } +#[async_trait::async_trait] impl ProveRequest for LocalTransactionProver { type Input = TransactionInputs; type Output = ProvenTransaction; - fn prove(&self, input: Self::Input) -> Result { - tokio::runtime::Handle::current().block_on(self.prove(input)).map_err(|e| { + async fn prove(&self, input: Self::Input) -> Result { + LocalTransactionProver::prove(self, input).await.map_err(|e| { tonic::Status::internal(e.as_report_context("failed to prove transaction")) }) } } +#[async_trait::async_trait] impl ProveRequest for LocalBatchProver { type Input = ProposedBatch; type Output = ProvenBatch; - fn prove(&self, input: Self::Input) -> Result { + async fn prove(&self, input: Self::Input) -> Result { self.prove(input) .map_err(|e| tonic::Status::internal(e.as_report_context("failed to prove batch"))) } } +#[async_trait::async_trait] impl ProveRequest for LocalBlockProver { type Input = BlockProofRequest; type Output = BlockProof; - fn prove(&self, input: Self::Input) -> Result { + async fn prove(&self, input: Self::Input) -> Result { let BlockProofRequest { tx_batches, block_header, block_inputs } = input; self.prove(tx_batches, &block_header, block_inputs) .map_err(|e| tonic::Status::internal(e.as_report_context("failed to prove block"))) diff --git a/bin/remote-prover/src/server/service.rs b/bin/remote-prover/src/server/service.rs index 4a72147a65..0658336625 100644 --- a/bin/remote-prover/src/server/service.rs +++ b/bin/remote-prover/src/server/service.rs @@ -76,13 +76,6 @@ impl proto::api_server::Api for ProverService { // This mutex is fair and uses FIFO ordering. let prover = self.acquire_prover().await; - // Blocking in place is fairly safe since we guarantee that only a single request is - // processed at a time. - // - // This has the downside that requests being proven cannot be cancelled since we are now - // outside the async runtime. This could occur if the server timeout is exceeded, or - // the client cancels the request. A different approach is technically possible, but - // would require more complex logic to handle cancellation in tandem with sync. - tokio::task::block_in_place(|| prover.prove(request)).map(tonic::Response::new) + prover.prove(request).await.map(tonic::Response::new) } } diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index 8b58a67c5d..f7125fce60 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -540,11 +540,13 @@ fn endpoint_limits(params: &[(&str, usize)]) -> proto::rpc::EndpointLimits { /// Cached RPC query parameter limits. static RPC_LIMITS: LazyLock = LazyLock::new(|| { - use QueryParamAccountIdLimit as AccountId; - use QueryParamNoteIdLimit as NoteId; - use QueryParamNoteTagLimit as NoteTag; - use QueryParamNullifierLimit as Nullifier; - use QueryParamStorageMapKeyTotalLimit as StorageMapKeyTotal; + use { + QueryParamAccountIdLimit as AccountId, + QueryParamNoteIdLimit as NoteId, + QueryParamNoteTagLimit as NoteTag, + QueryParamNullifierLimit as Nullifier, + QueryParamStorageMapKeyTotalLimit as StorageMapKeyTotal, + }; proto::rpc::RpcLimits { endpoints: std::collections::HashMap::from([ From 765169bf31045a766b00b12f2b27cf65566d849c Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Wed, 11 Mar 2026 18:06:25 -0300 Subject: [PATCH 03/19] chore: patch crypto until a 0.22.x release is done --- Cargo.lock | 16 ++++++---------- Cargo.toml | 5 +++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd8824b1fe..55d4876775 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2804,8 +2804,7 @@ dependencies = [ [[package]] name = "miden-crypto" version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8fc3ec2033d3e17a40611f3ab7c20b0578ccf5e6ddcc9a1df9f26599e6ebdd" +source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" dependencies = [ "blake3", "cc", @@ -2853,8 +2852,7 @@ dependencies = [ [[package]] name = "miden-crypto-derive" version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "207828f24e358b4e1e0641c37802816b8730816ff92ddb4d271ef3a00f8696bb" +source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" dependencies = [ "quote", "syn 2.0.114", @@ -2881,8 +2879,7 @@ dependencies = [ [[package]] name = "miden-field" version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f821a07c16cfa6e500d5a56d05c11523984e3cd562cfc80ef657e4264d708067" +source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" dependencies = [ "miden-serde-utils", "num-bigint", @@ -3439,8 +3436,7 @@ dependencies = [ [[package]] name = "miden-serde-utils" version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe74c2e7d8a8b8758e067de10665816928222c1d0561d95c12ac4bcaefc2a2a" +source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" dependencies = [ "p3-field", "p3-goldilocks", @@ -4552,7 +4548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" dependencies = [ "heck", - "itertools 0.14.0", + "itertools 0.13.0", "log", "multimap", "once_cell", @@ -4574,7 +4570,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.13.0", "proc-macro2", "quote", "syn 2.0.114", diff --git a/Cargo.toml b/Cargo.toml index 1dabe05c65..5e429dd940 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,6 +141,11 @@ needless_for_each = "allow" # Context dependent if that's useful. should_panic_without_expect = "allow" # We don't care about the specific panic message. # End of pedantic lints. +# TODO: Remove this patch once miden-crypto 0.22.5 is released. +# Fixes missing re-exports of StorageError and SubtreeUpdate from miden_crypto::merkle::smt. +[patch.crates-io] +miden-crypto = { branch = "version/0.22.x", git = "https://github.com/0xMiden/crypto" } + # Configure `cargo-typos` [workspace.metadata.typos] files.extend-exclude = ["*.svg"] # Ignore SVG files. From 44d5214c9463b049553b88ddb4f1be3edd5e2d15 Mon Sep 17 00:00:00 2001 From: Marti Date: Thu, 12 Mar 2026 10:27:22 +0000 Subject: [PATCH 04/19] chore: update to crypto v0.22.5 --- Cargo.lock | 20 ++++++++++++-------- Cargo.toml | 5 ----- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55d4876775..99498ae62d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2803,8 +2803,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.22.4" -source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e66531081b0cee8b83d5eacc4e557b36b94de9ba844c69f0266b97fc815a4f80" dependencies = [ "blake3", "cc", @@ -2851,8 +2852,9 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.22.4" -source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a799510573ae17ddaf33edf0043a5ba9dda69d344869ff9e223fe7240560b437" dependencies = [ "quote", "syn 2.0.114", @@ -2878,8 +2880,9 @@ dependencies = [ [[package]] name = "miden-field" -version = "0.22.4" -source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb022648eff894a7e26a3ae1f24f799c7159d9effcabda3f99402d53d66fdb0" dependencies = [ "miden-serde-utils", "num-bigint", @@ -3435,8 +3438,9 @@ dependencies = [ [[package]] name = "miden-serde-utils" -version = "0.22.4" -source = "git+https://github.com/0xMiden/crypto?branch=version%2F0.22.x#dfce24b13e46a599e6d3b5789e9ad929b7e69b30" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a536748c9e0348f9c5e88b19c2e993f196303a55fdabbde0eab1f6fd40830f4a" dependencies = [ "p3-field", "p3-goldilocks", diff --git a/Cargo.toml b/Cargo.toml index 5e429dd940..1dabe05c65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,11 +141,6 @@ needless_for_each = "allow" # Context dependent if that's useful. should_panic_without_expect = "allow" # We don't care about the specific panic message. # End of pedantic lints. -# TODO: Remove this patch once miden-crypto 0.22.5 is released. -# Fixes missing re-exports of StorageError and SubtreeUpdate from miden_crypto::merkle::smt. -[patch.crates-io] -miden-crypto = { branch = "version/0.22.x", git = "https://github.com/0xMiden/crypto" } - # Configure `cargo-typos` [workspace.metadata.typos] files.extend-exclude = ["*.svg"] # Ignore SVG files. From 5320e577cc60cb088ce10345cb8c63da0c337dfd Mon Sep 17 00:00:00 2001 From: Marti Date: Thu, 12 Mar 2026 10:27:49 +0000 Subject: [PATCH 05/19] chore: fmt --- crates/rpc/src/server/api.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index f7125fce60..8b58a67c5d 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -540,13 +540,11 @@ fn endpoint_limits(params: &[(&str, usize)]) -> proto::rpc::EndpointLimits { /// Cached RPC query parameter limits. static RPC_LIMITS: LazyLock = LazyLock::new(|| { - use { - QueryParamAccountIdLimit as AccountId, - QueryParamNoteIdLimit as NoteId, - QueryParamNoteTagLimit as NoteTag, - QueryParamNullifierLimit as Nullifier, - QueryParamStorageMapKeyTotalLimit as StorageMapKeyTotal, - }; + use QueryParamAccountIdLimit as AccountId; + use QueryParamNoteIdLimit as NoteId; + use QueryParamNoteTagLimit as NoteTag; + use QueryParamNullifierLimit as Nullifier; + use QueryParamStorageMapKeyTotalLimit as StorageMapKeyTotal; proto::rpc::RpcLimits { endpoints: std::collections::HashMap::from([ From 8bb975e3f0b4fa8db837e6e5b70f3485f6622462 Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Thu, 12 Mar 2026 13:39:40 +0000 Subject: [PATCH 06/19] fix: account state forest pruning and LargeSmt loading - Use LargeSmt::load() instead of LargeSmt::new() in load_smt to support loading from non-empty RocksDB storage on restart (new() now errors with StorageNotEmpty in miden-crypto 0.22) - Fix prune logic to remove all versions before cutoff while keeping at least one version per lineage to preserve current state - Only pop roots from SmtForest that are no longer referenced by any lineage (prevents removing shared roots) - Fix test helpers tree_id_for_root/tree_id_for_vault_root to use get_root_at_block instead of latest_root - Update all prune test assertions for the new version-tracking model (our AccountStateForest uses explicit version entries rather than LargeSmtForest's deduplicated tree count) --- crates/store/src/account_state_forest/mod.rs | 41 +++++-- .../store/src/account_state_forest/tests.rs | 105 +++++++++++++----- crates/store/src/db/tests.rs | 23 ++-- crates/store/src/state/loader.rs | 2 +- 4 files changed, 123 insertions(+), 48 deletions(-) diff --git a/crates/store/src/account_state_forest/mod.rs b/crates/store/src/account_state_forest/mod.rs index b00f31bb04..7211e06c82 100644 --- a/crates/store/src/account_state_forest/mod.rs +++ b/crates/store/src/account_state_forest/mod.rs @@ -98,20 +98,20 @@ impl AccountStateForest { &self, account_id: AccountId, slot_name: &StorageSlotName, - _block_num: BlockNumber, + block_num: BlockNumber, ) -> Option { let lineage = Self::storage_lineage_id(account_id, slot_name); - self.latest_root(lineage) + self.get_root_at_block(lineage, block_num) } #[cfg(test)] fn tree_id_for_vault_root( &self, account_id: AccountId, - _block_num: BlockNumber, + block_num: BlockNumber, ) -> Option { let lineage = Self::vault_lineage_id(account_id); - self.latest_root(lineage) + self.get_root_at_block(lineage, block_num) } fn storage_lineage_id(account_id: AccountId, slot_name: &StorageSlotName) -> LineageId { @@ -646,12 +646,20 @@ impl AccountStateForest { let mut roots_to_prune = Vec::new(); for versions in self.lineage_versions.values_mut() { - // Keep only versions after the cutoff. We need at least one version (the latest - // at or before cutoff) to serve as the base state. - let split_idx = - versions.partition_point(|(v, _)| *v < cutoff_version).saturating_sub(1); - if split_idx > 0 { - let removed: Vec<_> = versions.drain(..split_idx).collect(); + // Remove all versions strictly before the cutoff, but always keep at least one + // version (the latest at or before cutoff) so the lineage's current state is + // preserved. + let split_idx = versions.partition_point(|(v, _)| *v < cutoff_version); + + // If all versions are before the cutoff, keep the last one as the current state. + let drain_end = if split_idx >= versions.len() { + split_idx.saturating_sub(1) + } else { + split_idx + }; + + if drain_end > 0 { + let removed: Vec<_> = versions.drain(..drain_end).collect(); for (_, root) in &removed { roots_to_prune.push(*root); } @@ -659,8 +667,17 @@ impl AccountStateForest { } } - // Remove old roots from the SmtForest to free memory. - self.forest.pop_smts(roots_to_prune); + // Collect all roots still in use across all lineages. + let active_roots: BTreeSet = self + .lineage_versions + .values() + .flat_map(|versions| versions.iter().map(|(_, root)| *root)) + .collect(); + + // Only pop roots that are no longer referenced by any lineage. + let orphaned_roots: Vec = + roots_to_prune.into_iter().filter(|r| !active_roots.contains(r)).collect(); + self.forest.pop_smts(orphaned_roots); pruned_count } diff --git a/crates/store/src/account_state_forest/tests.rs b/crates/store/src/account_state_forest/tests.rs index daaff21c58..24f9b4bd28 100644 --- a/crates/store/src/account_state_forest/tests.rs +++ b/crates/store/src/account_state_forest/tests.rs @@ -349,11 +349,14 @@ fn vault_shared_root_retained_when_one_entry_pruned() { forest.update_account(block_at_51, &delta_2_update).unwrap(); let block_at_52 = BlockNumber::from(HISTORICAL_BLOCK_RETENTION + 2); - let total_roots_removed = forest.prune(block_at_52); + let total_versions_removed = forest.prune(block_at_52); - assert_eq!(total_roots_removed, 0); + // cutoff = 52 - 50 = 2. account2's version 1 is pruned (it also has version 51 >= cutoff). + // account1's version 1 is its only version, so it's retained. + assert_eq!(total_versions_removed, 1); assert!(forest.get_vault_root(account1, block_1).is_some()); - assert!(forest.get_vault_root(account2, block_1).is_some()); + // account2's version 1 was pruned; earliest remaining is version 51. + assert!(forest.get_vault_root(account2, block_1).is_none()); let vault_root_at_52 = forest.get_vault_root(account1, block_at_52); assert_eq!(vault_root_at_52, Some(root1)); @@ -691,8 +694,10 @@ fn prune_removes_smt_roots_from_forest() { let retained_block = BlockNumber::from(TEST_PRUNE_CHAIN_TIP); let pruned_block = BlockNumber::from(3u32); - let total_roots_removed = forest.prune(retained_block); - assert_eq!(total_roots_removed, 0); + let total_versions_removed = forest.prune(retained_block); + // cutoff = 55 - 50 = 5. Vault versions 1..=4 pruned (4 entries), storage version 3 pruned + // (1 entry). + assert_eq!(total_versions_removed, 5); assert!(forest.get_vault_root(account_id, retained_block).is_some()); assert!(forest.get_vault_root(account_id, pruned_block).is_none()); assert!(forest.get_storage_map_root(account_id, &slot_name, pruned_block).is_none()); @@ -730,10 +735,17 @@ fn prune_respects_retention_boundary() { forest.update_account(block_num, &delta).unwrap(); } - let total_roots_removed = forest.prune(BlockNumber::from(HISTORICAL_BLOCK_RETENTION)); + let total_versions_removed = forest.prune(BlockNumber::from(HISTORICAL_BLOCK_RETENTION)); - assert_eq!(total_roots_removed, 0); - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 11); + // cutoff = HISTORICAL_BLOCK_RETENTION - HISTORICAL_BLOCK_RETENTION = GENESIS, + // so nothing should be pruned (all versions are within retention). + assert_eq!(total_versions_removed, 0); + + // 1 lineage * HISTORICAL_BLOCK_RETENTION versions = 50 versions total. + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + HISTORICAL_BLOCK_RETENTION as usize + ); } #[test] @@ -763,13 +775,24 @@ fn prune_roots_removes_old_entries() { forest.update_account(block_num, &delta).unwrap(); } - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); + // 2 lineages (vault + storage) * 100 blocks = 200 version entries. + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + 2 * TEST_CHAIN_LENGTH as usize + ); - let total_roots_removed = forest.prune(BlockNumber::from(TEST_CHAIN_LENGTH)); + let total_versions_removed = forest.prune(BlockNumber::from(TEST_CHAIN_LENGTH)); - assert_eq!(total_roots_removed, 0); + // cutoff = 100 - 50 = 50. All versions strictly before 50 are removed per lineage. + let expected_removed_per_lineage = + (TEST_CHAIN_LENGTH - HISTORICAL_BLOCK_RETENTION) as usize - 1; + assert_eq!(total_versions_removed, 2 * expected_removed_per_lineage); - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); + let expected_remaining_per_lineage = TEST_CHAIN_LENGTH as usize - expected_removed_per_lineage; + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + 2 * expected_remaining_per_lineage + ); } #[test] @@ -794,15 +817,24 @@ fn prune_handles_multiple_accounts() { forest.update_account(block_num, &delta2).unwrap(); } - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); + // 2 accounts with 1 vault lineage each * 100 blocks = 200 version entries. + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + 2 * TEST_CHAIN_LENGTH as usize + ); - let total_roots_removed = forest.prune(BlockNumber::from(TEST_CHAIN_LENGTH)); + let total_versions_removed = forest.prune(BlockNumber::from(TEST_CHAIN_LENGTH)); - let expected_removed_per_account = (TEST_CHAIN_LENGTH - HISTORICAL_BLOCK_RETENTION) as usize; - assert_eq!(total_roots_removed, 0); - assert!(total_roots_removed <= expected_removed_per_account * 2); + // cutoff = 100 - 50 = 50. All versions strictly before 50 are removed per lineage. + let expected_removed_per_lineage = + (TEST_CHAIN_LENGTH - HISTORICAL_BLOCK_RETENTION) as usize - 1; + assert_eq!(total_versions_removed, 2 * expected_removed_per_lineage); - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); + let expected_remaining_per_lineage = TEST_CHAIN_LENGTH as usize - expected_removed_per_lineage; + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + 2 * expected_remaining_per_lineage + ); } #[test] @@ -831,14 +863,25 @@ fn prune_handles_multiple_slots() { forest.update_account(block_num, &delta).unwrap(); } - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); + // 2 lineages (slot_a + slot_b) * 100 blocks = 200 version entries. + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + 2 * TEST_CHAIN_LENGTH as usize + ); let chain_tip = BlockNumber::from(TEST_CHAIN_LENGTH); - let total_roots_removed = forest.prune(chain_tip); + let total_versions_removed = forest.prune(chain_tip); - assert_eq!(total_roots_removed, 0); + // cutoff = 100 - 50 = 50. All versions strictly before 50 are removed per lineage. + let expected_removed_per_lineage = + (TEST_CHAIN_LENGTH - HISTORICAL_BLOCK_RETENTION) as usize - 1; + assert_eq!(total_versions_removed, 2 * expected_removed_per_lineage); - assert_eq!(forest.lineage_versions.values().map(Vec::len).sum::(), 22); + let expected_remaining_per_lineage = TEST_CHAIN_LENGTH as usize - expected_removed_per_lineage; + assert_eq!( + forest.lineage_versions.values().map(Vec::len).sum::(), + 2 * expected_remaining_per_lineage + ); } #[test] @@ -887,15 +930,25 @@ fn prune_preserves_most_recent_state_per_entity() { dummy_partial_delta(account_id, AccountVaultDelta::default(), storage_delta_at_51); forest.update_account(block_at_51, &delta_at_51).unwrap(); - // Block 100: Prune + // Block 100: Prune (cutoff = 50) let block_100 = BlockNumber::from(100); - let total_roots_removed = forest.prune(block_100); + let total_versions_removed = forest.prune(block_100); - assert_eq!(total_roots_removed, 0); + // map_a has version 1 pruned (version 51 is >= cutoff), vault and map_b keep their only + // version (1) since it's the latest for those lineages. + assert_eq!(total_versions_removed, 1); + // map_a at block 51 still accessible. assert!(forest.get_storage_map_root(account_id, &slot_map_a, block_at_51).is_some()); - assert!(forest.get_storage_map_root(account_id, &slot_map_a, block_1).is_some()); + + // map_a at block 1 is no longer accessible (version 1 was pruned, earliest is 51). + assert!(forest.get_storage_map_root(account_id, &slot_map_a, block_1).is_none()); + + // map_b at block 1 still accessible (only version, retained as latest). assert!(forest.get_storage_map_root(account_id, &slot_map_b, block_1).is_some()); + + // vault at block 1 still accessible (only version, retained as latest). + assert!(forest.get_vault_root(account_id, block_1).is_some()); } #[test] diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index ebd071f7f4..bfd2685c9a 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -2974,8 +2974,10 @@ fn account_state_forest_shared_roots_not_deleted_prematurely() { forest.update_account(block53, &delta1_update).unwrap(); // Prune at block 53 + // cutoff = 53 - 50 = 3: each of the 3 lineages has one version < 3 that gets removed + // (account1 v=1, account2 v=2, account3 v=2), since each also has a newer version. let total_roots_removed = forest.prune(block53); - assert_eq!(total_roots_removed, 0); + assert_eq!(total_roots_removed, 3); // Account2 and Account3 should still be accessible at their recent blocks let account1_root = forest.get_storage_map_root(account1, &slot_name, block53).unwrap(); @@ -3095,9 +3097,11 @@ fn account_state_forest_retains_latest_after_100_blocks_and_pruning() { forest.update_account(block_51, &delta_51).unwrap(); // Prune again at block 100 + // cutoff = 50: both vault and storage lineages have v=1 (< 50) and v=51, so v=1 is pruned + // from each lineage, totaling 2 version entries removed. let total_roots_removed = forest.prune(block_100); - assert_eq!(total_roots_removed, 0); + assert_eq!(total_roots_removed, 2); let vault_root_at_51 = forest .get_vault_root(account_id, block_51) @@ -3119,8 +3123,9 @@ fn account_state_forest_retains_latest_after_100_blocks_and_pruning() { "Witness must verify against storage root" ); + // After pruning, the v=1 entry was removed so querying at block_1 returns None. let vault_root_at_1 = forest.get_vault_root(account_id, block_1); - assert!(vault_root_at_1.is_some()); + assert!(vault_root_at_1.is_none(), "Block 1 vault entry was pruned"); } #[test] @@ -3426,10 +3431,10 @@ fn account_state_forest_preserves_mixed_slots_independently() { // Vault: block 1 is most recent, should NOT be pruned // Map A: block 1 is old (block 51 is newer), SHOULD be pruned // Map B: block 1 is most recent, should NOT be pruned - assert_eq!( - total_roots_removed, 0, - "Vault root from block 1 should NOT be pruned (most recent)" - ); + // Vault: block 1 is the only version, kept (all versions before cutoff case). + // Map A: has v=1 and v=51; v=1 < cutoff=50, so 1 version entry removed. + // Map B: block 1 is the only version, kept. + assert_eq!(total_roots_removed, 1, "Only map_a's block 1 version entry should be pruned"); // Verify vault is still accessible let vault_root_at_1 = @@ -3454,7 +3459,7 @@ fn account_state_forest_preserves_mixed_slots_independently() { "Map B should still be from block 1 (most recent)" ); - // Verify map_a block 1 is no longer accessible + // Verify map_a block 1 is no longer accessible (it was pruned) let map_a_root_at_1 = forest.get_storage_map_root(account_id, &slot_map_a, block_1); - assert!(map_a_root_at_1.is_some(), "Map A block 1 should be pruned"); + assert!(map_a_root_at_1.is_none(), "Map A block 1 should be pruned"); } diff --git a/crates/store/src/state/loader.rs b/crates/store/src/state/loader.rs index cebe410ff9..7ab8c028c7 100644 --- a/crates/store/src/state/loader.rs +++ b/crates/store/src/state/loader.rs @@ -329,7 +329,7 @@ impl StorageLoader for RocksDbStorage { /// Loads an SMT from persistent storage. #[cfg(feature = "rocksdb")] pub fn load_smt(storage: S) -> Result, StateInitializationError> { - LargeSmt::new(storage).map_err(account_tree_large_smt_error_to_init_error) + LargeSmt::load(storage).map_err(account_tree_large_smt_error_to_init_error) } // TREE LOADING FUNCTIONS From fe275f321c4fb6e17c64906411ad041b28ad968b Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Thu, 12 Mar 2026 13:55:24 +0000 Subject: [PATCH 07/19] refactor: simplify KMS signer DER parsing with spki and k256 crates Replace ~130 lines of hand-rolled DER parsing with proper library calls: - Use spki::SubjectPublicKeyInfoRef::from_der() for SPKI public key parsing - Use k256::ecdsa::Signature::from_der() for DER signature decoding This restores the simplicity of the original code before the migration, where PublicKey::from_der() and Signature::from_der() were available directly on the miden-crypto types. --- Cargo.lock | 2 + crates/validator/Cargo.toml | 2 + crates/validator/src/signers/kms.rs | 155 +++------------------------- 3 files changed, 17 insertions(+), 142 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a4c032442..41f0d6f98e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3287,12 +3287,14 @@ dependencies = [ "build-rs", "diesel", "diesel_migrations", + "k256", "miden-node-db", "miden-node-proto", "miden-node-proto-build", "miden-node-utils", "miden-protocol", "miden-tx", + "spki", "thiserror 2.0.18", "tokio", "tokio-stream", diff --git a/crates/validator/Cargo.toml b/crates/validator/Cargo.toml index 84ed6b2484..cdc3e97e08 100644 --- a/crates/validator/Cargo.toml +++ b/crates/validator/Cargo.toml @@ -22,12 +22,14 @@ aws-config = { version = "1.8.14" } aws-sdk-kms = { version = "1.100" } diesel = { workspace = true } diesel_migrations = { workspace = true } +k256 = { features = ["ecdsa"], version = "0.13" } miden-node-db = { workspace = true } miden-node-proto = { workspace = true } miden-node-proto-build = { features = ["internal"], workspace = true } miden-node-utils = { features = ["testing"], workspace = true } miden-protocol = { workspace = true } miden-tx = { workspace = true } +spki = { version = "0.7" } thiserror = { workspace = true } tokio = { features = ["macros", "net", "rt-multi-thread"], workspace = true } tokio-stream = { features = ["net"], workspace = true } diff --git a/crates/validator/src/signers/kms.rs b/crates/validator/src/signers/kms.rs index 01aa7d7898..990c25a669 100644 --- a/crates/validator/src/signers/kms.rs +++ b/crates/validator/src/signers/kms.rs @@ -6,6 +6,7 @@ use miden_protocol::block::BlockHeader; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::{PublicKey, Signature}; use miden_protocol::crypto::hash::keccak::Keccak256; use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; +use spki::der::Decode; // KMS SIGNER ERROR // ================================================================================================ @@ -70,9 +71,13 @@ impl KmsSigner { let pub_key_output = client.get_public_key().key_id(key_id.clone()).send().await?; let spki_der = pub_key_output.public_key().ok_or(KmsSignerError::EmptyBlob)?.as_ref(); - // Extract the raw SEC1 public key bytes from the SPKI DER encoding and decode as a - // Miden public key. - let sec1_bytes = extract_sec1_from_spki_der(spki_der)?; + // Parse the SPKI DER to extract the raw SEC1 public key bytes. + let spki = spki::SubjectPublicKeyInfoRef::from_der(spki_der) + .map_err(|e| DeserializationError::InvalidValue(e.to_string()))?; + let sec1_bytes = spki + .subject_public_key + .as_bytes() + .ok_or_else(|| DeserializationError::InvalidValue("Invalid SPKI BIT STRING".into()))?; let pub_key = PublicKey::read_from_bytes(sec1_bytes)?; Ok(Self { key_id, pub_key, client }) } @@ -103,13 +108,13 @@ impl BlockSigner for KmsSigner { .map_err(Box::from) .map_err(KmsSignerError::KmsServiceError)?; - // Decode DER-encoded signature. + // Decode DER-encoded ECDSA signature into r||s bytes. let sig_der = sign_output.signature().ok_or(KmsSignerError::EmptyBlob)?; - // Recovery id is not used by verify(pk), so 0 is fine. - let recovery_id = 0; - let sig_bytes = parse_der_ecdsa_signature(sig_der.as_ref()) + let k256_sig = k256::ecdsa::Signature::from_der(sig_der.as_ref()) + .map_err(|e| DeserializationError::InvalidValue(e.to_string())) .map_err(KmsSignerError::SignatureFormatError)?; - let sig = Signature::from_sec1_bytes_and_recovery_id(sig_bytes, recovery_id) + // Recovery id is not used by verify(pk), so 0 is fine. + let sig = Signature::from_sec1_bytes_and_recovery_id(k256_sig.to_bytes().into(), 0) .map_err(KmsSignerError::SignatureFormatError)?; // Check the returned signature. @@ -124,137 +129,3 @@ impl BlockSigner for KmsSigner { self.pub_key.clone() } } - -// HELPERS -// ================================================================================================ - -/// Extracts the raw SEC1 public key bytes from a DER-encoded `SubjectPublicKeyInfo` (SPKI) -/// structure. -/// -/// SPKI DER layout: -/// SEQUENCE { -/// SEQUENCE { algorithm OID, parameters } -/// BIT STRING { 0x00 (unused bits), } -/// } -fn extract_sec1_from_spki_der(der: &[u8]) -> Result<&[u8], DeserializationError> { - // Skip the outer SEQUENCE tag + length. - let rest = skip_der_tag_and_length(der, 0x30)?; - // Skip the inner SEQUENCE (algorithm identifier) tag + length + content. - let rest = skip_der_tlv(rest, 0x30)?; - // Parse the BIT STRING. - let content = read_der_content(rest, 0x03)?; - // The first byte of BIT STRING content is the "unused bits" count (must be 0 for keys). - if content.is_empty() || content[0] != 0 { - return Err(DeserializationError::InvalidValue( - "Invalid SPKI BIT STRING padding".to_string(), - )); - } - Ok(&content[1..]) -} - -/// Parses a DER-encoded ECDSA signature (ASN.1: SEQUENCE { INTEGER r, INTEGER s }) into a -/// 64-byte r||s array. -fn parse_der_ecdsa_signature(der: &[u8]) -> Result<[u8; 64], DeserializationError> { - let rest = skip_der_tag_and_length(der, 0x30)?; - let (r_bytes, rest) = read_der_integer(rest)?; - let (s_bytes, _) = read_der_integer(rest)?; - - let mut out = [0u8; 64]; - copy_integer_to_fixed(r_bytes, &mut out[..32])?; - copy_integer_to_fixed(s_bytes, &mut out[32..])?; - Ok(out) -} - -/// Copies a variable-length big-endian integer into a fixed-size buffer, right-aligned. -/// Strips leading zero padding if present. -fn copy_integer_to_fixed(src: &[u8], dst: &mut [u8]) -> Result<(), DeserializationError> { - // Strip leading zeros. - let src = match src.iter().position(|&b| b != 0) { - Some(pos) => &src[pos..], - None => &[0], - }; - if src.len() > dst.len() { - return Err(DeserializationError::InvalidValue( - "DER integer too large for target".to_string(), - )); - } - let offset = dst.len() - src.len(); - dst[offset..].copy_from_slice(src); - Ok(()) -} - -/// Skips a DER tag byte and its length field, returning the content slice. -fn skip_der_tag_and_length(data: &[u8], expected_tag: u8) -> Result<&[u8], DeserializationError> { - if data.is_empty() || data[0] != expected_tag { - return Err(DeserializationError::InvalidValue(format!( - "Expected DER tag 0x{expected_tag:02x}, got 0x{:02x}", - data.first().copied().unwrap_or(0) - ))); - } - let (_, rest) = read_der_length(&data[1..])?; - Ok(rest) -} - -/// Skips an entire DER TLV (tag + length + value), returning the remaining data after it. -fn skip_der_tlv(data: &[u8], expected_tag: u8) -> Result<&[u8], DeserializationError> { - if data.is_empty() || data[0] != expected_tag { - return Err(DeserializationError::InvalidValue(format!( - "Expected DER tag 0x{expected_tag:02x}, got 0x{:02x}", - data.first().copied().unwrap_or(0) - ))); - } - let (len, rest) = read_der_length(&data[1..])?; - if rest.len() < len { - return Err(DeserializationError::InvalidValue("DER content truncated".to_string())); - } - Ok(&rest[len..]) -} - -/// Reads a DER element's content bytes given its expected tag. -fn read_der_content(data: &[u8], expected_tag: u8) -> Result<&[u8], DeserializationError> { - if data.is_empty() || data[0] != expected_tag { - return Err(DeserializationError::InvalidValue(format!( - "Expected DER tag 0x{expected_tag:02x}, got 0x{:02x}", - data.first().copied().unwrap_or(0) - ))); - } - let (len, rest) = read_der_length(&data[1..])?; - if rest.len() < len { - return Err(DeserializationError::InvalidValue("DER content truncated".to_string())); - } - Ok(&rest[..len]) -} - -/// Reads a DER INTEGER element, returning (value bytes, remaining data). -fn read_der_integer(data: &[u8]) -> Result<(&[u8], &[u8]), DeserializationError> { - if data.is_empty() || data[0] != 0x02 { - return Err(DeserializationError::InvalidValue("Expected DER INTEGER tag".to_string())); - } - let (len, rest) = read_der_length(&data[1..])?; - if rest.len() < len { - return Err(DeserializationError::InvalidValue("DER INTEGER truncated".to_string())); - } - Ok((&rest[..len], &rest[len..])) -} - -/// Reads a DER length field, returning (length value, remaining data after length). -fn read_der_length(data: &[u8]) -> Result<(usize, &[u8]), DeserializationError> { - if data.is_empty() { - return Err(DeserializationError::InvalidValue("DER length missing".to_string())); - } - if data[0] < 0x80 { - Ok((data[0] as usize, &data[1..])) - } else { - let num_bytes = (data[0] & 0x7f) as usize; - if num_bytes == 0 || num_bytes > 4 || data.len() < 1 + num_bytes { - return Err(DeserializationError::InvalidValue( - "Invalid DER length encoding".to_string(), - )); - } - let mut len = 0usize; - for &b in &data[1..=num_bytes] { - len = (len << 8) | b as usize; - } - Ok((len, &data[1 + num_bytes..])) - } -} From 57673610b53d913ec9dd8a0a499d6d1cbd80d6ac Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Thu, 12 Mar 2026 15:05:26 +0000 Subject: [PATCH 08/19] chore: import smt types from miden-protocol instead of miden-crypto Remove stale comment about missing re-exports (fixed in miden-crypto 0.22.5) and import from miden_protocol::crypto::merkle::smt to match the convention used on next. --- crates/large-smt-backend-rocksdb/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/large-smt-backend-rocksdb/src/lib.rs b/crates/large-smt-backend-rocksdb/src/lib.rs index 4cee18c8c9..563439c9f4 100644 --- a/crates/large-smt-backend-rocksdb/src/lib.rs +++ b/crates/large-smt-backend-rocksdb/src/lib.rs @@ -26,10 +26,8 @@ extern crate alloc; mod helpers; #[expect(clippy::doc_markdown, clippy::inline_always)] mod rocksdb; -// Re-export from miden-crypto's merkle::smt module. -// NOTE: StorageError and SubtreeUpdate were missing from the re-exports in miden-crypto 0.22.4 -// (fixed on miden-crypto main in commit c6b23f0). We import directly from miden-crypto here. -pub use miden_crypto::merkle::smt::{ +// Re-export from miden-protocol. +pub use miden_protocol::crypto::merkle::smt::{ InnerNode, LargeSmt, LargeSmtError, From 3528ad52887247e8eb21b53f5ed49f5fd26aa478 Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Thu, 12 Mar 2026 15:19:43 +0000 Subject: [PATCH 09/19] fix(stress-test): avoid account ID prefix collisions in seeding Public and private accounts were created with overlapping seed index ranges, which in the v0.14 beta can produce accounts with duplicate ID prefixes. Use separate non-overlapping index offsets for each storage mode within a block. --- bin/stress-test/src/seeding/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/stress-test/src/seeding/mod.rs b/bin/stress-test/src/seeding/mod.rs index d4cdaa9e4a..d3d3dff65c 100644 --- a/bin/stress-test/src/seeding/mod.rs +++ b/bin/stress-test/src/seeding/mod.rs @@ -176,23 +176,27 @@ async fn generate_blocks( let mut block_txs = Vec::with_capacity(BATCHES_PER_BLOCK * TRANSACTIONS_PER_BATCH); // create public accounts and notes that mint assets for these accounts + // Use separate index offsets for public and private accounts to avoid ID prefix + // collisions (different storage modes can produce the same prefix in v0.14). + let pub_offset = i * (num_public_accounts + num_private_accounts); let (pub_accounts, pub_notes) = create_accounts_and_notes( num_public_accounts, AccountStorageMode::Public, &key_pair, &rng, faucet.id(), - i, + pub_offset, ); // create private accounts and notes that mint assets for these accounts + let priv_offset = pub_offset + num_public_accounts; let (priv_accounts, priv_notes) = create_accounts_and_notes( num_private_accounts, AccountStorageMode::Private, &key_pair, &rng, faucet.id(), - i, + priv_offset, ); let notes = [pub_notes, priv_notes].concat(); @@ -291,14 +295,14 @@ fn create_accounts_and_notes( key_pair: &SecretKey, rng: &Arc>, faucet_id: AccountId, - block_num: usize, + index_offset: usize, ) -> (Vec, Vec) { (0..num_accounts) .into_par_iter() .map(|account_index| { let account = create_account( key_pair.public_key(), - ((block_num * num_accounts) + account_index) as u64, + (index_offset + account_index) as u64, storage_mode, ); let note = { From b57d7165866c77553ba1efd412200be90dfaa677 Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Thu, 12 Mar 2026 15:54:12 +0000 Subject: [PATCH 10/19] fix(stress-test): use high-entropy seeds for account creation The previous approach used low-entropy seeds (index padded with zeros) which could produce AccountId prefix collisions during the hash grinding process. Use a seeded PRNG to generate full 32-byte random seeds per account while maintaining deterministic behavior. --- bin/stress-test/src/seeding/mod.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/stress-test/src/seeding/mod.rs b/bin/stress-test/src/seeding/mod.rs index d3d3dff65c..5ae5fad065 100644 --- a/bin/stress-test/src/seeding/mod.rs +++ b/bin/stress-test/src/seeding/mod.rs @@ -54,7 +54,8 @@ use miden_standards::account::auth::AuthSingleSig; use miden_standards::account::faucets::BasicFungibleFaucet; use miden_standards::account::wallets::BasicWallet; use miden_standards::note::P2idNote; -use rand::Rng; +use rand::rngs::StdRng; +use rand::{Rng, SeedableRng}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::prelude::ParallelSlice; use tokio::io::AsyncWriteExt; @@ -329,11 +330,13 @@ fn create_note(faucet_id: AccountId, target_id: AccountId, rng: &mut RpoRandomCo .expect("note creation failed") } -/// Creates a new private account with a given public key and anchor block. Generates the seed from -/// the given index. +/// Creates a new account with a given public key. Uses a seeded PRNG derived from the index to +/// generate a high-entropy init seed, avoiding `AccountId` prefix collisions that can occur with +/// low-entropy seeds. fn create_account(public_key: PublicKey, index: u64, storage_mode: AccountStorageMode) -> Account { - let init_seed: Vec<_> = index.to_be_bytes().into_iter().chain([0u8; 24]).collect(); - AccountBuilder::new(init_seed.try_into().unwrap()) + let mut rng = StdRng::seed_from_u64(index); + let init_seed: [u8; 32] = rng.random(); + AccountBuilder::new(init_seed) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(storage_mode) .with_auth_component(AuthSingleSig::new(public_key.into(), AuthScheme::Falcon512Poseidon2)) From 916d06a38c8c278906de8d14edc17d8e1ede5785 Mon Sep 17 00:00:00 2001 From: "Claude (Opus)" Date: Thu, 12 Mar 2026 16:39:49 +0000 Subject: [PATCH 11/19] chore: address self review comments - Remove dead `Panic(JoinError)` variant from `NtxError` - Remove unused `get_root`/`set_root` and `ROOT_KEY` from `RocksDbStorage` - Replace verbose `std::iter::empty` with `Vec::new()` in rpc tests - Extract inline fee construction to `test_fee()` variable in store tests Co-Authored-By: Claude Opus 4.6 (1M context) --- .../large-smt-backend-rocksdb/src/rocksdb.rs | 39 ------------------- crates/ntx-builder/src/actor/execute.rs | 4 -- crates/rpc/src/tests.rs | 4 +- crates/store/src/db/tests.rs | 9 ++--- 4 files changed, 6 insertions(+), 50 deletions(-) diff --git a/crates/large-smt-backend-rocksdb/src/rocksdb.rs b/crates/large-smt-backend-rocksdb/src/rocksdb.rs index 4f0b93908d..b3afe5f164 100644 --- a/crates/large-smt-backend-rocksdb/src/rocksdb.rs +++ b/crates/large-smt-backend-rocksdb/src/rocksdb.rs @@ -44,8 +44,6 @@ const METADATA_CF: &str = "metadata"; /// rebuilding. const DEPTH_24_CF: &str = "depth24"; -/// The key used in the `METADATA_CF` column family to store the SMT's root hash. -const ROOT_KEY: &[u8] = b"smt_root"; /// The key used in the `METADATA_CF` column family to store the total count of non-empty leaves. const LEAF_COUNT_KEY: &[u8] = b"leaf_count"; /// The key used in the `METADATA_CF` column family to store the total count of key-value entries. @@ -261,43 +259,6 @@ impl RocksDbStorage { let name = cf_for_depth(index.depth()); self.cf_handle(name).expect("CF handle missing") } - - /// Retrieves the SMT root hash from the `METADATA_CF` column family. - /// - /// Note: In miden-crypto 0.22+, `get_root` is no longer part of the `SmtStorage` trait. - /// The root is managed in-memory by `LargeSmt`. This method is retained for backward - /// compatibility and direct database inspection. - /// - /// # Errors - /// - `StorageError::Backend`: If the metadata column family is missing or a RocksDB error - /// occurs. - /// - `StorageError::DeserializationError`: If the retrieved root hash bytes cannot be - /// deserialized. - pub fn get_root(&self) -> Result, StorageError> { - let cf = self.cf_handle(METADATA_CF)?; - match self.db.get_cf(cf, ROOT_KEY).map_err(map_rocksdb_err)? { - Some(bytes) => { - let digest = Word::read_from_bytes(&bytes)?; - Ok(Some(digest)) - }, - None => Ok(None), - } - } - - /// Stores the SMT root hash in the `METADATA_CF` column family. - /// - /// Note: In miden-crypto 0.22+, `set_root` is no longer part of the `SmtStorage` trait. - /// The root is managed in-memory by `LargeSmt`. This method is retained for backward - /// compatibility and direct database operations. - /// - /// # Errors - /// - `StorageError::Backend`: If the metadata column family is missing or a RocksDB error - /// occurs. - pub fn set_root(&self, root: Word) -> Result<(), StorageError> { - let cf = self.cf_handle(METADATA_CF)?; - self.db.put_cf(cf, ROOT_KEY, root.to_bytes()).map_err(map_rocksdb_err)?; - Ok(()) - } } impl SmtStorage for RocksDbStorage { diff --git a/crates/ntx-builder/src/actor/execute.rs b/crates/ntx-builder/src/actor/execute.rs index d21a62384c..e7e01f0de5 100644 --- a/crates/ntx-builder/src/actor/execute.rs +++ b/crates/ntx-builder/src/actor/execute.rs @@ -51,7 +51,6 @@ use miden_tx::{ TransactionProverError, }; use tokio::sync::Mutex; -use tokio::task::JoinError; use tracing::{Instrument, instrument}; use crate::COMPONENT; @@ -73,9 +72,6 @@ pub enum NtxError { Proving(#[source] TransactionProverError), #[error("failed to submit transaction")] Submission(#[source] tonic::Status), - #[error("the ntx task panicked")] - #[expect(dead_code)] - Panic(#[source] JoinError), } type NtxResult = Result; diff --git a/crates/rpc/src/tests.rs b/crates/rpc/src/tests.rs index 3ae4c85872..bd72cc1ba2 100644 --- a/crates/rpc/src/tests.rs +++ b/crates/rpc/src/tests.rs @@ -85,8 +85,8 @@ fn build_test_proven_tx(account: &Account, delta: &AccountDelta) -> ProvenTransa ProvenTransaction::new( account_update, - std::iter::empty::(), - std::iter::empty::(), + Vec::::new(), + Vec::::new(), 0.into(), Word::default(), test_fee(), diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index bfd2685c9a..5fc15c75f4 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -1354,21 +1354,21 @@ fn mock_block_transaction(account_id: AccountId, num: u64) -> TransactionHeader NoteMetadata::new(account_id, NoteType::Public).with_tag(NoteTag::new(num as u32)), )]; + let fee = test_fee(); TransactionHeader::new_unchecked( TransactionId::new( initial_state_commitment, final_account_commitment, input_notes_commitment, output_notes_commitment, - FungibleAsset::new(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET).unwrap(), 0) - .unwrap(), + fee, ), account_id, initial_state_commitment, final_account_commitment, input_notes, output_notes, - test_fee(), + fee, ) } @@ -1895,8 +1895,7 @@ fn serialization_symmetry_core_types() { num_to_word(2), num_to_word(3), num_to_word(4), - FungibleAsset::new(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET).unwrap(), 0) - .unwrap(), + test_fee(), ); let bytes = tx_id.to_bytes(); let restored = TransactionId::read_from_bytes(&bytes).unwrap(); From 0490027999b89f375883665b3700523a8a3215b9 Mon Sep 17 00:00:00 2001 From: Marti Date: Thu, 12 Mar 2026 17:02:14 +0000 Subject: [PATCH 12/19] chore: cleanup imports --- .../src/remote_prover/batch_prover.rs | 1 - .../src/remote_prover/block_prover.rs | 1 - .../remote-prover-client/src/remote_prover/tx_prover.rs | 1 - crates/rpc/src/server/api.rs | 9 ++++++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/remote-prover-client/src/remote_prover/batch_prover.rs b/crates/remote-prover-client/src/remote_prover/batch_prover.rs index dd9d4cab5b..c5c100f3e1 100644 --- a/crates/remote-prover-client/src/remote_prover/batch_prover.rs +++ b/crates/remote-prover-client/src/remote_prover/batch_prover.rs @@ -110,7 +110,6 @@ impl RemoteBatchProver { &self, proposed_batch: ProposedBatch, ) -> Result { - use miden_protocol::utils::serde::Serializable; self.connect().await?; let mut client = self diff --git a/crates/remote-prover-client/src/remote_prover/block_prover.rs b/crates/remote-prover-client/src/remote_prover/block_prover.rs index fff6bcc092..e59d605d74 100644 --- a/crates/remote-prover-client/src/remote_prover/block_prover.rs +++ b/crates/remote-prover-client/src/remote_prover/block_prover.rs @@ -108,7 +108,6 @@ impl RemoteBlockProver { block_header: &BlockHeader, block_inputs: BlockInputs, ) -> Result { - use miden_protocol::utils::serde::Serializable; self.connect().await?; let mut client = self diff --git a/crates/remote-prover-client/src/remote_prover/tx_prover.rs b/crates/remote-prover-client/src/remote_prover/tx_prover.rs index 360798b09f..be213904c2 100644 --- a/crates/remote-prover-client/src/remote_prover/tx_prover.rs +++ b/crates/remote-prover-client/src/remote_prover/tx_prover.rs @@ -107,7 +107,6 @@ impl RemoteTransactionProver { tx_inputs: &TransactionInputs, ) -> impl FutureMaybeSend> { async move { - use miden_protocol::utils::serde::Serializable; self.connect().await.map_err(|err| { TransactionProverError::other_with_source( "failed to connect to the remote prover", diff --git a/crates/rpc/src/server/api.rs b/crates/rpc/src/server/api.rs index 8b58a67c5d..cbd45855b2 100644 --- a/crates/rpc/src/server/api.rs +++ b/crates/rpc/src/server/api.rs @@ -19,7 +19,12 @@ use miden_node_utils::limiter::{ }; use miden_protocol::batch::ProvenBatch; use miden_protocol::block::{BlockHeader, BlockNumber}; -use miden_protocol::transaction::{OutputNote, ProvenTransaction, TxAccountUpdate}; +use miden_protocol::transaction::{ + OutputNote, + ProvenTransaction, + PublicOutputNote, + TxAccountUpdate, +}; use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_protocol::{MIN_PROOF_SECURITY_LEVEL, Word}; use miden_tx::TransactionVerifier; @@ -505,8 +510,6 @@ impl api_server::Api for RpcService { fn strip_output_note_decorators<'a>( notes: impl Iterator + 'a, ) -> impl Iterator + 'a { - use miden_protocol::transaction::PublicOutputNote; - notes.map(|note| match note { OutputNote::Public(public_note) => { // Reconstruct via PublicOutputNote::new which calls minify_script() internally. From 99c7134c222be7a842b3b886a16745b61994575f Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Thu, 12 Mar 2026 16:23:02 -0300 Subject: [PATCH 13/19] test: single source of randomness --- bin/stress-test/src/main.rs | 3 ++- bin/stress-test/src/seeding/mod.rs | 31 ++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/bin/stress-test/src/main.rs b/bin/stress-test/src/main.rs index a5cc82f9f4..6839b417b4 100644 --- a/bin/stress-test/src/main.rs +++ b/bin/stress-test/src/main.rs @@ -104,7 +104,8 @@ async fn main() { num_accounts, public_accounts_percentage, } => { - seed_store(data_directory, num_accounts, public_accounts_percentage).await; + let seed: u64 = rand::random(); + seed_store(data_directory, num_accounts, public_accounts_percentage, seed).await; }, Command::BenchmarkStore { endpoint, diff --git a/bin/stress-test/src/seeding/mod.rs b/bin/stress-test/src/seeding/mod.rs index c0e5ddb4a4..c0692042f8 100644 --- a/bin/stress-test/src/seeding/mod.rs +++ b/bin/stress-test/src/seeding/mod.rs @@ -79,13 +79,19 @@ pub const ACCOUNTS_FILENAME: &str = "accounts.txt"; // ================================================================================================ /// Seeds the store with a given number of accounts. +/// +/// All randomness is derived from the provided `seed`, making runs fully reproducible. pub async fn seed_store( data_directory: PathBuf, num_accounts: usize, public_accounts_percentage: u8, + seed: u64, ) { let start = Instant::now(); + // Derive all randomness from a single master RNG seeded by the user-provided seed. + let mut master_rng = StdRng::seed_from_u64(seed); + // Recreate the data directory (it should be empty for store bootstrapping). // // Ignore the error since it will also error if it does not exist. @@ -93,10 +99,11 @@ pub async fn seed_store( fs_err::create_dir_all(&data_directory).expect("created data directory"); // generate the faucet account and the genesis state - let faucet = create_faucet(); + let faucet_coin_seed: [u64; 4] = master_rng.random(); + let faucet = create_faucet(faucet_coin_seed); let fee_params = FeeParameters::new(faucet.id(), 0).unwrap(); - let signer = EcdsaSecretKey::new(); - let genesis_state = GenesisState::new(vec![faucet.clone()], fee_params, 1, 1, signer); + let genesis_signer = EcdsaSecretKey::with_rng(&mut master_rng); + let genesis_state = GenesisState::new(vec![faucet.clone()], fee_params, 1, 1, genesis_signer); let genesis_block = genesis_state .clone() .into_block() @@ -108,6 +115,10 @@ pub async fn seed_store( let (_, store_url) = start_store(data_directory.clone()).await; let store_client = StoreClient::new(store_url); + // Derive remaining seeds from the master RNG. + let account_coin_seed: [u64; 4] = master_rng.random(); + let block_signer = EcdsaSecretKey::with_rng(&mut master_rng); + // start generating blocks let accounts_filepath = data_directory.join(ACCOUNTS_FILENAME); let data_directory = @@ -121,6 +132,8 @@ pub async fn seed_store( &store_client, data_directory, accounts_filepath, + account_coin_seed, + &block_signer, ) .await; @@ -140,6 +153,8 @@ async fn generate_blocks( store_client: &StoreClient, data_directory: DataDirectory, accounts_filepath: PathBuf, + coin_seed: [u64; 4], + block_signer: &EcdsaSecretKey, ) -> SeedingMetrics { // Each block is composed of [`BATCHES_PER_BLOCK`] batches, and each batch is composed of // [`TRANSACTIONS_PER_BATCH`] txs. The first note of the block is always a send assets tx @@ -163,7 +178,6 @@ async fn generate_blocks( let total_blocks = (num_accounts / consumes_per_block) + 1; // share random coin seed and key pair for all accounts to avoid key generation overhead - let coin_seed: [u64; 4] = rand::rng().random(); let rng = Arc::new(Mutex::new(RpoRandomCoin::new(coin_seed.map(Felt::new).into()))); let key_pair = { let mut rng = rng.lock().unwrap(); @@ -222,7 +236,8 @@ async fn generate_blocks( let block_inputs = get_block_inputs(store_client, &batches, &mut metrics).await; // update blocks - prev_block_header = apply_block(batches, block_inputs, store_client, &mut metrics).await; + prev_block_header = + apply_block(batches, block_inputs, store_client, block_signer, &mut metrics).await; if current_anchor_header.block_epoch() != prev_block_header.block_epoch() { current_anchor_header = prev_block_header.clone(); } @@ -256,12 +271,13 @@ async fn apply_block( batches: Vec, block_inputs: BlockInputs, store_client: &StoreClient, + signer: &EcdsaSecretKey, metrics: &mut SeedingMetrics, ) -> BlockHeader { let proposed_block = ProposedBlock::new(block_inputs, batches).unwrap(); let (header, body) = proposed_block.clone().into_header_and_body().unwrap(); let block_size: usize = header.to_bytes().len() + body.to_bytes().len(); - let signature = EcdsaSecretKey::new().sign(header.commitment()); + let signature = signer.sign(header.commitment()); // SAFETY: The header, body, and signature are known to correspond to each other. let signed_block = SignedBlock::new_unchecked(header, body, signature); let ordered_batches = proposed_block.batches().clone(); @@ -346,8 +362,7 @@ fn create_account(public_key: PublicKey, index: u64, storage_mode: AccountStorag } /// Creates a new faucet account. -fn create_faucet() -> Account { - let coin_seed: [u64; 4] = rand::rng().random(); +fn create_faucet(coin_seed: [u64; 4]) -> Account { let mut rng = RpoRandomCoin::new(coin_seed.map(Felt::new).into()); let key_pair = SecretKey::with_rng(&mut rng); let init_seed = [0_u8; 32]; From 9d5ff52b4fe4323187f251c1b0e779205bd1c5ee Mon Sep 17 00:00:00 2001 From: Marti Date: Fri, 13 Mar 2026 12:25:38 +0000 Subject: [PATCH 14/19] temp: use mmagician-0.22.6 branch --- Cargo.lock | 22 ++++++++-------------- Cargo.toml | 3 +++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17d96c737d..f747e1aa59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2803,9 +2803,8 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e66531081b0cee8b83d5eacc4e557b36b94de9ba844c69f0266b97fc815a4f80" +version = "0.22.6" +source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" dependencies = [ "blake3", "cc", @@ -2852,9 +2851,8 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a799510573ae17ddaf33edf0043a5ba9dda69d344869ff9e223fe7240560b437" +version = "0.22.6" +source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" dependencies = [ "quote", "syn 2.0.114", @@ -2880,9 +2878,8 @@ dependencies = [ [[package]] name = "miden-field" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb022648eff894a7e26a3ae1f24f799c7159d9effcabda3f99402d53d66fdb0" +version = "0.22.6" +source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" dependencies = [ "miden-serde-utils", "num-bigint", @@ -3288,14 +3285,12 @@ dependencies = [ "build-rs", "diesel", "diesel_migrations", - "k256", "miden-node-db", "miden-node-proto", "miden-node-proto-build", "miden-node-utils", "miden-protocol", "miden-tx", - "spki", "thiserror 2.0.18", "tokio", "tokio-stream", @@ -3442,9 +3437,8 @@ dependencies = [ [[package]] name = "miden-serde-utils" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a536748c9e0348f9c5e88b19c2e993f196303a55fdabbde0eab1f6fd40830f4a" +version = "0.22.6" +source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" dependencies = [ "p3-field", "p3-goldilocks", diff --git a/Cargo.toml b/Cargo.toml index 1dabe05c65..6d1d462394 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -144,3 +144,6 @@ should_panic_without_expect = "allow" # We don't care about the specific panic # Configure `cargo-typos` [workspace.metadata.typos] files.extend-exclude = ["*.svg"] # Ignore SVG files. + +[patch.crates-io] +miden-crypto = { branch = "mmagician-0.22.6", git = "https://github.com/0xMiden/crypto" } From f9d4412c67d7ad5528a18c3cb2ef0e5a1cf92490 Mon Sep 17 00:00:00 2001 From: Marti Date: Fri, 13 Mar 2026 12:26:00 +0000 Subject: [PATCH 15/19] chore: revert kms changes --- crates/validator/Cargo.toml | 2 -- crates/validator/src/signers/kms.rs | 21 ++++++--------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/crates/validator/Cargo.toml b/crates/validator/Cargo.toml index cdc3e97e08..84ed6b2484 100644 --- a/crates/validator/Cargo.toml +++ b/crates/validator/Cargo.toml @@ -22,14 +22,12 @@ aws-config = { version = "1.8.14" } aws-sdk-kms = { version = "1.100" } diesel = { workspace = true } diesel_migrations = { workspace = true } -k256 = { features = ["ecdsa"], version = "0.13" } miden-node-db = { workspace = true } miden-node-proto = { workspace = true } miden-node-proto-build = { features = ["internal"], workspace = true } miden-node-utils = { features = ["testing"], workspace = true } miden-protocol = { workspace = true } miden-tx = { workspace = true } -spki = { version = "0.7" } thiserror = { workspace = true } tokio = { features = ["macros", "net", "rt-multi-thread"], workspace = true } tokio-stream = { features = ["net"], workspace = true } diff --git a/crates/validator/src/signers/kms.rs b/crates/validator/src/signers/kms.rs index 990c25a669..e84576ac1e 100644 --- a/crates/validator/src/signers/kms.rs +++ b/crates/validator/src/signers/kms.rs @@ -5,8 +5,7 @@ use miden_node_utils::signer::BlockSigner; use miden_protocol::block::BlockHeader; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::{PublicKey, Signature}; use miden_protocol::crypto::hash::keccak::Keccak256; -use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable}; -use spki::der::Decode; +use miden_protocol::utils::serde::{DeserializationError, Serializable}; // KMS SIGNER ERROR // ================================================================================================ @@ -71,14 +70,8 @@ impl KmsSigner { let pub_key_output = client.get_public_key().key_id(key_id.clone()).send().await?; let spki_der = pub_key_output.public_key().ok_or(KmsSignerError::EmptyBlob)?.as_ref(); - // Parse the SPKI DER to extract the raw SEC1 public key bytes. - let spki = spki::SubjectPublicKeyInfoRef::from_der(spki_der) - .map_err(|e| DeserializationError::InvalidValue(e.to_string()))?; - let sec1_bytes = spki - .subject_public_key - .as_bytes() - .ok_or_else(|| DeserializationError::InvalidValue("Invalid SPKI BIT STRING".into()))?; - let pub_key = PublicKey::read_from_bytes(sec1_bytes)?; + // Decode the compressed SPKI as a Miden public key. + let pub_key = PublicKey::from_der(spki_der)?; Ok(Self { key_id, pub_key, client }) } } @@ -108,13 +101,11 @@ impl BlockSigner for KmsSigner { .map_err(Box::from) .map_err(KmsSignerError::KmsServiceError)?; - // Decode DER-encoded ECDSA signature into r||s bytes. + // Decode DER-encoded signature. let sig_der = sign_output.signature().ok_or(KmsSignerError::EmptyBlob)?; - let k256_sig = k256::ecdsa::Signature::from_der(sig_der.as_ref()) - .map_err(|e| DeserializationError::InvalidValue(e.to_string())) - .map_err(KmsSignerError::SignatureFormatError)?; // Recovery id is not used by verify(pk), so 0 is fine. - let sig = Signature::from_sec1_bytes_and_recovery_id(k256_sig.to_bytes().into(), 0) + let recovery_id = 0; + let sig = Signature::from_der(sig_der.as_ref(), recovery_id) .map_err(KmsSignerError::SignatureFormatError)?; // Check the returned signature. From c5c87b5a99d7bd118d396f4b4a69c9bc088e8687 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Fri, 13 Mar 2026 13:47:31 -0300 Subject: [PATCH 16/19] fix: remove middle step serialization for InputNoteCommitment --- crates/proto/src/domain/transaction.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/crates/proto/src/domain/transaction.rs b/crates/proto/src/domain/transaction.rs index ee7d24bf20..0da1a05762 100644 --- a/crates/proto/src/domain/transaction.rs +++ b/crates/proto/src/domain/transaction.rs @@ -1,7 +1,6 @@ use miden_protocol::Word; use miden_protocol::note::Nullifier; use miden_protocol::transaction::{InputNoteCommitment, TransactionId}; -use miden_protocol::utils::serde::{Deserializable, Serializable}; use crate::errors::{ConversionError, MissingFieldHelper}; use crate::generated as proto; @@ -85,13 +84,6 @@ impl TryFrom for InputNoteCommitment { let header: Option = value.header.map(TryInto::try_into).transpose()?; - // TODO: https://github.com/0xMiden/node/issues/1783 - // InputNoteCommitment has private fields, so we reconstruct it via - // serialization roundtrip using its Serializable/Deserializable impls. - let mut bytes = Vec::new(); - nullifier.write_into(&mut bytes); - header.write_into(&mut bytes); - InputNoteCommitment::read_from_bytes(&bytes) - .map_err(|err| ConversionError::deserialization_error("InputNoteCommitment", err)) + Ok(InputNoteCommitment::from_parts_unchecked(nullifier, header)) } } From 98497ba9a21a68f544fda4b10d954e4af267f7b5 Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Fri, 13 Mar 2026 15:20:38 -0300 Subject: [PATCH 17/19] chore: cargo lock --- Cargo.lock | 6 ++---- Cargo.toml | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f747e1aa59..972adbdde3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3322,8 +3322,7 @@ dependencies = [ [[package]] name = "miden-protocol" version = "0.14.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b41308a7d7c031a571f4ee7bfb1a0a25f6e2a1fe4378fe8d4c0bfd5fe4cf56" +source = "git+https://github.com/0xMiden/protocol?branch=igamigo-fix-partial-smt#ff82cb7e28d0de39bf8ca8daa2350b7516b0e7d9" dependencies = [ "bech32", "fs-err", @@ -3352,8 +3351,7 @@ dependencies = [ [[package]] name = "miden-protocol-macros" version = "0.14.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4626a7e06401a2eae244d4b480ff9fd3518c1f3d839781919e9fb6c635fe33" +source = "git+https://github.com/0xMiden/protocol?branch=igamigo-fix-partial-smt#ff82cb7e28d0de39bf8ca8daa2350b7516b0e7d9" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 6d1d462394..1a3487933e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -147,3 +147,4 @@ files.extend-exclude = ["*.svg"] # Ignore SVG files. [patch.crates-io] miden-crypto = { branch = "mmagician-0.22.6", git = "https://github.com/0xMiden/crypto" } +miden-protocol = { branch = "igamigo-fix-partial-smt", git = "https://github.com/0xMiden/protocol" } From 8079f1083b6be4e054a8ffc1928084e28d56a35c Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Fri, 13 Mar 2026 15:20:49 -0300 Subject: [PATCH 18/19] Revert "test: single source of randomness" This reverts commit 99c7134c222be7a842b3b886a16745b61994575f. --- bin/stress-test/src/main.rs | 3 +-- bin/stress-test/src/seeding/mod.rs | 31 ++++++++---------------------- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/bin/stress-test/src/main.rs b/bin/stress-test/src/main.rs index 6839b417b4..a5cc82f9f4 100644 --- a/bin/stress-test/src/main.rs +++ b/bin/stress-test/src/main.rs @@ -104,8 +104,7 @@ async fn main() { num_accounts, public_accounts_percentage, } => { - let seed: u64 = rand::random(); - seed_store(data_directory, num_accounts, public_accounts_percentage, seed).await; + seed_store(data_directory, num_accounts, public_accounts_percentage).await; }, Command::BenchmarkStore { endpoint, diff --git a/bin/stress-test/src/seeding/mod.rs b/bin/stress-test/src/seeding/mod.rs index c0692042f8..c0e5ddb4a4 100644 --- a/bin/stress-test/src/seeding/mod.rs +++ b/bin/stress-test/src/seeding/mod.rs @@ -79,19 +79,13 @@ pub const ACCOUNTS_FILENAME: &str = "accounts.txt"; // ================================================================================================ /// Seeds the store with a given number of accounts. -/// -/// All randomness is derived from the provided `seed`, making runs fully reproducible. pub async fn seed_store( data_directory: PathBuf, num_accounts: usize, public_accounts_percentage: u8, - seed: u64, ) { let start = Instant::now(); - // Derive all randomness from a single master RNG seeded by the user-provided seed. - let mut master_rng = StdRng::seed_from_u64(seed); - // Recreate the data directory (it should be empty for store bootstrapping). // // Ignore the error since it will also error if it does not exist. @@ -99,11 +93,10 @@ pub async fn seed_store( fs_err::create_dir_all(&data_directory).expect("created data directory"); // generate the faucet account and the genesis state - let faucet_coin_seed: [u64; 4] = master_rng.random(); - let faucet = create_faucet(faucet_coin_seed); + let faucet = create_faucet(); let fee_params = FeeParameters::new(faucet.id(), 0).unwrap(); - let genesis_signer = EcdsaSecretKey::with_rng(&mut master_rng); - let genesis_state = GenesisState::new(vec![faucet.clone()], fee_params, 1, 1, genesis_signer); + let signer = EcdsaSecretKey::new(); + let genesis_state = GenesisState::new(vec![faucet.clone()], fee_params, 1, 1, signer); let genesis_block = genesis_state .clone() .into_block() @@ -115,10 +108,6 @@ pub async fn seed_store( let (_, store_url) = start_store(data_directory.clone()).await; let store_client = StoreClient::new(store_url); - // Derive remaining seeds from the master RNG. - let account_coin_seed: [u64; 4] = master_rng.random(); - let block_signer = EcdsaSecretKey::with_rng(&mut master_rng); - // start generating blocks let accounts_filepath = data_directory.join(ACCOUNTS_FILENAME); let data_directory = @@ -132,8 +121,6 @@ pub async fn seed_store( &store_client, data_directory, accounts_filepath, - account_coin_seed, - &block_signer, ) .await; @@ -153,8 +140,6 @@ async fn generate_blocks( store_client: &StoreClient, data_directory: DataDirectory, accounts_filepath: PathBuf, - coin_seed: [u64; 4], - block_signer: &EcdsaSecretKey, ) -> SeedingMetrics { // Each block is composed of [`BATCHES_PER_BLOCK`] batches, and each batch is composed of // [`TRANSACTIONS_PER_BATCH`] txs. The first note of the block is always a send assets tx @@ -178,6 +163,7 @@ async fn generate_blocks( let total_blocks = (num_accounts / consumes_per_block) + 1; // share random coin seed and key pair for all accounts to avoid key generation overhead + let coin_seed: [u64; 4] = rand::rng().random(); let rng = Arc::new(Mutex::new(RpoRandomCoin::new(coin_seed.map(Felt::new).into()))); let key_pair = { let mut rng = rng.lock().unwrap(); @@ -236,8 +222,7 @@ async fn generate_blocks( let block_inputs = get_block_inputs(store_client, &batches, &mut metrics).await; // update blocks - prev_block_header = - apply_block(batches, block_inputs, store_client, block_signer, &mut metrics).await; + prev_block_header = apply_block(batches, block_inputs, store_client, &mut metrics).await; if current_anchor_header.block_epoch() != prev_block_header.block_epoch() { current_anchor_header = prev_block_header.clone(); } @@ -271,13 +256,12 @@ async fn apply_block( batches: Vec, block_inputs: BlockInputs, store_client: &StoreClient, - signer: &EcdsaSecretKey, metrics: &mut SeedingMetrics, ) -> BlockHeader { let proposed_block = ProposedBlock::new(block_inputs, batches).unwrap(); let (header, body) = proposed_block.clone().into_header_and_body().unwrap(); let block_size: usize = header.to_bytes().len() + body.to_bytes().len(); - let signature = signer.sign(header.commitment()); + let signature = EcdsaSecretKey::new().sign(header.commitment()); // SAFETY: The header, body, and signature are known to correspond to each other. let signed_block = SignedBlock::new_unchecked(header, body, signature); let ordered_batches = proposed_block.batches().clone(); @@ -362,7 +346,8 @@ fn create_account(public_key: PublicKey, index: u64, storage_mode: AccountStorag } /// Creates a new faucet account. -fn create_faucet(coin_seed: [u64; 4]) -> Account { +fn create_faucet() -> Account { + let coin_seed: [u64; 4] = rand::rng().random(); let mut rng = RpoRandomCoin::new(coin_seed.map(Felt::new).into()); let key_pair = SecretKey::with_rng(&mut rng); let init_seed = [0_u8; 32]; From b6b3af017d92a63b49aa17a76d8c7e313d7c5bc5 Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Fri, 13 Mar 2026 15:24:01 -0300 Subject: [PATCH 19/19] chore: remove crypto patch --- Cargo.lock | 678 ++++++++++++++++++++++++++++------------------------- Cargo.toml | 1 - 2 files changed, 363 insertions(+), 316 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 972adbdde3..7505403463 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", - "anstyle-parse", + "anstyle-parse 0.2.7", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse 1.0.0", "anstyle-query", "anstyle-wincon", "colorchoice", @@ -96,6 +111,15 @@ dependencies = [ "utf8parse", ] +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + [[package]] name = "anstyle-query" version = "1.1.5" @@ -118,12 +142,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -dependencies = [ - "backtrace", -] +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arrayref" @@ -160,7 +181,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -177,9 +198,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.14" +version = "1.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8fc176d53d6fe85017f230405e3255cedb4a02221cb55ed6d76dccbbb099b2" +checksum = "11493b0bad143270fb8ad284a096dd529ba91924c5409adeac856cc1bf047dbc" dependencies = [ "aws-credential-types", "aws-runtime", @@ -197,7 +218,7 @@ dependencies = [ "fastrand", "hex", "http 1.4.0", - "ring", + "sha1", "time", "tokio", "tracing", @@ -207,9 +228,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.12" +version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e26bbf46abc608f2dc61fd6cb3b7b0665497cc259a21520151ed98f8b37d2c79" +checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -219,9 +240,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.15.4" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" +checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" dependencies = [ "aws-lc-sys", "zeroize", @@ -229,9 +250,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.37.1" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" +checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" dependencies = [ "cc", "cmake", @@ -241,9 +262,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.7.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f92058d22a46adf53ec57a6a96f34447daf02bff52e8fb956c66bcd5c6ac12" +checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -266,9 +287,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.100.0" +version = "1.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723700afe7459a33d1ac30852e9208b801946c032625cc8c808f57b9563bb5c7" +checksum = "8e6bfd8dfb5a562f9a605bbd5c3aef09db9231c826a1e0488ce3f4338c70dbbb" dependencies = [ "aws-credential-types", "aws-runtime", @@ -290,9 +311,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.94.0" +version = "1.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699da1961a289b23842d88fe2984c6ff68735fdf9bdcbc69ceaeb2491c9bf434" +checksum = "f64a6eded248c6b453966e915d32aeddb48ea63ad17932682774eb026fbef5b1" dependencies = [ "aws-credential-types", "aws-runtime", @@ -314,9 +335,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.96.0" +version = "1.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e3a4cb3b124833eafea9afd1a6cc5f8ddf3efefffc6651ef76a03cbc6b4981" +checksum = "db96d720d3c622fcbe08bae1c4b04a72ce6257d8b0584cb5418da00ae20a344f" dependencies = [ "aws-credential-types", "aws-runtime", @@ -338,9 +359,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.98.0" +version = "1.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c4f19655ab0856375e169865c91264de965bd74c407c7f1e403184b1049409" +checksum = "fafbdda43b93f57f699c5dfe8328db590b967b8a820a13ccdd6687355dfcc7ca" dependencies = [ "aws-credential-types", "aws-runtime", @@ -363,9 +384,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f6ae9b71597dc5fd115d52849d7a5556ad9265885ad3492ea8d73b93bbc46e" +checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" dependencies = [ "aws-credential-types", "aws-smithy-http", @@ -385,9 +406,9 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "1.2.12" +version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cba48474f1d6807384d06fec085b909f5807e16653c5af5c45dfe89539f0b70" +checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" dependencies = [ "futures-util", "pin-project-lite", @@ -396,9 +417,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.63.4" +version = "0.63.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4a8a5fe3e4ac7ee871237c340bbce13e982d37543b65700f4419e039f5d78e" +checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", @@ -417,9 +438,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.1.10" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0709f0083aa19b704132684bc26d3c868e06bd428ccc4373b0b55c3e8748a58b" +checksum = "6a2f165a7feee6f263028b899d0a181987f4fa7179a6411a32a439fba7c5f769" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -436,7 +457,7 @@ dependencies = [ "hyper-util", "pin-project-lite", "rustls 0.21.12", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -447,27 +468,27 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.62.4" +version = "0.62.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b3a779093e18cad88bbae08dc4261e1d95018c4c5b9356a52bcae7c0b6e9bb" +checksum = "9648b0bb82a2eedd844052c6ad2a1a822d1f8e3adee5fbf668366717e428856a" dependencies = [ "aws-smithy-types", ] [[package]] name = "aws-smithy-observability" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3f39d5bb871aaf461d59144557f16d5927a5248a983a40654d9cf3b9ba183b" +checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" dependencies = [ "aws-smithy-runtime-api", ] [[package]] name = "aws-smithy-query" -version = "0.60.14" +version = "0.60.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f76a580e3d8f8961e5d48763214025a2af65c2fa4cd1fb7f270a0e107a71b0" +checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" dependencies = [ "aws-smithy-types", "urlencoding", @@ -475,9 +496,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.10.1" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd3dfc18c1ce097cf81fced7192731e63809829c6cbf933c1ec47452d08e1aa" +checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -500,9 +521,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.11.4" +version = "1.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c55e0837e9b8526f49e0b9bfa9ee18ddee70e853f5bc09c5d11ebceddcb0fec" +checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -517,9 +538,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.4.4" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576b0d6991c9c32bc14fc340582ef148311f924d41815f641a308b5d11e8e7cd" +checksum = "d2b1117b3b2bbe166d11199b540ceed0d0f7676e36e7b962b5a437a9971eac75" dependencies = [ "base64-simd", "bytes", @@ -543,18 +564,18 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.60.14" +version = "0.60.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53543b4b86ed43f051644f704a98c7291b3618b67adf057ee77a366fa52fcaa" +checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" dependencies = [ "xmlparser", ] [[package]] name = "aws-types" -version = "1.3.12" +version = "1.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c50f3cdf47caa8d01f2be4a6663ea02418e892f9bbfd82c7b9a3a37eaccdd3a" +checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -717,7 +738,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -737,9 +758,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "blake3" @@ -775,9 +796,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "byteorder" @@ -819,9 +840,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.54" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "jobserver", @@ -882,9 +903,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", @@ -944,9 +965,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.55" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e34525d5bbbd55da2bb745d34b36121baac88d07619a9a09cfcf4a6c0832785" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -954,11 +975,11 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.55" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a20016a20a3da95bef50ec7238dbd09baeef4311dcdd38ec15aba69812fb61" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ - "anstream", + "anstream 1.0.0", "anstyle", "clap_lex", "strsim", @@ -966,21 +987,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "clap_lex" -version = "0.7.7" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmake" @@ -1167,7 +1188,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1191,7 +1212,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1202,7 +1223,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1272,9 +1293,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", ] @@ -1297,14 +1318,14 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "diesel" -version = "2.3.6" +version = "2.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b6c2fc184a6fb6ebcf5f9a5e3bbfa84d8fd268cdfcce4ed508979a6259494d" +checksum = "f4ae09a41a4b89f94ec1e053623da8340d996bc32c6517d325a9daad9b239358" dependencies = [ "bigdecimal", "diesel_derives", @@ -1327,7 +1348,7 @@ dependencies = [ "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1347,7 +1368,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe2444076b48641147115697648dc743c2c00b61adade0f01ce67133c7babe8c" dependencies = [ - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1376,7 +1397,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1402,7 +1423,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1477,9 +1498,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" dependencies = [ "log", ] @@ -1495,9 +1516,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" dependencies = [ "log", "regex", @@ -1505,11 +1526,11 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" dependencies = [ - "anstream", + "anstream 0.6.21", "anstyle", "env_filter", "jiff", @@ -1556,9 +1577,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixed-hash" @@ -1626,9 +1647,9 @@ dependencies = [ [[package]] name = "fs-err" -version = "3.2.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf68cef89750956493a66a10f512b9e58d9db21f2a573c079c0bdf1207a54a7" +checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" dependencies = [ "autocfg", ] @@ -1641,9 +1662,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -1656,9 +1677,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -1666,15 +1687,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -1683,32 +1704,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" @@ -1718,9 +1739,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -1730,7 +1751,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -1782,21 +1802,21 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", "wasm-bindgen", @@ -2106,7 +2126,7 @@ dependencies = [ "http 1.4.0", "hyper 1.8.1", "hyper-util", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -2129,14 +2149,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", - "futures-core", "futures-util", "http 1.4.0", "http-body 1.0.1", @@ -2145,7 +2164,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.6.3", "system-configuration", "tokio", "tower-service", @@ -2155,9 +2174,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2320,9 +2339,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" @@ -2372,9 +2391,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" -version = "0.2.18" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50" +checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" dependencies = [ "jiff-static", "log", @@ -2385,13 +2404,13 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.18" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78" +checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2428,9 +2447,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" dependencies = [ "once_cell", "wasm-bindgen", @@ -2470,7 +2489,7 @@ dependencies = [ "ena", "itertools 0.14.0", "lalrpop-util", - "petgraph", + "petgraph 0.7.1", "regex", "regex-syntax", "sha3", @@ -2503,9 +2522,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libloading" @@ -2550,9 +2569,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.23" +version = "1.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" +checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1" dependencies = [ "cc", "pkg-config", @@ -2561,9 +2580,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -2608,7 +2627,7 @@ dependencies = [ "quote", "regex-syntax", "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2678,9 +2697,9 @@ checksum = "120fa187be19d9962f0926633453784691731018a2bf936ddb4e29101b79c4a7" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miden-agglayer" @@ -2804,7 +2823,8 @@ dependencies = [ [[package]] name = "miden-crypto" version = "0.22.6" -source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56602a204fa7798f7770a98b6b749d34ea2b3929fc25fe869f30cad539d5b5c3" dependencies = [ "blake3", "cc", @@ -2852,10 +2872,11 @@ dependencies = [ [[package]] name = "miden-crypto-derive" version = "0.22.6" -source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6825dc04f78d60190ab1a79b2efe5d39f2c5a6ee30d515b1de0d8f872575d91c" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2879,7 +2900,8 @@ dependencies = [ [[package]] name = "miden-field" version = "0.22.6" -source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546ac41444d6f1ab015daa0bf420759405d3cf0a5cb2b552140ad60443ddf39c" dependencies = [ "miden-serde-utils", "num-bigint", @@ -2943,7 +2965,7 @@ dependencies = [ "serde_json", "spin 0.9.8", "strip-ansi-escapes", - "syn 2.0.114", + "syn 2.0.117", "textwrap", "thiserror 2.0.18", "trybuild", @@ -2958,7 +2980,7 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3063,7 +3085,7 @@ name = "miden-node-grpc-error-macro" version = "0.14.0-beta.1" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3206,7 +3228,7 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tokio-stream", - "toml 1.0.3+spec-1.1.0", + "toml 1.0.6+spec-1.1.0", "tonic", "tonic-reflection", "tower-http", @@ -3239,7 +3261,7 @@ name = "miden-node-test-macro" version = "0.1.0" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3344,7 +3366,7 @@ dependencies = [ "semver 1.0.27", "serde", "thiserror 2.0.18", - "toml 1.0.3+spec-1.1.0", + "toml 1.0.6+spec-1.1.0", "walkdir", ] @@ -3355,7 +3377,7 @@ source = "git+https://github.com/0xMiden/protocol?branch=igamigo-fix-partial-smt dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3418,7 +3440,7 @@ version = "0.14.0-beta.1" dependencies = [ "build-rs", "fs-err", - "getrandom 0.4.1", + "getrandom 0.4.2", "miden-node-proto-build", "miden-protocol", "miden-tx", @@ -3436,7 +3458,8 @@ dependencies = [ [[package]] name = "miden-serde-utils" version = "0.22.6" -source = "git+https://github.com/0xMiden/crypto?branch=mmagician-0.22.6#90a323480b008af7ef656a31e509d3955358c273" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bedaf94fb4bb6806e4af99fadce74e4cdd0e8664c571107b255f86b00b3149b" dependencies = [ "p3-field", "p3-goldilocks", @@ -3605,7 +3628,7 @@ checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3615,7 +3638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36c791ecdf977c99f45f23280405d7723727470f6689a5e6dbf513ac547ae10d" dependencies = [ "serde", - "toml 0.9.11+spec-1.1.0", + "toml 0.9.12+spec-1.1.0", ] [[package]] @@ -3760,7 +3783,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3825,9 +3848,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -3921,9 +3944,9 @@ checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" [[package]] name = "owo-colors" -version = "4.2.3" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" +checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "p3-air" @@ -4312,6 +4335,17 @@ dependencies = [ "indexmap", ] +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap", +] + [[package]] name = "phf_shared" version = "0.11.3" @@ -4323,29 +4357,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -4410,15 +4444,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" dependencies = [ "portable-atomic", ] @@ -4470,7 +4504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4485,9 +4519,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] @@ -4503,9 +4537,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" dependencies = [ "bit-set", "bit-vec", @@ -4528,7 +4562,7 @@ checksum = "fb6dc647500e84a25a85b100e76c85b8ace114c209432dc174f20aac11d4ed6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4543,23 +4577,22 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" +checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ "heck", - "itertools 0.13.0", + "itertools 0.14.0", "log", "multimap", - "once_cell", - "petgraph", + "petgraph 0.8.3", "prettyplease", "prost", "prost-types", "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn 2.0.114", + "syn 2.0.117", "tempfile", ] @@ -4570,10 +4603,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4590,9 +4623,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" dependencies = [ "prost", ] @@ -4626,9 +4659,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +checksum = "83c41efbf8f90ac44de7f3a868f0867851d261b56291732d0cbf7cceaaeb55a6" dependencies = [ "bitflags", "memchr", @@ -4637,9 +4670,9 @@ dependencies = [ [[package]] name = "pulldown-cmark-to-cmark" -version = "21.1.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8246feae3db61428fd0bb94285c690b460e4517d83152377543ca802357785f1" +checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" dependencies = [ "pulldown-cmark", ] @@ -4677,8 +4710,8 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.36", - "socket2 0.6.2", + "rustls 0.23.37", + "socket2 0.6.3", "thiserror 2.0.18", "tokio", "tracing", @@ -4698,7 +4731,7 @@ dependencies = [ "rand", "ring", "rustc-hash", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-pki-types", "slab", "thiserror 2.0.18", @@ -4716,16 +4749,16 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.2", + "socket2 0.6.3", "tracing", "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -4736,6 +4769,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.9.2" @@ -4841,9 +4880,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -4853,9 +4892,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -4870,9 +4909,9 @@ checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "relative-path" @@ -4903,7 +4942,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-pki-types", "rustls-platform-verifier", "serde", @@ -4990,7 +5029,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.117", "unicode-ident", ] @@ -5026,9 +5065,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", @@ -5051,9 +5090,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", "log", @@ -5098,7 +5137,7 @@ dependencies = [ "jni", "log", "once_cell", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki 0.103.9", @@ -5156,9 +5195,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -5180,9 +5219,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -5231,9 +5270,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.5.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags", "core-foundation 0.10.1", @@ -5244,9 +5283,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -5304,7 +5343,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5354,9 +5393,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" +checksum = "911bd979bf1070a3f3aa7b691a3b3e9968f339ceeec89e08c280a8a22207a32f" dependencies = [ "futures-executor", "futures-util", @@ -5369,13 +5408,24 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" +checksum = "0a7d91949b85b0d2fb687445e448b40d322b6b3e4af6b44a29b21d9a5f33e6d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", ] [[package]] @@ -5442,9 +5492,9 @@ checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -5470,12 +5520,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5612,9 +5662,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -5638,14 +5688,14 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ "bitflags", "core-foundation 0.9.4", @@ -5670,12 +5720,12 @@ checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -5752,7 +5802,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5763,7 +5813,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5852,9 +5902,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", @@ -5862,20 +5912,20 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5894,7 +5944,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.36", + "rustls 0.23.37", "tokio", ] @@ -5925,24 +5975,22 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.11+spec-1.1.0" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ - "indexmap", "serde_core", "serde_spanned", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", - "toml_writer", "winnow", ] [[package]] name = "toml" -version = "1.0.3+spec-1.1.0" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7614eaf19ad818347db24addfa201729cf2a9b6fdfd9eb0ab870fcacc606c0c" +checksum = "399b1124a3c9e16766831c6bba21e50192572cdd98706ea114f9502509686ffc" dependencies = [ "indexmap", "serde_core", @@ -5973,12 +6021,12 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" dependencies = [ "indexmap", - "toml_datetime 0.7.5+spec-1.1.0", + "toml_datetime 1.0.0+spec-1.1.0", "toml_parser", "winnow", ] @@ -6000,9 +6048,9 @@ checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tonic" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" dependencies = [ "async-trait", "axum", @@ -6018,7 +6066,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs", - "socket2 0.6.2", + "socket2 0.6.3", "sync_wrapper", "tokio", "tokio-rustls 0.26.4", @@ -6031,21 +6079,21 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40aaccc9f9eccf2cd82ebc111adc13030d23e887244bc9cfa5d1d636049de3" +checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "tonic-health" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a82868bf299e0a1d2e8dce0dc33a46c02d6f045b2c1f1d6cc8dc3d0bf1812ef" +checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" dependencies = [ "prost", "tokio", @@ -6056,9 +6104,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" dependencies = [ "bytes", "prost", @@ -6067,25 +6115,25 @@ dependencies = [ [[package]] name = "tonic-prost-build" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a16cba4043dc3ff43fcb3f96b4c5c154c64cbd18ca8dce2ab2c6a451d058a2" +checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" dependencies = [ "prettyplease", "proc-macro2", "prost-build", "prost-types", "quote", - "syn 2.0.114", + "syn 2.0.117", "tempfile", "tonic-build", ] [[package]] name = "tonic-reflection" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34da53e8387581d66db16ff01f98a70b426b091fdf76856e289d5c1bd386ed7b" +checksum = "aaf0685a51e6d02b502ba0764002e766b7f3042aed13d9234925b6ffbfa3fca7" dependencies = [ "prost", "prost-types", @@ -6097,9 +6145,9 @@ dependencies = [ [[package]] name = "tonic-web" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75214f6b6bd28c19aa752ac09fdf0eea546095670906c21fe3940e180a4c43f2" +checksum = "29453d84de05f4f1b573db22e6f9f6c95c189a6089a440c9a098aa9dea009299" dependencies = [ "base64", "bytes", @@ -6226,7 +6274,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6291,9 +6339,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -6328,9 +6376,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" +checksum = "47c635f0191bd3a2941013e5062667100969f8c4e9cd787c14f977265d73616e" dependencies = [ "dissimilar", "glob", @@ -6339,7 +6387,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.11+spec-1.1.0", + "toml 1.0.6+spec-1.1.0", ] [[package]] @@ -6374,9 +6422,9 @@ checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-linebreak" @@ -6451,9 +6499,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.20.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ "js-sys", "wasm-bindgen", @@ -6546,9 +6594,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" dependencies = [ "cfg-if", "once_cell", @@ -6559,9 +6607,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" dependencies = [ "cfg-if", "futures-util", @@ -6573,9 +6621,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6583,22 +6631,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" dependencies = [ "unicode-ident", ] @@ -6652,9 +6700,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" dependencies = [ "js-sys", "wasm-bindgen", @@ -6731,7 +6779,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6742,7 +6790,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -7004,9 +7052,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] @@ -7063,7 +7111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d31a19dae58475d019850e25b0170e94b16d382fbf6afee9c0e80fdc935e73e" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -7141,7 +7189,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.114", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -7157,7 +7205,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -7246,28 +7294,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.34" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ddd76bcebeed25db614f82bf31a9f4222d3fbba300e6fb6c00afa26cbd4d9d" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.34" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -7287,7 +7335,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure", ] @@ -7327,11 +7375,11 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "zmij" -version = "1.0.17" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02aae0f83f69aafc94776e879363e9771d7ecbffe2c7fbb6c14c5e00dfe88439" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 1a3487933e..e045b203f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,5 +146,4 @@ should_panic_without_expect = "allow" # We don't care about the specific panic files.extend-exclude = ["*.svg"] # Ignore SVG files. [patch.crates-io] -miden-crypto = { branch = "mmagician-0.22.6", git = "https://github.com/0xMiden/crypto" } miden-protocol = { branch = "igamigo-fix-partial-smt", git = "https://github.com/0xMiden/protocol" }