diff --git a/.config/nextest.toml b/.config/nextest.toml index 18e3038f5a..7ea4c3caf3 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -5,6 +5,10 @@ retries = { backoff = "exponential", count = 2, delay = "1s", jitter = tr slow-timeout = { period = "3m", terminate-after = 2 } status-level = "skip" +[[profile.default.overrides]] +filter = "package(miden-client-unit-tests) | package(miden-client-integration-tests)" +threads-required = 2 + [[profile.default.overrides]] filter = "test(import_genesis_accounts_can_be_used_for_transactions)" retries = 0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ec59d6b04c..2f5847e5ca 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -80,10 +80,10 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - - name: Install Rust with clippy + - name: Install Rust with nightly clippy run: | - rustup update --no-self-update - rustup component add clippy + rustup update --no-self-update nightly + rustup +nightly component add clippy - name: make - clippy run: make clippy @@ -92,11 +92,11 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - - name: Install Rust with clippy + - name: Install Rust with nightly clippy run: | - rustup update --no-self-update - rustup target add wasm32-unknown-unknown - rustup component add clippy + rustup update --no-self-update nightly + rustup target add --toolchain nightly wasm32-unknown-unknown + rustup +nightly component add clippy - name: make - clippy-wasm run: make clippy-wasm diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a42f6d79b5..c2e3e88c75 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -301,8 +301,8 @@ jobs: needs: [build-web-client-dist-folder, build-node-builder] strategy: matrix: - shard_index: [1, 2, 3, 4, 5, 6] - shard_total: [6] + shard_index: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + shard_total: [10] steps: - uses: actions/checkout@v6 - name: Install Rust diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e2051607b..e5c436531f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * [FEATURE][web] Added `getAccountProof` method to the web client's `RpcClient`, allowing lightweight retrieval of account header, storage slot values, and code via a single RPC call. Refactored the `NodeRpcClient::get_account_proof` signature to allow requesting just private account proofs ([#1794](https://github.com/0xMiden/miden-client/pull/1794), [#1814](https://github.com/0xMiden/miden-client/pull/1814)). * Added `getAccountByKeyCommitment` method to `WebClient` for retrieving accounts by public key commitment ([#1729](https://github.com/0xMiden/miden-client/pull/1729)). * Added automatic registration of note scripts required by network transactions (NTX). The client now checks the node's script registry before submitting a transaction and registers any missing scripts via a separate registration transaction ([#1840](https://github.com/0xMiden/miden-client/pull/1840)). +* Added automatic retry for rate-limited (`ResourceExhausted`) and transiently unavailable RPC calls in `GrpcClient`, with up to 5 attempts and `retry-after` header support ([#1928](https://github.com/0xMiden/miden-client/pull/1928)). ### Changes @@ -36,6 +37,8 @@ * [BREAKING][type][web] `AuthSecretKey.getRpoFalcon512SecretKeyAsFelts()` and `getEcdsaK256KeccakSecretKeyAsFelts()` now return `Result, JsValue>` instead of panicking on key type mismatch ([#1833](https://github.com/0xMiden/miden-client/pull/1833)). * [BREAKING][rename][cli] Renamed `CliConfig::from_system()` to `CliConfig::load()` and `CliClient::from_system_user_config()` to `CliClient::new()` for better discoverability ([#1848](https://github.com/0xMiden/miden-client/pull/1848)). * Removed `SmtForest` empty-root workaround in `AccountSmtForest::safe_pop_smts`, now that the upstream fix has landed in miden-crypto v0.19.7 ([#1864](https://github.com/0xMiden/miden-client/pull/1864)). +* [BREAKING][rename][all] Adapted to upstream protocol renames: `Falcon512Rpo` renamed to `Falcon512Poseidon2`, `Felt::as_int()` renamed to `as_canonical_u64()`, `OutputNote::Full` replaced by `OutputNote::Public(PublicOutputNote)`, Asset now uses key-value words API. +* [BREAKING][rename][all] Adapted to upstream protocol 0.14.0 renames: `NoteHeader::commitment()` renamed to `to_commitment()`, `NoteLocation::node_index_in_block()` renamed to `block_note_tree_index()`, `StorageMapKey::inner()` removed (use `Word::from(key)`), `TransactionOutputs::expiration_block_num` field now private (use getter). ([#1926](https://github.com/0xMiden/miden-client/pull/1926)) * Added an `InputNoteReader` accessible through `client.input_note_reader()` that allows for lazy iterator over all the consumed input notes ([#1843](https://github.com/0xMiden/miden-client/pull/1843), ([#1925](https://github.com/0xMiden/miden-client/pull/1925))). * Removed miden-cli template TOMLs in favor of direct serialization into packages ([#1879](https://github.com/0xMiden/miden-client/pull/1879)). diff --git a/Cargo.lock b/Cargo.lock index e6455ee7b2..e5c276ca9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,81 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "alloy-primitives" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3b431b4e72cd8bd0ec7a50b4be18e73dab74de0dba180eef171055e5d5926e" +dependencies = [ + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "itoa", + "paste", + "ruint", + "rustc-hash", + "sha3", +] + +[[package]] +name = "alloy-sol-macro" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab81bab693da9bb79f7a95b64b394718259fdd7e41dceeced4cad57cb71c4f6a" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489f1620bb7e2483fb5819ed01ab6edc1d2f93939dce35a5695085a1afd1d699" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck", + "indexmap", + "proc-macro-error2", + "proc-macro2", + "quote", + "sha3", + "syn 2.0.117", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56cef806ad22d4392c5fc83cf8f2089f988eb99c7067b4e0c6f1971fc1cca318" +dependencies = [ + "const-hex", + "dunce", + "heck", + "macro-string", + "proc-macro2", + "quote", + "syn 2.0.117", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-types" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64612d29379782a5dde6f4b6570d9c756d734d760c0c94c254d361e678a6591f" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -53,9 +128,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -68,15 +143,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -130,9 +205,9 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5bcfa8749ac45dd12cb11055aeeb6b27a3895560d60d71e3c23bf979e60514" +checksum = "9a686bbee5efb88a82df0621b236e74d925f470e5445d3220a5648b892ec99c9" dependencies = [ "anstyle", "bstr", @@ -219,9 +294,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" dependencies = [ "aws-lc-sys", "zeroize", @@ -229,9 +304,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" +checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a" dependencies = [ "cc", "cmake", @@ -266,9 +341,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.103.0" +version = "1.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bfd8dfb5a562f9a605bbd5c3aef09db9231c826a1e0488ce3f4338c70dbbb" +checksum = "c41ae6a33da941457e89075ef8ca5b4870c8009fe4dceeba82fce2f30f313ac6" dependencies = [ "aws-credential-types", "aws-runtime", @@ -290,9 +365,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.96.0" +version = "1.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64a6eded248c6b453966e915d32aeddb48ea63ad17932682774eb026fbef5b1" +checksum = "9aadc669e184501caaa6beafb28c6267fc1baef0810fb58f9b205485ca3f2567" dependencies = [ "aws-credential-types", "aws-runtime", @@ -314,9 +389,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.98.0" +version = "1.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db96d720d3c622fcbe08bae1c4b04a72ce6257d8b0584cb5418da00ae20a344f" +checksum = "1342a7db8f358d3de0aed2007a0b54e875458e39848d54cc1d46700b2bfcb0a8" dependencies = [ "aws-credential-types", "aws-runtime", @@ -338,9 +413,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.100.0" +version = "1.101.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fafbdda43b93f57f699c5dfe8328db590b967b8a820a13ccdd6687355dfcc7ca" +checksum = "ab41ad64e4051ecabeea802d6a17845a91e83287e1dd249e6963ea1ba78c428a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -517,9 +592,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.4.6" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b1117b3b2bbe166d11199b540ceed0d0f7676e36e7b962b5a437a9971eac75" +checksum = "9d73dbfbaa8e4bc57b9045137680b958d274823509a360abfd8e1d514d40c95c" dependencies = [ "base64-simd", "bytes", @@ -572,10 +647,13 @@ checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ "axum-core", "bytes", + "form_urlencoded", "futures-util", "http 1.4.0", "http-body 1.0.1", "http-body-util", + "hyper 1.8.1", + "hyper-util", "itoa", "matchit", "memchr", @@ -583,10 +661,15 @@ dependencies = [ "percent-encoding", "pin-project-lite", "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", "sync_wrapper", + "tokio", "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -605,6 +688,7 @@ dependencies = [ "sync_wrapper", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -684,6 +768,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" @@ -812,9 +905,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.56" +version = "1.2.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", "jobserver", @@ -898,9 +991,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -908,9 +1001,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -920,9 +1013,9 @@ 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", @@ -932,9 +1025,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmake" @@ -947,9 +1040,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "comfy-table" @@ -972,6 +1065,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-hex" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" +dependencies = [ + "cfg-if", + "cpufeatures", + "proptest", + "serde_core", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -984,6 +1089,15 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -1044,7 +1158,7 @@ dependencies = [ "crossterm_winapi", "document-features", "parking_lot", - "rustix 1.1.4", + "rustix", "winapi", ] @@ -1148,6 +1262,20 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "deadpool" version = "0.12.3" @@ -1223,17 +1351,19 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ + "convert_case", "proc-macro2", "quote", "rustc_version 0.4.1", "syn 2.0.117", + "unicode-xid", ] [[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", @@ -1337,9 +1467,9 @@ dependencies = [ [[package]] name = "dissimilar" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" +checksum = "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e" [[package]] name = "document-features" @@ -1451,9 +1581,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -1461,9 +1591,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", @@ -1575,7 +1705,7 @@ dependencies = [ "futures-core", "futures-sink", "nanorand", - "spin", + "spin 0.9.8", ] [[package]] @@ -1605,6 +1735,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror 1.0.69", +] + [[package]] name = "fs-err" version = "3.3.0" @@ -1701,6 +1841,12 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.32" @@ -1798,6 +1944,41 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "governor" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9efcab3c1958580ff1f25a2a41be1668f7603d849bb63af523b208a3cc1223b8" +dependencies = [ + "cfg-if", + "dashmap", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.4", + "hashbrown 0.16.1", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.9.2", + "smallvec", + "spinning_top", + "web-time", +] + [[package]] name = "group" version = "0.13.0" @@ -1847,6 +2028,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.5" @@ -1865,9 +2052,6 @@ dependencies = [ "allocator-api2", "equivalent", "foldhash 0.2.0", - "rayon", - "serde", - "serde_core", ] [[package]] @@ -1982,6 +2166,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + [[package]] name = "hyper" version = "0.14.32" @@ -2091,7 +2281,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.6.3", "tokio", "tower-service", "tracing", @@ -2306,9 +2496,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" @@ -2421,9 +2611,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.182" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libloading" @@ -2443,9 +2633,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" dependencies = [ "libc", ] @@ -2477,21 +2667,15 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.24" +version = "1.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4735e9cbde5aac84a5ce588f6b23a90b9b0b528f6c5a8db8a4aff300463a0839" +checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1" dependencies = [ "cc", "pkg-config", "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.12.1" @@ -2588,6 +2772,17 @@ dependencies = [ "libc", ] +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "matchers" version = "0.2.0" @@ -2617,10 +2812,11 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miden-agglayer" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e492a6044cf8875a64d7eec130d260f2eda1c783795261f00d5d52837ed027bd" +checksum = "98863d46f0f288b03f52a4591230b6ddded2b2110b4e0f9268d4b6f19efe49ba" dependencies = [ + "alloy-sol-types", "fs-err", "miden-assembly", "miden-core", @@ -2631,28 +2827,28 @@ dependencies = [ "miden-utils-sync", "primitive-types", "regex", - "thiserror", + "thiserror 2.0.18", "walkdir", ] [[package]] name = "miden-air" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cca9632323bd4e32ae5b21b101ed417a646f5d72196b1bf3f1ca889a148322a" +checksum = "5322d00bef8b19f4cd3415da2533a87c8860c7d9b80043d6cce0f184b40c5fff" dependencies = [ "miden-core", + "miden-crypto", "miden-utils-indexing", - "thiserror", - "winter-air", - "winter-prover", + "thiserror 2.0.18", + "tracing", ] [[package]] name = "miden-assembly" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2395b2917aea613a285d3425d1ca07e6c45442e2b34febdea2081db555df62fc" +checksum = "7ece22da0cbf350e4a2939a07eaa3200445e42e47ce1b1ee6538723b6b40a4d4" dependencies = [ "env_logger", "log", @@ -2660,14 +2856,14 @@ dependencies = [ "miden-core", "miden-mast-package", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "miden-assembly-syntax" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f9bed037d137f209b9e7b28811ec78c0536b3f9259d6f4ceb5823c87513b346" +checksum = "d84a0e14ce66e76497a6771f3e360eb85557f2417ea22db279d54c1238ffafde" dependencies = [ "aho-corasick", "env_logger", @@ -2684,30 +2880,30 @@ dependencies = [ "rustc_version 0.4.1", "semver 1.0.27", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "miden-block-prover" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9564dfb23c529aad68369845b6897a6f62bacdeab7c00db432a5f16670764d4" +checksum = "9710309c899f329e92853b1e396d01d6d0876dc5a95555b786cf7e6c93eae5bd" dependencies = [ "miden-protocol", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "miden-client" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "async-trait", "chrono", "futures", "getrandom 0.3.4", + "gloo-timers", "hex", - "miden-mast-package", "miden-node-proto-build", "miden-note-transport-proto-build", "miden-protocol", @@ -2718,10 +2914,10 @@ dependencies = [ "miette", "prost", "prost-types", - "rand", + "rand 0.9.2", "serde", "serde_json", - "thiserror", + "thiserror 2.0.18", "tokio", "tonic", "tonic-health", @@ -2735,7 +2931,7 @@ dependencies = [ [[package]] name = "miden-client-bench" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "assert_cmd", @@ -2744,7 +2940,7 @@ dependencies = [ "miden-client", "miden-client-sqlite-store", "predicates", - "rand", + "rand 0.9.2", "rand_chacha", "serial_test", "tokio", @@ -2752,7 +2948,7 @@ dependencies = [ [[package]] name = "miden-client-cli" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "assert_cmd", @@ -2764,11 +2960,11 @@ dependencies = [ "miden-client-sqlite-store", "miette", "predicates", - "rand", + "rand 0.9.2", "regex", "serde", "serial_test", - "thiserror", + "thiserror 2.0.18", "tokio", "toml 0.9.12+spec-1.1.0", "tracing", @@ -2778,7 +2974,7 @@ dependencies = [ [[package]] name = "miden-client-integration-tests" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "async-trait", @@ -2786,7 +2982,7 @@ dependencies = [ "miden-client", "miden-client-sqlite-store", "num_cpus", - "rand", + "rand 0.9.2", "regex", "serde", "serde_json", @@ -2799,7 +2995,7 @@ dependencies = [ [[package]] name = "miden-client-sqlite-store" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "async-trait", @@ -2811,26 +3007,26 @@ dependencies = [ "miden-standards", "rusqlite", "rusqlite_migration", - "thiserror", + "thiserror 2.0.18", "tokio", ] [[package]] name = "miden-client-unit-tests" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "miden-client", "miden-client-sqlite-store", "miden-protocol", "miden-standards", "miden-testing", - "rand", + "rand 0.9.2", "tokio", ] [[package]] name = "miden-client-web" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "async-trait", "console_error_panic_hook", @@ -2840,10 +3036,10 @@ dependencies = [ "miden-idxdb-store", "miden-protocol", "miden-standards", - "rand", + "rand 0.9.2", "serde", "serde-wasm-bindgen", - "thiserror", + "thiserror 2.0.18", "tracing", "tracing-subscriber", "tracing-wasm", @@ -2854,9 +3050,9 @@ dependencies = [ [[package]] name = "miden-core" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8714aa5f86c59e647b7417126b32adc4ef618f835964464f5425549df76b6d03" +checksum = "7bf4f5601b0d669aa125cce3bba4b98f2c8df729e2d53e66777429ac5f53e228" dependencies = [ "derive_more", "itertools 0.14.0", @@ -2865,20 +3061,19 @@ dependencies = [ "miden-formatting", "miden-utils-core-derive", "miden-utils-indexing", + "miden-utils-sync", "num-derive", "num-traits", "proptest", "proptest-derive", - "thiserror", - "winter-math", - "winter-utils", + "thiserror 2.0.18", ] [[package]] name = "miden-core-lib" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb16a4d39202c59a7964d3585cd5af21a46a759ff6452cb5f20723ed5af4362" +checksum = "82595fabb062315c32f6fc11c31755d3e5c6f8bc8c67d35154a067397d65b1de" dependencies = [ "env_logger", "fs-err", @@ -2887,15 +3082,14 @@ dependencies = [ "miden-crypto", "miden-processor", "miden-utils-sync", - "sha2", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "miden-crypto" -version = "0.19.8" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be59336a868de7c379eace9450563c2d7f4a0b7ab936835ec5a340dcd8d9a5ed" +checksum = "0ed0a034a460e27723dcfdf25effffab84331c3b46b13e7a1bd674197cc71bfe" dependencies = [ "blake3", "cc", @@ -2904,32 +3098,41 @@ dependencies = [ "ed25519-dalek", "flume", "glob", - "hashbrown 0.16.1", "hkdf", "k256", "miden-crypto-derive", + "miden-field", + "miden-serde-utils", "num", "num-complex", - "rand", + "p3-blake3", + "p3-challenger", + "p3-dft", + "p3-goldilocks", + "p3-keccak", + "p3-matrix", + "p3-maybe-rayon", + "p3-miden-lifted-stark", + "p3-symmetric", + "p3-util", + "rand 0.9.2", "rand_chacha", "rand_core 0.9.5", "rand_hc", "rayon", + "serde", "sha2", "sha3", "subtle", - "thiserror", - "winter-crypto", - "winter-math", - "winter-utils", + "thiserror 2.0.18", "x25519-dalek", ] [[package]] name = "miden-crypto-derive" -version = "0.19.8" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06f2e7a7ac7d01e03a7340224722e75494826fe6b61a3796b77fbb044d018287" +checksum = "e8bf6ebde028e79bcc61a3632d2f375a5cc64caa17d014459f75015238cb1e08" dependencies = [ "quote", "syn 2.0.117", @@ -2937,9 +3140,9 @@ dependencies = [ [[package]] name = "miden-debug-types" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1494f102ad5b9fa43e391d2601186dc601f41ab7dcd8a23ecca9bf3ef930f4" +checksum = "c9ef08bafef275f0d6a15108108b3f6df6642772e0a1c05e102cb7e96841e888" dependencies = [ "memchr", "miden-crypto", @@ -2949,8 +3152,26 @@ dependencies = [ "miden-utils-sync", "paste", "serde", - "serde_spanned 1.0.4", - "thiserror", + "serde_spanned 1.1.0", + "thiserror 2.0.18", +] + +[[package]] +name = "miden-field" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38011348f4fb4c9e5ce1f471203d024721c00e3b60a91aa91aaefe6738d8b5ea" +dependencies = [ + "miden-serde-utils", + "num-bigint", + "p3-challenger", + "p3-field", + "p3-goldilocks", + "paste", + "rand 0.10.0", + "serde", + "subtle", + "thiserror 2.0.18", ] [[package]] @@ -2964,7 +3185,7 @@ dependencies = [ [[package]] name = "miden-idxdb-store" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "async-trait", "base64", @@ -2980,27 +3201,27 @@ dependencies = [ [[package]] name = "miden-large-smt-backend-rocksdb" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31cc8f0fe3aad1112d0c23321b4533f88871d1a8238a7a36fc55789a4b19a9b5" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" 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.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692185bfbe0ecdb28bf623f1f8c88282cd6727ba081a28e23b301bdde1b45be4" +checksum = "f9b24d09fda64e0751f943ac616643342b05a47d626e2ee0040b902eff3c924e" dependencies = [ "derive_more", "miden-assembly-syntax", "miden-core", - "thiserror", + "miden-debug-types", + "thiserror 2.0.18", ] [[package]] @@ -3009,8 +3230,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", @@ -3021,15 +3240,11 @@ 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.117", - "terminal_size 0.3.0", "textwrap", - "thiserror", + "thiserror 2.0.18", "trybuild", "unicode-width 0.1.14", ] @@ -3047,9 +3262,8 @@ dependencies = [ [[package]] name = "miden-node-block-producer" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba271db1a669ee3b6b0ac5f2732a3d111928119f1cc2605da8a58d6662d906b" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "futures", @@ -3061,8 +3275,8 @@ dependencies = [ "miden-remote-prover-client", "miden-standards", "miden-tx-batch-prover", - "rand", - "thiserror", + "rand 0.9.2", + "thiserror 2.0.18", "tokio", "tokio-stream", "tonic", @@ -3074,24 +3288,22 @@ dependencies = [ [[package]] name = "miden-node-db" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97faeda3dbe8a8f8575e574aa2be84709be616312ea18abb7602261cb02ee4ef" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "deadpool", "deadpool-diesel", "deadpool-sync", "diesel", "miden-protocol", - "thiserror", + "thiserror 2.0.18", "tracing", ] [[package]] name = "miden-node-grpc-error-macro" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f133ba98d42f5cad906dd1ec56b577e3ba951ff290f4ec29c28645e01f949604" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "quote", "syn 2.0.117", @@ -3099,9 +3311,8 @@ dependencies = [ [[package]] name = "miden-node-ntx-builder" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e51ad2ef788a2424eaa4da41fb5855246f5765fd6da0a28345e73d6b26916a" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "build-rs", @@ -3111,25 +3322,27 @@ dependencies = [ "libsqlite3-sys", "miden-node-db", "miden-node-proto", + "miden-node-proto-build", "miden-node-utils", "miden-protocol", "miden-remote-prover-client", "miden-standards", "miden-tx", - "thiserror", + "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", "tonic", + "tonic-reflection", + "tower-http", "tracing", "url", ] [[package]] name = "miden-node-proto" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23721a329b692e70ff281d1b9c431e5e69683919d608e976b14946b306bc230" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "build-rs", @@ -3138,13 +3351,12 @@ dependencies = [ "http 1.4.0", "miden-node-grpc-error-macro", "miden-node-proto-build", - "miden-node-rocksdb-cxx-linkage-fix", "miden-node-utils", "miden-protocol", "miden-standards", "miette", "prost", - "thiserror", + "thiserror 2.0.18", "tonic", "tonic-prost", "tonic-prost-build", @@ -3153,9 +3365,8 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ac57ddec6bf630b5301630c953ed23661575b70e2fcc3ff221c660f3006a30" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "build-rs", "fs-err", @@ -3166,15 +3377,13 @@ dependencies = [ [[package]] name = "miden-node-rocksdb-cxx-linkage-fix" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4e79626aae4683ad8b00828d184ab437152402f3c1e5dce7c94456b361cec6" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" [[package]] name = "miden-node-rpc" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f0adf72daf3c49fe606df205b34bcb1877168c7542af3f7e7253d549565de3" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "futures", @@ -3186,7 +3395,7 @@ dependencies = [ "miden-protocol", "miden-tx", "semver 1.0.27", - "thiserror", + "thiserror 2.0.18", "tokio", "tokio-stream", "tonic", @@ -3200,9 +3409,8 @@ dependencies = [ [[package]] name = "miden-node-store" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d93ac410e4719ed4213b4014ac034b1ca62bcccdf999363534cb38ced0715e" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "build-rs", @@ -3222,19 +3430,18 @@ dependencies = [ "miden-node-db", "miden-node-proto", "miden-node-proto-build", - "miden-node-rocksdb-cxx-linkage-fix", "miden-node-utils", "miden-protocol", "miden-remote-prover-client", "miden-standards", "pretty_assertions", - "rand", + "rand 0.9.2", "rand_chacha", "serde", - "thiserror", + "thiserror 2.0.18", "tokio", "tokio-stream", - "toml 1.0.4+spec-1.1.0", + "toml 1.1.0+spec-1.1.0", "tonic", "tonic-reflection", "tower-http", @@ -3244,26 +3451,31 @@ dependencies = [ [[package]] name = "miden-node-utils" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ec7a7f77ee57b5b84632fd1facc5fb466b77f1fe9b9fbb8ad1689b2d7f43478" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "bytes", + "clap", + "fs-err", + "governor", "http 1.4.0", "http-body-util", + "humantime", "itertools 0.14.0", "lru", - "miden-node-rocksdb-cxx-linkage-fix", + "miden-large-smt-backend-rocksdb", "miden-protocol", "opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", - "rand", - "thiserror", + "rand 0.9.2", + "thiserror 2.0.18", "tokio", "tonic", + "tower", "tower-http", + "tower_governor", "tracing", "tracing-forest", "tracing-opentelemetry", @@ -3273,9 +3485,8 @@ dependencies = [ [[package]] name = "miden-node-validator" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd351f4377f77490c5760bff197f88f2d493f567f6c1abdabc042c0f39118ac1" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "anyhow", "aws-config", @@ -3289,7 +3500,7 @@ dependencies = [ "miden-node-utils", "miden-protocol", "miden-tx", - "thiserror", + "thiserror 2.0.18", "tokio", "tokio-stream", "tonic", @@ -3312,9 +3523,9 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e09f7916b1e7505f74a50985a185fdea4c0ceb8f854a34c90db28e3f7da7ab6" +checksum = "ba53ff06ef0affa0c3fb13e7e2ef5bde99f96eebcec8c360c6658050480ef676" dependencies = [ "itertools 0.14.0", "miden-air", @@ -3324,17 +3535,16 @@ dependencies = [ "miden-utils-indexing", "paste", "rayon", - "thiserror", + "thiserror 2.0.18", "tokio", "tracing", - "winter-prover", ] [[package]] name = "miden-protocol" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a88effeac994eb55b8dc4f93fbfd71a5d916dfaba1099896e27a0ee42c488c1" +checksum = "38c30a20ea30071544a827d0daa12e343e444c1e314d1a4560c43f2d6c7b43c6" dependencies = [ "bech32", "fs-err", @@ -3349,23 +3559,22 @@ dependencies = [ "miden-protocol-macros", "miden-utils-sync", "miden-verifier", - "rand", + "rand 0.9.2", "rand_chacha", "rand_xoshiro", "regex", "semver 1.0.27", "serde", - "thiserror", - "toml 0.9.12+spec-1.1.0", + "thiserror 2.0.18", + "toml 1.1.0+spec-1.1.0", "walkdir", - "winter-rand-utils", ] [[package]] name = "miden-protocol-macros" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb28b730005e5f8b08d615ea9216f8cab77b3a7439fa54d5e39d2ec43ef53a3" +checksum = "76c58e1d47dd08af461f6aa13ec128013bb1a26183ea4dd42f323939bcbf72d4" dependencies = [ "proc-macro2", "quote", @@ -3374,23 +3583,26 @@ dependencies = [ [[package]] name = "miden-prover" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45e30526be72b8af0fd1d8b24c9cba8ac1187ca335dcee38b8e5e20234e7698" +checksum = "15462425359e87540d92e277cf1174a85a174ca433bd63d27286f65ab318f2d4" dependencies = [ + "bincode", "miden-air", + "miden-core", + "miden-crypto", "miden-debug-types", "miden-processor", + "serde", + "thiserror 2.0.18", + "tokio", "tracing", - "winter-maybe-async", - "winter-prover", ] [[package]] name = "miden-remote-prover-client" -version = "0.14.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fae30a877ba6481e62ed2a553277633c91a592686afa73ba91c2f15ed7e17f" +version = "0.14.0" +source = "git+https://github.com/0xMiden/miden-node?branch=next#a329b4c7fc5592bd2844242f8a325084e76c9512" dependencies = [ "build-rs", "fs-err", @@ -3400,7 +3612,7 @@ dependencies = [ "miden-tx", "miette", "prost", - "thiserror", + "thiserror 2.0.18", "tokio", "tonic", "tonic-prost", @@ -3408,11 +3620,21 @@ dependencies = [ "tonic-web-wasm-client", ] +[[package]] +name = "miden-serde-utils" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff78082e9b4ca89863e68da01b35f8a4029ee6fd912e39fa41fde4273a7debab" +dependencies = [ + "p3-field", + "p3-goldilocks", +] + [[package]] name = "miden-standards" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cef036bbfec29acba92751a13d05844bbcf080140201097b419c9ad1927e367" +checksum = "612af5b544a25e318d89dca9ac958d436f9a8b209be4dda6ee2df0c21c58548e" dependencies = [ "fs-err", "miden-assembly", @@ -3420,17 +3642,17 @@ dependencies = [ "miden-core-lib", "miden-processor", "miden-protocol", - "rand", + "rand 0.9.2", "regex", - "thiserror", + "thiserror 2.0.18", "walkdir", ] [[package]] name = "miden-testing" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e980777d0f7e6069942b14d4e7cb3d4d137b323ddfa15722a3bd21e9d13fdd2e" +checksum = "982fb99a73d12abc6088562be1f606f24cbb2673e832ba872bf86d6add566638" dependencies = [ "anyhow", "itertools 0.14.0", @@ -3444,31 +3666,30 @@ dependencies = [ "miden-standards", "miden-tx", "miden-tx-batch-prover", - "rand", + "rand 0.9.2", "rand_chacha", - "thiserror", - "winterfell", + "thiserror 2.0.18", ] [[package]] name = "miden-tx" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c67e0df9adcf29c9111df65acf408ae05952b8bc6569f571963676f97668d83f" +checksum = "18e32f06ec896176724bbb29de6c655f856e5444319cd3824c921511cde24f87" dependencies = [ "miden-processor", "miden-protocol", "miden-prover", "miden-standards", "miden-verifier", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "miden-tx-batch-prover" -version = "0.14.0-alpha.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba29f8f6ecae671eff8b52b4c19eca8db5964c0b45b5d68c3ce38a57a8367931" +checksum = "eb6bd365128454fe630a5441d1cf99297b6e1bba56923f00b97c1df485c37b90" dependencies = [ "miden-protocol", "miden-tx", @@ -3476,9 +3697,9 @@ dependencies = [ [[package]] name = "miden-utils-core-derive" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b1d490e6d7b509622d3c2cc69ffd66ad48bf953dc614579b568fe956ce0a6c" +checksum = "477db426fc31f666d7e65b0cc907fe431d36d88d611a0594cf266104eb168b4c" dependencies = [ "proc-macro2", "quote", @@ -3487,9 +3708,9 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52658f6dc091c1c78e8b35ee3e7ff3dad53051971a3c514e461f581333758fe7" +checksum = "785c1ec4ad9994100b117b8eab8c453dcc35d3d168e4f72ac818efb700abe7b1" dependencies = [ "miden-crypto", "miden-debug-types", @@ -3500,46 +3721,53 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff7bcb7875b222424bdfb657a7cf21a55e036aa7558ebe1f5d2e413b440d0d" +checksum = "46cec00c8cf32ec46df7542fb9ea15fbe7a5149920ef97776a4f4bc3a563e8de" dependencies = [ - "thiserror", + "miden-crypto", + "thiserror 2.0.18", ] [[package]] name = "miden-utils-sync" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d53d1ab5b275d8052ad9c4121071cb184bc276ee74354b0d8a2075e5c1d1f0" +checksum = "9529c1c173506f30d3949f7a54b65f1eb318098e37ed5730a1bb9027eee2fa4b" dependencies = [ "lock_api", "loom", + "once_cell", "parking_lot", ] [[package]] name = "miden-verifier" -version = "0.20.6" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13816663794beb15c8a4721c15252eb21f3b3233525684f60c7888837a98ff4" +checksum = "997c842047ffa2d011eb65bf638a3135b2d52bce5b20770fcc6040f1b48c624a" dependencies = [ + "bincode", "miden-air", "miden-core", - "thiserror", + "miden-crypto", + "serde", + "thiserror 2.0.18", "tracing", - "winter-verifier", ] [[package]] name = "midenc-hir-type" -version = "0.4.3" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4cfab04baffdda3fb9eafa5f873604059b89a1699aa95e4f1057397a69f0b5" +checksum = "2eb29d7c049fb69373c7e775e3d4411e63e4ee608bc43826282ba62c6ec9f891" dependencies = [ "miden-formatting", + "miden-serde-utils", + "serde", + "serde_repr", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -3556,7 +3784,7 @@ dependencies = [ "supports-color", "supports-hyperlinks", "supports-unicode", - "terminal_size 0.4.3", + "terminal_size", "textwrap", "unicode-width 0.1.14", ] @@ -3648,7 +3876,7 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "node-builder" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "miden-node-block-producer", @@ -3659,7 +3887,7 @@ dependencies = [ "miden-node-validator", "miden-protocol", "miden-standards", - "rand", + "rand 0.9.2", "rand_chacha", "tempfile", "tokio", @@ -3677,8 +3905,20 @@ dependencies = [ ] [[package]] -name = "normalize-line-endings" -version = "0.3.0" +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" @@ -3803,9 +4043,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" @@ -3835,22 +4075,22 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror", + "thiserror 2.0.18", "tracing", ] [[package]] name = "opentelemetry-otlp" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" +checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" dependencies = [ "http 1.4.0", "opentelemetry", "opentelemetry-proto", "opentelemetry_sdk", "prost", - "thiserror", + "thiserror 2.0.18", "tokio", "tonic", ] @@ -3879,8 +4119,8 @@ dependencies = [ "futures-util", "opentelemetry", "percent-encoding", - "rand", - "thiserror", + "rand 0.9.2", + "thiserror 2.0.18", "tokio", "tokio-stream", ] @@ -3903,6 +4143,321 @@ version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +[[package]] +name = "p3-air" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ebc58ec27a174420348b3f04dba836fa2e5b5fe8df74601087417352757c643" +dependencies = [ + "p3-field", + "p3-matrix", + "tracing", +] + +[[package]] +name = "p3-blake3" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3cacb38c29fbee71fe3e5c6c0a1073632e46dc3e93fbdc50ab4e4fac137b525" +dependencies = [ + "blake3", + "p3-symmetric", + "p3-util", +] + +[[package]] +name = "p3-challenger" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9bbcb18fe90271668259aacfc43455e328673c2b5c926cff0663edc8653e4d" +dependencies = [ + "p3-field", + "p3-maybe-rayon", + "p3-monty-31", + "p3-symmetric", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-commit" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14d07b50c6f6d3bc89ed7c54ae0c569fb4caaa58263fd389dc02fb1b0a6378fa" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "p3-matrix", + "p3-util", + "serde", +] + +[[package]] +name = "p3-dft" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17e7ba0dc20be075eab3f88f0cb820a0901f86218a1c46134e7c817d41597989" +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.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b8533e6c2f4d0cc61fd2ae5299bb83316898e535f47291808d37e4d666ba088" +dependencies = [ + "itertools 0.14.0", + "num-bigint", + "p3-maybe-rayon", + "p3-util", + "paste", + "rand 0.10.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-goldilocks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8102a8c85acee1f896c3764bef5fac908e6026dadfc557c185294970cce0746" +dependencies = [ + "num-bigint", + "p3-challenger", + "p3-dft", + "p3-field", + "p3-mds", + "p3-poseidon1", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "paste", + "rand 0.10.0", + "serde", +] + +[[package]] +name = "p3-keccak" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65d30dd586d2855906a01c3414c155c2d564f6677d1b51f04186dcac080f757" +dependencies = [ + "p3-symmetric", + "p3-util", + "tiny-keccak", +] + +[[package]] +name = "p3-matrix" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72bb78444459155c2e4711d71abbfef7b04cc2ba1fa83751ccab241b01957095" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand 0.10.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a0a54345917f500130a9986fa5ff9ecbc26f0c6313080b35b713e26ddc8053" +dependencies = [ + "rayon", +] + +[[package]] +name = "p3-mds" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd514bf3e9bf9f1b7db2db96e5bd2972d9963dd62430de1e193d74522ae96a6" +dependencies = [ + "p3-dft", + "p3-field", + "p3-symmetric", + "p3-util", + "rand 0.10.0", +] + +[[package]] +name = "p3-miden-lifted-air" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5c31c65fdc88952d7b301546add9670676e5b878aa0066dd929f107c203b006" +dependencies = [ + "p3-air", + "p3-field", + "p3-matrix", + "p3-util", + "thiserror 2.0.18", +] + +[[package]] +name = "p3-miden-lifted-fri" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9932f1b0a16609a45cd4ee10a4d35412728bc4b38837c7979d7c85d8dcc9fc" +dependencies = [ + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-miden-lmcs", + "p3-miden-transcript", + "p3-util", + "rand 0.10.0", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "p3-miden-lifted-stark" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3956ab7270c3cdd53ca9796d39ae1821984eb977415b0672110f9666bff5d8" +dependencies = [ + "p3-challenger", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-miden-lifted-air", + "p3-miden-lifted-fri", + "p3-miden-lmcs", + "p3-miden-stateful-hasher", + "p3-miden-transcript", + "p3-util", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "p3-miden-lmcs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c46791c983e772136db3d48f102431457451447abb9087deb6c8ce3c1efc86" +dependencies = [ + "p3-commit", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-miden-stateful-hasher", + "p3-miden-transcript", + "p3-symmetric", + "p3-util", + "rand 0.10.0", + "serde", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "p3-miden-stateful-hasher" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec47a9d9615eb3d9d2a59b00d19751d9ad85384b55886827913d680d912eac6a" +dependencies = [ + "p3-field", + "p3-symmetric", +] + +[[package]] +name = "p3-miden-transcript" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c565647487e4a949f67e6f115b0391d6cb82ac8e561165789939bab23d0ae7" +dependencies = [ + "p3-challenger", + "p3-field", + "serde", + "thiserror 2.0.18", +] + +[[package]] +name = "p3-monty-31" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d9340a650f07a6cd42a4e877017ba7b206df87fe50dfc3cf110f01a3c370bd1" +dependencies = [ + "itertools 0.14.0", + "num-bigint", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-mds", + "p3-poseidon1", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "paste", + "rand 0.10.0", + "serde", + "spin 0.10.0", + "tracing", +] + +[[package]] +name = "p3-poseidon1" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd56ae3a51ded1b77f7b1b21d0b157ae82b9d5ca8f2cba347c0b821fe771a79" +dependencies = [ + "p3-field", + "p3-symmetric", + "rand 0.10.0", +] + +[[package]] +name = "p3-poseidon2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "858aa1c33ec983dfbb8cfc553a213de19d8fde96485e54e6e952b9ac5e70bd4e" +dependencies = [ + "p3-field", + "p3-mds", + "p3-symmetric", + "p3-util", + "rand 0.10.0", +] + +[[package]] +name = "p3-symmetric" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9a3b20bb8104e52d45219a78d80654c8ac6a4781be0eaa3f3e999f5ae4b9b2" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "p3-util", + "serde", +] + +[[package]] +name = "p3-util" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f24495d9cd64693165a9f1b3da0758395ad6d25d2d44dd740bdb34c2bce0c53" +dependencies = [ + "rayon", + "serde", + "transpose", +] + [[package]] name = "parking_lot" version = "0.12.5" @@ -4058,9 +4613,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" dependencies = [ "portable-atomic", ] @@ -4155,6 +4710,28 @@ dependencies = [ "uint", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -4179,13 +4756,13 @@ dependencies = [ [[package]] name = "proptest" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bitflags", "num-traits", - "rand", + "rand 0.9.2", "rand_chacha", "rand_xorshift", "regex-syntax", @@ -4280,7 +4857,7 @@ dependencies = [ "prost-reflect", "prost-types", "protox-parse", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -4292,14 +4869,14 @@ dependencies = [ "logos", "miette", "prost-types", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "pulldown-cmark" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c41efbf8f90ac44de7f3a868f0867851d261b56291732d0cbf7cceaaeb55a6" +checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" dependencies = [ "bitflags", "memchr", @@ -4315,6 +4892,21 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quote" version = "1.0.45" @@ -4336,6 +4928,15 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.2" @@ -4346,6 +4947,15 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +dependencies = [ + "rand_core 0.10.0", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -4374,6 +4984,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" + [[package]] name = "rand_hc" version = "0.3.2" @@ -4401,6 +5017,15 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags", +] + [[package]] name = "rayon" version = "1.11.0" @@ -4438,7 +5063,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -4517,9 +5142,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a1f2315036ef6b1fbacd1972e8ee7688030b0a2121edfc2a6550febd41574d" dependencies = [ "hashbrown 0.16.1", - "thiserror", + "thiserror 2.0.18", ] +[[package]] +name = "ruint" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +dependencies = [ + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rusqlite" version = "0.37.0" @@ -4574,19 +5220,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.59.0", -] - [[package]] name = "rustix" version = "1.1.4" @@ -4596,7 +5229,7 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.12.1", + "linux-raw-sys", "windows-sys 0.61.2", ] @@ -4623,7 +5256,7 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.10", "subtle", "zeroize", ] @@ -4661,9 +5294,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "aws-lc-rs", "ring", @@ -4703,9 +5336,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", ] @@ -4854,22 +5487,56 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "serde_spanned" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ - "serde", + "serde_core", ] [[package]] -name = "serde_spanned" -version = "1.0.4" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "serde_core", + "form_urlencoded", + "itoa", + "ryu", + "serde", ] [[package]] @@ -4983,6 +5650,9 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "smawk" @@ -5002,12 +5672,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]] @@ -5019,6 +5689,24 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -5053,6 +5741,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" @@ -5129,6 +5823,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f425ae0b12e2f5ae65542e00898d500d4d318b4baf09f40fd0d410454e9947" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -5154,14 +5860,14 @@ checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "tempfile" -version = "3.26.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "getrandom 0.4.2", "once_cell", - "rustix 1.1.4", + "rustix", "windows-sys 0.61.2", ] @@ -5185,22 +5891,12 @@ dependencies = [ [[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" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" +checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ - "rustix 1.1.4", - "windows-sys 0.60.2", + "rustix", + "windows-sys 0.61.2", ] [[package]] @@ -5211,7 +5907,7 @@ checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "testing-remote-prover" -version = "0.14.0-alpha.1" +version = "0.14.0" dependencies = [ "anyhow", "async-trait", @@ -5238,13 +5934,33 @@ dependencies = [ "unicode-width 0.2.2", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -5298,6 +6014,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" @@ -5319,7 +6044,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] @@ -5400,26 +6125,26 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.4", + "serde_spanned 1.1.0", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.15", ] [[package]] name = "toml" -version = "1.0.4+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94c3321114413476740df133f0d8862c61d87c8d26f04c6841e033c8c80db47" +checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 1.0.0+spec-1.1.0", + "serde_spanned 1.1.0", + "toml_datetime 1.1.0+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 1.0.0", ] [[package]] @@ -5442,9 +6167,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.0.0+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" dependencies = [ "serde_core", ] @@ -5460,16 +6185,16 @@ dependencies = [ "serde_spanned 0.6.9", "toml_datetime 0.6.11", "toml_write", - "winnow", + "winnow 0.7.15", ] [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" dependencies = [ - "winnow", + "winnow 1.0.0", ] [[package]] @@ -5480,9 +6205,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "tonic" @@ -5504,7 +6229,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", @@ -5615,7 +6340,7 @@ dependencies = [ "httparse", "js-sys", "pin-project", - "thiserror", + "thiserror 2.0.18", "tonic", "tower-service", "wasm-bindgen", @@ -5674,12 +6399,30 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +[[package]] +name = "tower_governor" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44de9b94d849d3c46e06a883d72d408c2de6403367b39df2b1c9d9e7b6736fe6" +dependencies = [ + "axum", + "forwarded-header-value", + "governor", + "http 1.4.0", + "pin-project", + "thiserror 2.0.18", + "tonic", + "tower", + "tracing", +] + [[package]] name = "tracing" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -5714,7 +6457,7 @@ checksum = "f09cb459317a3811f76644334473239d696cd8efc606963ae7d1c308cead3b74" dependencies = [ "chrono", "smallvec", - "thiserror", + "thiserror 2.0.18", "tracing", "tracing-subscriber", ] @@ -5758,9 +6501,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", @@ -5788,6 +6531,16 @@ dependencies = [ "wasm-bindgen", ] +[[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" @@ -5807,7 +6560,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 1.0.4+spec-1.1.0", + "toml 1.1.0+spec-1.1.0", ] [[package]] @@ -5863,9 +6616,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "a559e63b5d8004e12f9bce88af5c6d939c58de839b7532cfe9653846cedd2a9e" [[package]] name = "unicode-width" @@ -5934,9 +6687,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -6247,40 +7000,13 @@ dependencies = [ "windows-link", ] -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -6292,313 +7018,84 @@ dependencies = [ "windows-link", ] -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -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", ] [[package]] -name = "winter-air" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef01227f23c7c331710f43b877a8333f5f8d539631eea763600f1a74bf018c7c" -dependencies = [ - "libm", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-crypto" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cdb247bc142438798edb04067ab72a22cf815f57abbd7b78a6fa986fc101db8" -dependencies = [ - "blake3", - "sha3", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-fri" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd592b943f9d65545683868aaf1b601eb66e52bfd67175347362efff09101d3a" -dependencies = [ - "winter-crypto", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winter-math" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aecfb48ee6a8b4746392c8ff31e33e62df8528a3b5628c5af27b92b14aef1ea" -dependencies = [ - "winter-utils", -] - -[[package]] -name = "winter-maybe-async" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d31a19dae58475d019850e25b0170e94b16d382fbf6afee9c0e80fdc935e73e" -dependencies = [ - "quote", - "syn 2.0.117", -] - -[[package]] -name = "winter-prover" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84cc631ed56cd39b78ef932c1ec4060cc6a44d114474291216c32f56655b3048" -dependencies = [ - "tracing", - "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-maybe-async", - "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" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0425ea81f8f703a1021810216da12003175c7974a584660856224df04b2e2fdb" -dependencies = [ - "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winterfell" -version = "0.13.1" +name = "winnow" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f824ddd5aec8ca6a54307f20c115485a8a919ea94dd26d496d856ca6185f4f" -dependencies = [ - "winter-air", - "winter-prover", - "winter-verifier", -] +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" [[package]] name = "wit-bindgen" @@ -6741,18 +7238,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.40" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.40" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 51d2d7e7d9..d3f4220dad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,36 +21,43 @@ authors = ["miden contributors"] edition = "2024" license = "MIT" repository = "https://github.com/0xMiden/miden-client" -rust-version = "1.91" -version = "0.14.0-alpha.1" +rust-version = "1.93" +version = "0.14.0" [profile.test-dev] inherits = "dev" opt-level = 1 +[profile.release] +codegen-units = 1 +lto = true +strip = true + [workspace.dependencies] # Workspace crates -idxdb-store = { default-features = false, package = "miden-idxdb-store", path = "crates/idxdb-store", version = "0.14.0-alpha.1" } -miden-client = { default-features = false, path = "crates/rust-client", version = "0.14.0-alpha.1" } -miden-client-sqlite-store = { default-features = false, path = "crates/sqlite-store", version = "0.14.0-alpha.1" } +idxdb-store = { default-features = false, package = "miden-idxdb-store", path = "crates/idxdb-store", version = "0.14.0" } +miden-client = { default-features = false, path = "crates/rust-client", version = "0.14.0" } +miden-client-sqlite-store = { default-features = false, path = "crates/sqlite-store", version = "0.14.0" } # Miden protocol dependencies -miden-protocol = { default-features = false, version = "=0.14.0-alpha.1" } -miden-standards = { default-features = false, version = "=0.14.0-alpha.1" } -miden-testing = { default-features = false, version = "=0.14.0-alpha.1" } -miden-tx = { default-features = false, version = "=0.14.0-alpha.1" } +miden-protocol = { default-features = false, version = "0.14.0" } +miden-standards = { default-features = false, version = "0.14.0" } +miden-testing = { default-features = false, version = "0.14.0" } +miden-tx = { default-features = false, version = "0.14.0" } -# Miden node dependencies -miden-node-block-producer = { version = "=0.14.0-alpha.4" } -miden-node-ntx-builder = { version = "=0.14.0-alpha.4" } -miden-node-proto = { version = "=0.14.0-alpha.4" } -miden-node-proto-build = { default-features = false, version = "=0.14.0-alpha.4" } -miden-node-rpc = { version = "=0.14.0-alpha.4" } -miden-node-store = { version = "=0.14.0-alpha.4" } -miden-node-utils = { version = "=0.14.0-alpha.4" } -miden-node-validator = { version = "=0.14.0-alpha.4" } +# Miden node dependencies (from git branch until compatible crates.io release) +miden-node-block-producer = { branch = "next", git = "https://github.com/0xMiden/miden-node" } +miden-node-ntx-builder = { branch = "next", git = "https://github.com/0xMiden/miden-node" } +miden-node-proto = { branch = "next", git = "https://github.com/0xMiden/miden-node" } +miden-node-proto-build = { branch = "next", default-features = false, git = "https://github.com/0xMiden/miden-node" } +miden-node-rpc = { branch = "next", git = "https://github.com/0xMiden/miden-node" } +miden-node-store = { branch = "next", git = "https://github.com/0xMiden/miden-node" } +miden-node-utils = { branch = "next", git = "https://github.com/0xMiden/miden-node" } +miden-node-validator = { branch = "next", git = "https://github.com/0xMiden/miden-node" } miden-note-transport-proto-build = { default-features = false, version = "0.2" } -miden-remote-prover-client = { default-features = false, features = ["tx-prover"], version = "=0.14.0-alpha.4" } +miden-remote-prover-client = { branch = "next", default-features = false, features = [ + "tx-prover", +], git = "https://github.com/0xMiden/miden-node" } # External dependencies anyhow = { default-features = false, version = "1.0" } diff --git a/Makefile b/Makefile index f294af2115..a326af28e5 100644 --- a/Makefile +++ b/Makefile @@ -20,13 +20,13 @@ NOTE_TRANSPORT_ENDPOINT=http://127.0.0.1:57292 .PHONY: clippy clippy: ## Run Clippy with configs. We need two separate commands because the `testing-remote-prover` cannot be built along with the rest of the workspace. This is because they use different versions of the `miden-tx` crate which aren't compatible with each other. - cargo clippy --workspace $(EXCLUDE_WASM_PACKAGES) --exclude testing-remote-prover --all-targets -- -D warnings - cargo clippy --package testing-remote-prover --all-targets -- -D warnings + cargo +nightly clippy --workspace $(EXCLUDE_WASM_PACKAGES) --exclude testing-remote-prover --all-targets -- -D warnings + cargo +nightly clippy --package testing-remote-prover --all-targets -- -D warnings .PHONY: clippy-wasm clippy-wasm: rust-client-ts-build ## Run Clippy for the wasm packages (web client and idxdb store) - cargo clippy --package miden-client-web --target wasm32-unknown-unknown --all-targets -- -D warnings - cargo clippy --package miden-idxdb-store --target wasm32-unknown-unknown --all-targets -- -D warnings + cargo +nightly clippy --package miden-client-web --target wasm32-unknown-unknown --all-targets -- -D warnings + cargo +nightly clippy --package miden-idxdb-store --target wasm32-unknown-unknown --all-targets -- -D warnings .PHONY: fix fix: ## Run Fix with configs, building tests with proper features to avoid type split. diff --git a/bin/integration-tests/src/asm/PASS_THROUGH.masm b/bin/integration-tests/src/asm/PASS_THROUGH.masm index 59338c9123..8f56346cf7 100644 --- a/bin/integration-tests/src/asm/PASS_THROUGH.masm +++ b/bin/integration-tests/src/asm/PASS_THROUGH.masm @@ -4,7 +4,7 @@ use miden::protocol::output_note # ERRORS # ================================================================================================= -# PASS_THROUGH script expects exactly 10 note storage items +# PASS_THROUGH script expects exactly 14 note storage items const ERR_PASS_THROUGH_WRONG_NUMBER_OF_STORAGE_ITEMS="wrong number of storage items" #! PASS_THROUGH script: @@ -14,7 +14,8 @@ const ERR_PASS_THROUGH_WRONG_NUMBER_OF_STORAGE_ITEMS="wrong number of storage it #! Outputs: [] #! #! Note storage is assumed to be as follows: -#! - ASSET +#! - ASSET_KEY +#! - ASSET_VALUE #! - RECIPIENT #! - [note_type, tag] begin @@ -25,31 +26,40 @@ begin push.0 exec.active_note::get_storage # => [num_storage_items, storage_ptr] - # make sure the number of storage items is 10 - eq.10 assert.err=ERR_PASS_THROUGH_WRONG_NUMBER_OF_STORAGE_ITEMS + # make sure the number of storage items is 14 + eq.14 assert.err=ERR_PASS_THROUGH_WRONG_NUMBER_OF_STORAGE_ITEMS # => [storage_ptr] - # load ASSET - mem_loadw_be - # => [ASSET] + # Load in reverse order so after output_note::create we get [note_idx, ASSET_KEY, ASSET_VALUE] + # load ASSET_VALUE (deepest on stack) + drop + padw mem_loadw_le.4 + # => [ASSET_VALUE] - padw mem_loadw_be.4 - # => [RECIPIENT, ASSET] + # load ASSET_KEY on top + padw mem_loadw_le.0 + # => [ASSET_KEY, ASSET_VALUE] + + # load RECIPIENT on top + padw mem_loadw_le.8 + # => [RECIPIENT, ASSET_KEY, ASSET_VALUE] # load note_type and tag from memory - mem_load.8 mem_load.9 - # => [tag, note_type, RECIPIENT, ASSET] + mem_load.12 mem_load.13 + # => [tag, note_type, RECIPIENT, ASSET_KEY, ASSET_VALUE] # create a note using storage # Inputs: [tag, note_type, RECIPIENT] exec.output_note::create - # => [note_idx, ASSET] + # => [note_idx, ASSET_KEY, ASSET_VALUE] + + # rearrange stack for add_asset which expects [ASSET_KEY, ASSET_VALUE, note_idx] + movdn.8 + # => [ASSET_KEY, ASSET_VALUE, note_idx] - movdn.4 - # => [ASSET, note_idx] # add asset to the note exec.output_note::add_asset - # => [] + # => [...] # clean stack dropw dropw dropw dropw diff --git a/bin/integration-tests/src/asm/custom_p2id.masm b/bin/integration-tests/src/asm/custom_p2id.masm index f7cf717a33..673d2ea8af 100644 --- a/bin/integration-tests/src/asm/custom_p2id.masm +++ b/bin/integration-tests/src/asm/custom_p2id.masm @@ -32,7 +32,7 @@ begin # read first word push.{mem_address} # => [data_mem_address] - mem_loadw_be + mem_loadw_le # => [NOTE_ARG_1] push.{expected_note_arg_1} assert_eqw.err="First note argument didn't match expected" @@ -41,26 +41,28 @@ begin # read second word push.{mem_address_2} # => [data_mem_address_2] - mem_loadw_be + mem_loadw_le # => [NOTE_ARG_2] push.{expected_note_arg_2} assert_eqw.err="Second note argument didn't match expected" # => [] # store the note storage to memory starting at address 0 - padw push.0 exec.active_note::get_storage - # => [num_storage_items, storage_ptr, EMPTY_WORD] + push.0 exec.active_note::get_storage + # => [num_storage_items, storage_ptr] # make sure the number of storage items is 2 eq.2 assert.err="P2ID script expects exactly 2 note storage items" - # => [storage_ptr, EMPTY_WORD] + # => [storage_ptr] - # read the target account id from the note storage - mem_loadw_be drop drop - # => [target_account_id_prefix, target_account_id_suffix] + # read the target account ID from the note storage + drop + mem_load.1 + mem_load.0 + # => [target_account_id_suffix, target_account_id_prefix] exec.active_account::get_id - # => [account_id_prefix, account_id_suffix, target_account_id_prefix, target_account_id_suffix, ...] + # => [account_id_suffix, account_id_prefix, target_account_id_suffix, target_account_id_prefix] # ensure account_id = target_account_id, fails otherwise exec.account_id::is_equal assert.err="P2ID's target account address and transaction address do not match" diff --git a/bin/integration-tests/src/tests/client.rs b/bin/integration-tests/src/tests/client.rs index a8f7bc7bfe..d6b5ceb4a8 100644 --- a/bin/integration-tests/src/tests/client.rs +++ b/bin/integration-tests/src/tests/client.rs @@ -11,19 +11,12 @@ use miden_client::account::{ StorageSlot, StorageSlotName, }; -use miden_client::assembly::{ - CodeBuilder, - DefaultSourceManager, - MastForest, - Module, - ModuleKind, - Path, -}; +use miden_client::assembly::{CodeBuilder, DefaultSourceManager, Module, ModuleKind, Path}; use miden_client::asset::{Asset, FungibleAsset}; use miden_client::auth::RPO_FALCON_SCHEME_ID; use miden_client::builder::ClientBuilder; use miden_client::keystore::FilesystemKeyStore; -use miden_client::note::{NoteFile, NoteScript, NoteType}; +use miden_client::note::{NoteFile, NoteType}; use miden_client::rpc::domain::account::FetchedAccount; use miden_client::store::{ InputNoteRecord, @@ -44,7 +37,7 @@ use miden_client::transaction::{ TransactionRequestBuilder, TransactionStatus, }; -use miden_client::{ClientError, Deserializable, Felt, Serializable}; +use miden_client::{ClientError, Felt}; use miden_client_sqlite_store::ClientBuilderSqliteExt; use tracing::info; @@ -1350,7 +1343,7 @@ pub async fn test_unused_rpc_api(client_config: ClientConfig) -> Result<()> { let mut storage_map = StorageMap::new(); storage_map.insert( StorageMapKey::new([Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)].into()), - [Felt::new(0), Felt::new(0), Felt::new(0), Felt::new(1)].into(), + [Felt::new(1), Felt::new(0), Felt::new(0), Felt::new(0)].into(), )?; let map_slot_name = @@ -1449,19 +1442,9 @@ pub async fn test_unused_rpc_api(client_config: ClientConfig) -> Result<()> { .await .unwrap(); - // Remove debug decorators from original note script, as they are not persisted on submission - // (https://github.com/0xMiden/miden-base/issues/1812) - let mut mast = (*note.script().mast()).clone(); - mast.strip_decorators(); - - // normalize CSR storage to match deserialized form - let mast_bytes = mast.to_bytes(); - let mast = MastForest::read_from_bytes(&mast_bytes)?; - let note_script = NoteScript::from_parts(Arc::new(mast), note.script().entrypoint()); - assert_eq!(node_nullifier.nullifier, nullifier); assert_eq!(node_nullifier_proof.leaf().entries().first().unwrap().0, nullifier.as_word()); - assert_eq!(note_script, retrieved_note_script); + assert_eq!(note.script().root(), retrieved_note_script.root()); assert!(!sync_storage_maps.updates.is_empty()); assert!(!account_vault_info.updates.is_empty()); assert!(!transactions_info.transaction_records.is_empty()); diff --git a/bin/integration-tests/src/tests/config.rs b/bin/integration-tests/src/tests/config.rs index d806686992..fcfd86fc34 100644 --- a/bin/integration-tests/src/tests/config.rs +++ b/bin/integration-tests/src/tests/config.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use anyhow::{Context, Result}; use miden_client::builder::ClientBuilder; -use miden_client::crypto::RpoRandomCoin; +use miden_client::crypto::RandomCoin; use miden_client::rpc::{Endpoint, GrpcClient}; use miden_client::testing::common::{FilesystemKeyStore, TestClient, create_test_store_path}; use miden_client::{DebugMode, Felt}; @@ -61,7 +61,7 @@ impl ClientConfig { let mut rng = rand::rng(); let coin_seed: [u64; 4] = rng.random(); - let rng = RpoRandomCoin::new(coin_seed.map(Felt::new).into()); + let rng = RandomCoin::new(coin_seed.map(Felt::new).into()); let keystore = FilesystemKeyStore::new(auth_path.clone()).with_context(|| { format!("failed to create keystore at path: {}", auth_path.to_string_lossy()) diff --git a/bin/integration-tests/src/tests/custom_transaction.rs b/bin/integration-tests/src/tests/custom_transaction.rs index b1e294ea33..688a8ce9bb 100644 --- a/bin/integration-tests/src/tests/custom_transaction.rs +++ b/bin/integration-tests/src/tests/custom_transaction.rs @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; use miden_client::account::{AccountId, AccountStorageMode}; use miden_client::asset::FungibleAsset; use miden_client::auth::RPO_FALCON_SCHEME_ID; -use miden_client::crypto::{FeltRng, MerkleStore, MerkleTree, NodeIndex, Rpo256, RpoRandomCoin}; +use miden_client::crypto::{FeltRng, MerkleStore, MerkleTree, NodeIndex, Poseidon2, RandomCoin}; use miden_client::note::{ Note, NoteAssets, @@ -17,7 +17,6 @@ use miden_client::testing::common::*; use miden_client::transaction::{ AdviceMap, InputNote, - OutputNote, TransactionRequest, TransactionRequestBuilder, }; @@ -83,7 +82,7 @@ pub async fn test_transaction_request(client_config: ClientConfig) -> Result<()> // If these args were to be modified, the transaction would fail because the note code expects // these exact arguments - let note_args_commitment = Rpo256::hash_elements(&NOTE_ARGS); + let note_args_commitment = Poseidon2::hash_elements(&NOTE_ARGS); let note_args_map = vec![(note.clone(), Some(note_args_commitment))]; let mut advice_map = AdviceMap::default(); @@ -119,7 +118,7 @@ pub async fn test_transaction_request(client_config: ClientConfig) -> Result<()> let transaction_request = TransactionRequestBuilder::new() .input_notes(note_args_map) .custom_script(tx_script) - .script_arg([Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)].into()) + .script_arg([Felt::new(4), Felt::new(3), Felt::new(2), Felt::new(1)].into()) .extend_advice_map(advice_map) .build()?; @@ -186,7 +185,7 @@ pub async fn test_merkle_store(client_config: ClientConfig) -> Result<()> { // If these args were to be modified, the transaction would fail because the note code expects // these exact arguments - let note_args_commitment = Rpo256::hash_elements(&NOTE_ARGS); + let note_args_commitment = Poseidon2::hash_elements(&NOTE_ARGS); let note_args_map = vec![(note, Some(note_args_commitment))]; let mut advice_map = AdviceMap::default(); @@ -207,7 +206,7 @@ pub async fn test_merkle_store(client_config: ClientConfig) -> Result<()> { push.{num_leaves} push.4000 mem_store # merkle root -> mem[4004] - push.{} push.4004 mem_storew_be dropw + push.{} push.4004 mem_storew_le dropw ", merkle_root.to_hex() ); @@ -297,9 +296,8 @@ pub async fn test_onchain_notes_sync_with_tag(client_config: ClientConfig) -> Re let note = Note::new(note_assets, note_metadata, note_recipient); // Send transaction and wait for it to be committed - let tx_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(note.clone())]) - .build()?; + let tx_request = + TransactionRequestBuilder::new().own_output_notes(vec![note.clone()]).build()?; let note = tx_request .expected_output_own_notes() @@ -334,12 +332,11 @@ async fn mint_custom_note( target_account_id: AccountId, ) -> Result { // Prepare transaction - let mut random_coin = RpoRandomCoin::new(Default::default()); + let mut random_coin = RandomCoin::new(Default::default()); let note = create_custom_note(client, faucet_account_id, target_account_id, &mut random_coin)?; - let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(note.clone())]) - .build()?; + let transaction_request = + TransactionRequestBuilder::new().own_output_notes(vec![note.clone()]).build()?; execute_tx_and_sync(client, faucet_account_id, transaction_request).await?; Ok(note) @@ -352,15 +349,15 @@ fn create_custom_note( client: &TestClient, faucet_account_id: AccountId, target_account_id: AccountId, - rng: &mut RpoRandomCoin, + rng: &mut RandomCoin, ) -> Result { - let expected_note_args = NOTE_ARGS.iter().map(|x| x.as_int().to_string()).collect::>(); - let mem_addr: u32 = 1000; + let word_1: Word = NOTE_ARGS[0..4].try_into().unwrap(); + let word_2: Word = NOTE_ARGS[4..8].try_into().unwrap(); let note_script = include_str!("../asm/custom_p2id.masm") - .replace("{expected_note_arg_1}", &expected_note_args[0..=3].join(".")) - .replace("{expected_note_arg_2}", &expected_note_args[4..=7].join(".")) + .replace("{expected_note_arg_1}", &word_1.to_hex()) + .replace("{expected_note_arg_2}", &word_2.to_hex()) .replace("{mem_address}", &mem_addr.to_string()) .replace("{mem_address_2}", &(mem_addr + 4).to_string()); let note_script = client diff --git a/bin/integration-tests/src/tests/fpi.rs b/bin/integration-tests/src/tests/fpi.rs index 7e557ae78c..e0bfe9816b 100644 --- a/bin/integration-tests/src/tests/fpi.rs +++ b/bin/integration-tests/src/tests/fpi.rs @@ -1,9 +1,12 @@ +use std::collections::BTreeMap; + use anyhow::{Context, Result}; use miden_client::account::component::{AccountComponent, AccountComponentMetadata}; use miden_client::account::{ Account, AccountBuilder, AccountStorageMode, + AccountType, PartialAccount, PartialStorage, StorageMap, @@ -78,8 +81,8 @@ pub async fn test_fpi_execute_program(client_config: ClientConfig) -> Result<()> push.{proc_root} # push the foreign account id - push.{account_id_suffix} push.{account_id_prefix} - # => [foreign_id_prefix, foreign_id_suffix, FOREIGN_PROC_ROOT, + push.{account_id_prefix} push.{account_id_suffix} + # => [foreign_id_suffix, foreign_id_prefix, FOREIGN_PROC_ROOT, # slot_id_prefix, slot_id_suffix, KEY, pad(10)] exec.tx::execute_foreign_procedure @@ -121,15 +124,15 @@ pub async fn test_fpi_execute_program(client_config: ClientConfig) -> Result<()> wallet.id(), tx_script, AdviceInputs::default(), - [ForeignAccount::public(foreign_account_id, storage_requirements)?].into(), + BTreeMap::from([( + foreign_account_id, + ForeignAccount::public(foreign_account_id, storage_requirements)?, + )]), ) .await?; let mut expected_stack = [Felt::new(0); 16]; - expected_stack[3] = FPI_STORAGE_VALUE[0]; - expected_stack[2] = FPI_STORAGE_VALUE[1]; - expected_stack[1] = FPI_STORAGE_VALUE[2]; - expected_stack[0] = FPI_STORAGE_VALUE[3]; + expected_stack[..4].copy_from_slice(&FPI_STORAGE_VALUE); assert_eq!(output_stack, expected_stack); Ok(()) @@ -182,8 +185,8 @@ pub async fn test_nested_fpi_calls(client_config: ClientConfig) -> Result<()> { push.{inner_proc_root} # push the foreign account id - push.{account_id_suffix} push.{account_id_prefix} - # => [foreign_id_prefix, foreign_id_suffix, FOREIGN_PROC_ROOT, + push.{account_id_prefix} push.{account_id_suffix} + # => [foreign_id_suffix, foreign_id_prefix, FOREIGN_PROC_ROOT, # slot_id_prefix, slot_id_suffix, KEY, pad(10)] exec.tx::execute_foreign_procedure @@ -219,8 +222,8 @@ pub async fn test_nested_fpi_calls(client_config: ClientConfig) -> Result<()> { push.{outer_proc_root} # push the foreign account id - push.{account_id_suffix} push.{account_id_prefix} - # => [foreign_id_prefix, foreign_id_suffix, FOREIGN_PROC_ROOT, pad(16)] + push.{account_id_prefix} push.{account_id_suffix} + # => [foreign_id_suffix, foreign_id_prefix, FOREIGN_PROC_ROOT, pad(16)] exec.tx::execute_foreign_procedure # => [result(16)] @@ -303,7 +306,7 @@ pub async fn test_lazy_fpi_loading(client_config: ClientConfig) -> Result<()> { use miden::protocol::tx begin push.{proc_root} - push.{account_id_suffix} push.{account_id_prefix} + push.{account_id_prefix} push.{account_id_suffix} exec.tx::execute_foreign_procedure push.{constant_value} assert_eqw end @@ -385,7 +388,7 @@ pub async fn test_lazy_fpi_loading_with_storage_map(client_config: ClientConfig) use miden::protocol::tx begin push.{proc_root} - push.{account_id_suffix} push.{account_id_prefix} + push.{account_id_prefix} push.{account_id_suffix} exec.tx::execute_foreign_procedure push.{fpi_value} assert_eqw end @@ -479,8 +482,8 @@ async fn standard_fpi( push.{proc_root} # push the foreign account id - push.{account_id_suffix} push.{account_id_prefix} - # => [foreign_id_prefix, foreign_id_suffix, FOREIGN_PROC_ROOT, + push.{account_id_prefix} push.{account_id_suffix} + # => [foreign_id_suffix, foreign_id_prefix, FOREIGN_PROC_ROOT, # slot_id_prefix, slot_id_suffix, KEY, pad(10)] exec.tx::execute_foreign_procedure @@ -608,17 +611,17 @@ fn foreign_account_with_code( let get_item_component = AccountComponent::new( component_code, vec![map_slot], - AccountComponentMetadata::new("miden::testing::fpi_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::fpi_component", AccountType::all()), ) .map_err(|err| anyhow::anyhow!(err)) .context("failed to create foreign account component")?; let (key_pair, auth_component) = match auth_scheme { - AuthSchemeId::Falcon512Rpo => { - let key_pair = AuthSecretKey::new_falcon512_rpo(); + AuthSchemeId::Falcon512Poseidon2 => { + let key_pair = AuthSecretKey::new_falcon512_poseidon2(); let auth_component: AccountComponent = AuthSingleSig::new( key_pair.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, ) .into(); (key_pair, auth_component) diff --git a/bin/integration-tests/src/tests/network_fpi.rs b/bin/integration-tests/src/tests/network_fpi.rs index 87179903f8..5927b11d7a 100644 --- a/bin/integration-tests/src/tests/network_fpi.rs +++ b/bin/integration-tests/src/tests/network_fpi.rs @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; use miden_client::account::AccountStorageMode; use miden_client::auth::RPO_FALCON_SCHEME_ID; use miden_client::testing::common::{execute_tx_and_sync, insert_new_wallet, wait_for_blocks}; -use miden_client::transaction::{OutputNote, TransactionRequestBuilder}; +use miden_client::transaction::TransactionRequestBuilder; use miden_client::{Felt, Word, ZERO}; use super::fpi::{FPI_STORAGE_VALUE, MAP_KEY, MAP_SLOT_NAME, deploy_foreign_account}; @@ -101,8 +101,8 @@ pub async fn test_network_fpi(client_config: ClientConfig) -> Result<()> { push.{proc_root} # push the foreign account id - push.{account_id_suffix} push.{account_id_prefix} - # => [foreign_id_prefix, foreign_id_suffix, FOREIGN_PROC_ROOT, pad(16)] + push.{account_id_prefix} push.{account_id_suffix} + # => [foreign_id_suffix, foreign_id_prefix, FOREIGN_PROC_ROOT, pad(16)] exec.tx::execute_foreign_procedure @@ -125,9 +125,7 @@ pub async fn test_network_fpi(client_config: ClientConfig) -> Result<()> { &mut client2.rng(), )?; - let tx_request = TransactionRequestBuilder::new() - .own_output_notes([OutputNote::Full(network_note)]) - .build()?; + let tx_request = TransactionRequestBuilder::new().own_output_notes([network_note]).build()?; execute_tx_and_sync(&mut client2, sender_account.id(), tx_request).await?; @@ -145,7 +143,7 @@ pub async fn test_network_fpi(client_config: ClientConfig) -> Result<()> { assert_eq!( updated_network_account.storage().get_item(&COUNTER_SLOT_NAME)?, - Word::from([ZERO, ZERO, ZERO, Felt::new(2)]) + Word::from([Felt::new(2), ZERO, ZERO, ZERO]) ); Ok(()) diff --git a/bin/integration-tests/src/tests/network_transaction.rs b/bin/integration-tests/src/tests/network_transaction.rs index 7e145e4c99..65f9177c9d 100644 --- a/bin/integration-tests/src/tests/network_transaction.rs +++ b/bin/integration-tests/src/tests/network_transaction.rs @@ -8,6 +8,7 @@ use miden_client::account::{ AccountBuilder, AccountId, AccountStorageMode, + AccountType, StorageSlot, StorageSlotName, }; @@ -39,7 +40,7 @@ use miden_client::testing::common::{ wait_for_blocks, wait_for_tx, }; -use miden_client::transaction::{OutputNote, TransactionKernel, TransactionRequestBuilder}; +use miden_client::transaction::{TransactionKernel, TransactionRequestBuilder}; use miden_client::{Felt, Word, ZERO}; use rand::{Rng, RngCore}; @@ -129,8 +130,7 @@ async fn get_counter_contract_account( let counter_component = AccountComponent::new( counter_code, vec![counter_slot], - AccountComponentMetadata::new("miden::testing::counter_component") - .with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::counter_component", AccountType::all()), ) .map_err(|err| anyhow::anyhow!(err)) .context("failed to create counter contract component")?; @@ -141,7 +141,7 @@ async fn get_counter_contract_account( let incr_nonce_auth = AccountComponent::new( incr_nonce_auth_code, vec![], - AccountComponentMetadata::new("miden::testing::incr_nonce_auth").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::incr_nonce_auth", AccountType::all()), ) .map_err(|err| anyhow::anyhow!(err)) .context("failed to create increment nonce auth component")?; @@ -174,7 +174,7 @@ pub async fn test_counter_contract_ntx(client_config: ClientConfig) -> Result<() .get_storage_item(COUNTER_SLOT_NAME.clone()) .await .context("failed to find network account after deployment")?; - assert_eq!(counter_value, Word::from([ZERO, ZERO, ZERO, Felt::new(1)])); + assert_eq!(counter_value, Word::from([Felt::new(1), ZERO, ZERO, ZERO])); let (native_account, ..) = insert_new_wallet(&mut client, AccountStorageMode::Public, &keystore, RPO_FALCON_SCHEME_ID) @@ -185,7 +185,7 @@ pub async fn test_counter_contract_ntx(client_config: ClientConfig) -> Result<() for _ in 0..BUMP_NOTE_NUMBER { let network_note = get_network_note(native_account.id(), network_account.id(), &mut client.rng())?; - network_notes.push(OutputNote::Full(network_note)); + network_notes.push(network_note); } let tx_request = TransactionRequestBuilder::new().own_output_notes(network_notes).build()?; @@ -193,7 +193,7 @@ pub async fn test_counter_contract_ntx(client_config: ClientConfig) -> Result<() execute_tx_and_sync(&mut client, native_account.id(), tx_request).await?; // Wait for the node to consume the network notes in subsequent blocks - let expected_counter = Word::from([ZERO, ZERO, ZERO, Felt::new(1 + BUMP_NOTE_NUMBER)]); + let expected_counter = Word::from([Felt::new(1 + BUMP_NOTE_NUMBER), ZERO, ZERO, ZERO]); for _ in 0..10 { let a = client .test_rpc_api() @@ -237,7 +237,7 @@ pub async fn test_recall_note_before_ntx_consumes_it(client_config: ClientConfig let network_note = get_network_note(wallet.id(), network_account.id(), &mut client.rng())?; // Prepare both transactions let tx_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(network_note.clone())]) + .own_output_notes(vec![network_note.clone()]) .build()?; let bump_result = client.execute_transaction(wallet.id(), tx_request).await?; @@ -268,7 +268,7 @@ pub async fn test_recall_note_before_ntx_consumes_it(client_config: ClientConfig .get_storage_item(COUNTER_SLOT_NAME.clone()) .await .context("failed to find network account after recall test")?; - assert_eq!(network_counter, Word::from([ZERO, ZERO, ZERO, Felt::new(1)])); + assert_eq!(network_counter, Word::from([Felt::new(1), ZERO, ZERO, ZERO])); // The native account should have the incremented value let native_counter = client @@ -276,7 +276,7 @@ pub async fn test_recall_note_before_ntx_consumes_it(client_config: ClientConfig .get_storage_item(COUNTER_SLOT_NAME.clone()) .await .context("failed to find native account after recall test")?; - assert_eq!(native_counter, Word::from([ZERO, ZERO, ZERO, Felt::new(2)])); + assert_eq!(native_counter, Word::from([Felt::new(2), ZERO, ZERO, ZERO])); Ok(()) } diff --git a/bin/integration-tests/src/tests/pass_through.rs b/bin/integration-tests/src/tests/pass_through.rs index f67819cfb1..399d303d92 100644 --- a/bin/integration-tests/src/tests/pass_through.rs +++ b/bin/integration-tests/src/tests/pass_through.rs @@ -26,7 +26,7 @@ use miden_client::note::{ }; use miden_client::store::{InputNoteState, TransactionFilter}; use miden_client::testing::common::*; -use miden_client::transaction::{OutputNote, TransactionRequestBuilder}; +use miden_client::transaction::TransactionRequestBuilder; use miden_client::{Client, ClientRng, Word}; use rand::RngCore; use tracing::info; @@ -60,14 +60,14 @@ pub async fn test_pass_through(client_config: ClientConfig) -> Result<()> { &mut client, AccountStorageMode::Private, &authenticator_1, - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, ) .await?; let (target, ..) = insert_new_wallet( &mut client_2, AccountStorageMode::Private, &authenticator_2, - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, ) .await?; @@ -78,7 +78,7 @@ pub async fn test_pass_through(client_config: ClientConfig) -> Result<()> { &mut client, AccountStorageMode::Private, &authenticator_1, - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, ) .await?; @@ -100,10 +100,7 @@ pub async fn test_pass_through(client_config: ClientConfig) -> Result<()> { create_pass_through_note(sender.id(), target.id(), asset.into(), client.rng())?; let tx_request = TransactionRequestBuilder::new() - .own_output_notes(vec![ - OutputNote::Full(pass_through_note_1.clone()), - OutputNote::Full(pass_through_note_2.clone()), - ]) + .own_output_notes(vec![pass_through_note_1.clone(), pass_through_note_2.clone()]) .build()?; execute_tx_and_sync(&mut client, sender.id(), tx_request).await?; @@ -205,7 +202,8 @@ async fn create_pass_through_account( .with_allow_unauthorized_output_notes(true); let auth_component = - AuthSingleSigAcl::new(pub_key.into(), AuthSchemeId::Falcon512Rpo, acl_config).unwrap(); + AuthSingleSigAcl::new(pub_key.into(), AuthSchemeId::Falcon512Poseidon2, acl_config) + .unwrap(); let account = AccountBuilder::new(init_seed) .account_type(AccountType::RegularAccountImmutableCode) @@ -236,15 +234,20 @@ fn create_pass_through_note( ) -> Result<(Note, NoteDetails)> { let note_script = get_pass_through_note_script(); - let asset_word: Word = asset.into(); + let asset_key: Word = asset.to_key_word(); + let asset_value: Word = asset.to_value_word(); let target_recipient = P2idNoteStorage::new(target).into_recipient(rng.draw_word()); let inputs = NoteStorage::new(vec![ - asset_word[0], - asset_word[1], - asset_word[2], - asset_word[3], + asset_key[0], + asset_key[1], + asset_key[2], + asset_key[3], + asset_value[0], + asset_value[1], + asset_value[2], + asset_value[3], target_recipient.digest()[0], target_recipient.digest()[1], target_recipient.digest()[2], diff --git a/bin/miden-bench/src/config.rs b/bin/miden-bench/src/config.rs index a52d831246..965aabb51a 100644 --- a/bin/miden-bench/src/config.rs +++ b/bin/miden-bench/src/config.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use miden_client::builder::ClientBuilder; -use miden_client::crypto::RpoRandomCoin; +use miden_client::crypto::RandomCoin; use miden_client::keystore::FilesystemKeyStore; use miden_client::rpc::{Endpoint, GrpcClient}; use miden_client::{Client, DebugMode, Felt}; @@ -45,7 +45,7 @@ pub async fn create_client( let mut rng = rand::rng(); let coin_seed: [u64; 4] = rng.random(); - let rng_coin = RpoRandomCoin::new(coin_seed.map(Felt::new).into()); + let rng_coin = RandomCoin::new(coin_seed.map(Felt::new).into()); let client = ClientBuilder::new() .rpc(Arc::new(GrpcClient::new(endpoint, 30_000))) diff --git a/bin/miden-bench/src/deploy.rs b/bin/miden-bench/src/deploy.rs index 596180aaf0..2dba03b29c 100644 --- a/bin/miden-bench/src/deploy.rs +++ b/bin/miden-bench/src/deploy.rs @@ -55,7 +55,7 @@ fn create_account_with_empty_maps( num_maps: usize, seed: [u8; 32], ) -> anyhow::Result<(Account, AuthSecretKey)> { - let sk = AuthSecretKey::new_falcon512_rpo_with_rng(&mut ChaCha20Rng::from_seed(seed)); + let sk = AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut ChaCha20Rng::from_seed(seed)); // Create empty storage map slots let storage_slots: Vec = (0..num_maps) @@ -76,7 +76,7 @@ fn create_account_with_empty_maps( let expansion_component = AccountComponent::new( expansion_component_code, storage_slots, - AccountComponentMetadata::new("miden::testing::storage_expander").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::storage_expander", AccountType::all()), ) .map_err(|e| anyhow::anyhow!("Failed to create expansion component: {e}"))?; @@ -94,7 +94,7 @@ fn create_account_with_empty_maps( let reader_component = AccountComponent::new( reader_component_code, vec![], - AccountComponentMetadata::new("miden::testing::storage_reader").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::storage_reader", AccountType::all()), ) .map_err(|e| anyhow::anyhow!("Failed to create reader component: {e}"))?; @@ -102,14 +102,14 @@ fn create_account_with_empty_maps( let wallet_component = AccountComponent::new( basic_wallet_library(), vec![], - AccountComponentMetadata::new("miden::testing::basic_wallet").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::basic_wallet", AccountType::all()), ) .expect("basic wallet component should satisfy account component requirements"); let account = AccountBuilder::new(seed) .with_auth_component(AuthSingleSig::new( sk.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .account_type(AccountType::RegularAccountUpdatableCode) .with_component(wallet_component) diff --git a/bin/miden-bench/src/generators/large_account.rs b/bin/miden-bench/src/generators/large_account.rs index 0bf9cf436d..113850145f 100644 --- a/bin/miden-bench/src/generators/large_account.rs +++ b/bin/miden-bench/src/generators/large_account.rs @@ -112,7 +112,8 @@ end fn create_large_account(config: &LargeAccountConfig) -> anyhow::Result<(Account, AuthSecretKey)> { use miden_client::account::component::AccountComponentMetadata; - let sk = AuthSecretKey::new_falcon512_rpo_with_rng(&mut ChaCha20Rng::from_seed(config.seed)); + let sk = + AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut ChaCha20Rng::from_seed(config.seed)); // Create storage map slots let mut storage_slots = Vec::new(); @@ -139,7 +140,7 @@ fn create_large_account(config: &LargeAccountConfig) -> anyhow::Result<(Account, let reader_component = AccountComponent::new( reader_component_code, storage_slots, - AccountComponentMetadata::new("miden::testing::storage_reader").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::storage_reader", AccountType::all()), ) .map_err(|e| anyhow::anyhow!("Failed to create reader component: {e}"))?; @@ -147,14 +148,14 @@ fn create_large_account(config: &LargeAccountConfig) -> anyhow::Result<(Account, let wallet_component = AccountComponent::new( basic_wallet_library(), vec![], - AccountComponentMetadata::new("miden::testing::basic_wallet").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::basic_wallet", AccountType::all()), ) .expect("basic wallet component should satisfy account component requirements"); let account = AccountBuilder::new(config.seed) .with_auth_component(AuthSingleSig::new( sk.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .account_type(AccountType::RegularAccountUpdatableCode) .with_component(wallet_component) @@ -173,7 +174,7 @@ fn create_large_account(config: &LargeAccountConfig) -> anyhow::Result<(Account, pub fn random_word(rng: &mut impl Rng) -> [Felt; 4] { loop { let word: [Felt; 4] = std::array::from_fn(|_| Felt::new(rng.random::() >> 1)); - if word.iter().any(|f| f.as_int() != 0) { + if word.iter().any(|f| f.as_canonical_u64() != 0) { return word; } } diff --git a/bin/miden-bench/src/masm.rs b/bin/miden-bench/src/masm.rs index 3b11c76c56..ef55b8cd14 100644 --- a/bin/miden-bench/src/masm.rs +++ b/bin/miden-bench/src/masm.rs @@ -1,8 +1,8 @@ use std::fmt::Write; -use miden_client::Felt; use miden_client::keystore::FilesystemKeyStore; use miden_client::transaction::TransactionRequestBuilder; +use miden_client::{Felt, Word}; use crate::benchmarks::transaction::{ReadOp, StorageSlotInfo}; use crate::generators::{SlotDescriptor, generate_reader_component_code}; @@ -18,16 +18,8 @@ const MAX_OPS_PER_BLOCK: usize = 7_000; /// Writes the MASM instructions for a single map entry read (push key, call reader, drop result). fn write_read_op_instructions(script: &mut String, op: &ReadOp) { // Push key (4 felts) - let key = op.key.as_word(); - writeln!( - script, - " push.{}.{}.{}.{}", - key[3].as_int(), - key[2].as_int(), - key[1].as_int(), - key[0].as_int() - ) - .expect("write to string should not fail"); + writeln!(script, " push.{}", op.key.as_word().to_hex()) + .expect("write to string should not fail"); // Call the account's reader procedure for this storage map slot. // Stack input: [KEY] @@ -139,9 +131,9 @@ pub fn generate_expansion_tx_script(slot_idx: usize, entries: &[([Felt; 4], [Fel for (key, value) in entries { write!( script, - " push.{}.{}.{}.{}\n push.{}.{}.{}.{}\n call.storage_expander::{procedure_name}\n dropw dropw dropw dropw\n\n", - value[3].as_int(), value[2].as_int(), value[1].as_int(), value[0].as_int(), - key[3].as_int(), key[2].as_int(), key[1].as_int(), key[0].as_int(), + " push.{}\n push.{}\n call.storage_expander::{procedure_name}\n dropw dropw dropw dropw\n\n", + Word::from(*value).to_hex(), + Word::from(*key).to_hex(), ) .expect("write to string should not fail"); } diff --git a/bin/miden-cli/build.rs b/bin/miden-cli/build.rs index 11d673c091..acd4a590a5 100644 --- a/bin/miden-cli/build.rs +++ b/bin/miden-cli/build.rs @@ -41,9 +41,9 @@ const PACKAGE_DIR: &str = "packages"; fn main() { // Basic wallet (no storage schema) - let basic_wallet_metadata = AccountComponentMetadata::new(BasicWallet::NAME) - .with_description("Basic wallet component for receiving and sending assets") - .with_supports_all_types(); + let basic_wallet_metadata = + AccountComponentMetadata::new(BasicWallet::NAME, AccountType::all()) + .with_description("Basic wallet component for receiving and sending assets"); build_package("basic-wallet", basic_wallet_library(), &basic_wallet_metadata, None); // Basic fungible faucet @@ -65,12 +65,13 @@ fn main() { ], ), ); - let basic_faucet_metadata = AccountComponentMetadata::new(BasicFungibleFaucet::NAME) - .with_description("Basic fungible faucet component for minting and burning tokens") - .with_supported_type(AccountType::FungibleFaucet) - .with_storage_schema( - StorageSchema::new([faucet_metadata_schema]).expect("storage schema should be valid"), - ); + let basic_faucet_metadata = + AccountComponentMetadata::new(BasicFungibleFaucet::NAME, [AccountType::FungibleFaucet]) + .with_description("Basic fungible faucet component for minting and burning tokens") + .with_storage_schema( + StorageSchema::new([faucet_metadata_schema]) + .expect("storage schema should be valid"), + ); build_package( "basic-fungible-faucet", basic_fungible_faucet_library(), @@ -79,11 +80,10 @@ fn main() { ); // Basic auth (singlesig - supports both RPO Falcon and ECDSA) - let singlesig_metadata = AccountComponentMetadata::new(AuthSingleSig::NAME) + let singlesig_metadata = AccountComponentMetadata::new(AuthSingleSig::NAME, AccountType::all()) .with_description( "Authentication component using ECDSA K256 Keccak or Rpo Falcon 512 signature scheme", ) - .with_supports_all_types() .with_storage_schema( StorageSchema::new([ AuthSingleSig::public_key_slot_schema(), @@ -99,9 +99,8 @@ fn main() { // No authentication component. Nonce is incremented on first transaction and when the account // state is changed. Provides no cryptographic authentication. - let no_auth_metadata = AccountComponentMetadata::new(NoAuth::NAME) - .with_description("No authentication component") - .with_supports_all_types(); + let no_auth_metadata = AccountComponentMetadata::new(NoAuth::NAME, AccountType::all()) + .with_description("No authentication component"); build_package("no-auth", no_auth_library(), &no_auth_metadata, Some("auth")); // Multisig auth @@ -116,9 +115,8 @@ fn main() { AuthMultisig::approver_scheme_ids_slot().clone(), StorageSlotSchema::map("Approver scheme IDs", SchemaType::u32(), SchemaType::native_word()), ); - let multisig_metadata = AccountComponentMetadata::new(AuthMultisig::NAME) + let multisig_metadata = AccountComponentMetadata::new(AuthMultisig::NAME, AccountType::all()) .with_description("Multisig authentication component using hybrid signature schemes") - .with_supports_all_types() .with_storage_schema( StorageSchema::new([ AuthMultisig::threshold_config_slot_schema(), @@ -133,11 +131,10 @@ fn main() { // ACL auth let acl_metadata = - AccountComponentMetadata::new(AuthSingleSigAcl::NAME) + AccountComponentMetadata::new(AuthSingleSigAcl::NAME, AccountType::all()) .with_description( "Authentication component with procedure-based ACL using ECDSA K256 Keccak or Rpo Falcon 512 signature scheme", ) - .with_supports_all_types() .with_storage_schema( StorageSchema::new([ AuthSingleSigAcl::public_key_slot_schema(), diff --git a/bin/miden-cli/src/commands/account.rs b/bin/miden-cli/src/commands/account.rs index f0e7cfe426..04815e6164 100644 --- a/bin/miden-cli/src/commands/account.rs +++ b/bin/miden-cli/src/commands/account.rs @@ -115,7 +115,7 @@ async fn list_accounts(client: Client) -> Result<(), CliError> { acc.id().to_hex(), account_type_display_name(&acc.id())?, acc.id().storage_mode().to_string(), - acc.nonce().as_int().to_string(), + acc.nonce().as_canonical_u64().to_string(), status, ]); } @@ -136,7 +136,7 @@ pub async fn show_account( let account = if let Some(account) = client.get_account(account_id).await? { account } else { - println!("Account {account_id} is not tracked by the client. Fetching from the network...",); + println!("Account {account_id} is not tracked by the client. Fetching from the network..."); let rpc_client = GrpcClient::new(&cli_config.rpc.endpoint.clone().into(), cli_config.rpc.timeout_ms); @@ -174,7 +174,7 @@ pub async fn show_account( // TODO: Display non-fungible assets more clearly. ( "Non Fungible Asset", - non_fungible_asset.faucet_id_prefix().to_hex(), + non_fungible_asset.faucet_id().prefix().to_hex(), 1.0.to_string(), ) }, @@ -263,7 +263,10 @@ async fn print_summary_table( Cell::new("Storage Root"), Cell::new(account.storage().to_commitment().to_string()), ]); - table.add_row(vec![Cell::new("Nonce"), Cell::new(account.nonce().as_int().to_string())]); + table.add_row(vec![ + Cell::new("Nonce"), + Cell::new(account.nonce().as_canonical_u64().to_string()), + ]); println!("{table}\n"); Ok(()) diff --git a/bin/miden-cli/src/commands/exec.rs b/bin/miden-cli/src/commands/exec.rs index 6d55beef01..fdd57b9e4f 100644 --- a/bin/miden-cli/src/commands/exec.rs +++ b/bin/miden-cli/src/commands/exec.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeSet; +use std::collections::BTreeMap; use std::path::PathBuf; use clap::Parser; @@ -37,7 +37,7 @@ pub struct ExecCmd { /// /// The input file should contain a TOML table called `inputs`, as in the following example: /// inputs = [ - /// { key = "0x0000001000000000000000000000000000000000000000000000000000000000", values = ["13", "9"]}, + /// { key = "0x0000000000000000000000000000000000000000000000000000001000000000", values = ["13", "9"]}, /// { key = "0x0000000000000000000000000000000000000000000000000000000000000000" , values = ["1", "2"]}, /// ] #[arg(long, short)] @@ -88,7 +88,7 @@ impl ExecCmd { let tx_script = client.code_builder().compile_tx_script(&program)?; let result = client - .execute_program(account_id, tx_script, advice_inputs, BTreeSet::new()) + .execute_program(account_id, tx_script, advice_inputs, BTreeMap::new()) .await; match result { diff --git a/bin/miden-cli/src/commands/new_account.rs b/bin/miden-cli/src/commands/new_account.rs index e98d6d9302..aa96c6b632 100644 --- a/bin/miden-cli/src/commands/new_account.rs +++ b/bin/miden-cli/src/commands/new_account.rs @@ -9,6 +9,8 @@ use miden_client::Client; use miden_client::account::component::{ AccountComponent, AccountComponentMetadata, + AuthControlled, + BasicFungibleFaucet, InitStorageData, MIDEN_PACKAGE_EXTENSION, StorageSlotSchema, @@ -106,7 +108,7 @@ impl NewWalletCmd { ) -> Result<(), CliError> { let package_paths: Vec = [PathBuf::from("basic-wallet")] .into_iter() - .chain(self.extra_packages.clone().into_iter()) + .chain(self.extra_packages.clone()) .collect(); // Choose account type based on mutability. @@ -318,8 +320,7 @@ fn separate_auth_components( let mut regular_components = Vec::new(); for component in components { - let auth_proc_count = - component.get_procedures().into_iter().filter(|(_, is_auth)| *is_auth).count(); + let auth_proc_count = component.procedures().filter(|(_, is_auth)| *is_auth).count(); match auth_proc_count { 0 => regular_components.push(component), @@ -342,6 +343,36 @@ fn separate_auth_components( Ok((auth_component, regular_components)) } +/// Returns `true` when the CLI should inject `AuthControlled::allow_all()` for a +/// fungible faucet account built from package components. +/// +/// Why this exists: +/// - RC fungible faucets require a mint policy manager component in addition to +/// `BasicFungibleFaucet`. +/// - The CLI's built-in `basic-fungible-faucet` package only contributes the faucet component +/// itself; it does not include `AuthControlled`. +/// - Other faucet creation paths in this repo add `AuthControlled::allow_all()` explicitly, so the +/// CLI adds it implicitly here to preserve the same behavior and keep the old UX working. +/// +/// What it does: +/// - only applies to `AccountType::FungibleFaucet`, +/// - only triggers when `BasicFungibleFaucet` is present, +/// - and skips injection if an `AuthControlled` component is already present so user-provided mint +/// policy components are not duplicated or overridden. +fn should_add_implicit_auth_controlled( + account_type: AccountType, + regular_components: &[AccountComponent], +) -> bool { + let has_basic_fungible_faucet = regular_components + .iter() + .any(|component| component.metadata().name() == BasicFungibleFaucet::NAME); + let has_auth_controlled = regular_components + .iter() + .any(|component| component.metadata().name() == AuthControlled::NAME); + + account_type == AccountType::FungibleFaucet && has_basic_fungible_faucet && !has_auth_controlled +} + /// Helper function to create the seed, initialize the account builder, add the given components, /// and build the account. /// @@ -381,7 +412,15 @@ async fn create_client_account( // Process packages and separate auth components from regular components let account_components = process_packages(packages, &init_storage_data)?; - let (auth_component, regular_components) = separate_auth_components(account_components)?; + let (auth_component, mut regular_components) = separate_auth_components(account_components)?; + + // Faucet accounts require a mint policy manager component. The CLI's standard + // `basic-fungible-faucet` package only provides the faucet component itself, so add the + // default `allow_all` policy manager implicitly. + if should_add_implicit_auth_controlled(account_type, ®ular_components) { + debug!("Adding implicit AuthControlled mint policy component for fungible faucet"); + regular_components.push(AuthControlled::allow_all().into()); + } // Add the auth component (either from packages or default Falcon) let key_pair = if let Some(auth_component) = auth_component { @@ -390,10 +429,10 @@ async fn create_client_account( None } else { debug!("Adding default Falcon auth component"); - let kp = AuthSecretKey::new_falcon512_rpo_with_rng(client.rng()); + let kp = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); builder = builder.with_auth_component(AuthSingleSig::new( kp.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )); Some(kp) }; @@ -517,3 +556,51 @@ fn process_packages( Ok(account_components) } + +#[cfg(test)] +mod tests { + use miden_client::Felt; + use miden_client::account::component::BasicWallet; + use miden_client::asset::TokenSymbol; + + use super::*; + + #[test] + fn implicit_auth_controlled_is_added_for_basic_faucet_accounts() { + let regular_components = vec![ + BasicFungibleFaucet::new(TokenSymbol::new("BTC").unwrap(), 10, Felt::new(1_000_000)) + .unwrap() + .into(), + ]; + + assert!(should_add_implicit_auth_controlled( + AccountType::FungibleFaucet, + ®ular_components + )); + } + + #[test] + fn implicit_auth_controlled_is_skipped_when_component_already_present() { + let regular_components = vec![ + BasicFungibleFaucet::new(TokenSymbol::new("BTC").unwrap(), 10, Felt::new(1_000_000)) + .unwrap() + .into(), + AuthControlled::allow_all().into(), + ]; + + assert!(!should_add_implicit_auth_controlled( + AccountType::FungibleFaucet, + ®ular_components + )); + } + + #[test] + fn implicit_auth_controlled_is_not_added_for_non_faucet_accounts() { + let regular_components = vec![AccountComponent::from(BasicWallet)]; + + assert!(!should_add_implicit_auth_controlled( + AccountType::RegularAccountImmutableCode, + ®ular_components + )); + } +} diff --git a/bin/miden-cli/src/commands/new_transactions.rs b/bin/miden-cli/src/commands/new_transactions.rs index 761eae2a7d..9f166fd54f 100644 --- a/bin/miden-cli/src/commands/new_transactions.rs +++ b/bin/miden-cli/src/commands/new_transactions.rs @@ -15,8 +15,8 @@ use miden_client::store::NoteRecordError; use miden_client::transaction::{ ExecutedTransaction, InputNote, - OutputNote, PaymentNoteDescription, + RawOutputNote, SwapTransactionData, TransactionRequest, TransactionRequestBuilder, @@ -401,7 +401,7 @@ async fn execute_transaction( let output_notes = executed_transaction .output_notes() .iter() - .map(OutputNote::id) + .map(RawOutputNote::id) .collect::>(); println!("Proving transaction..."); @@ -499,9 +499,9 @@ fn print_transaction_details(executed_tx: &ExecutedTransaction) -> Result<(), Cl let faucet_details_map = load_faucet_details_map()?; let mut table = create_dynamic_table(&["Asset Type", "Faucet ID", "Amount"]); - for (faucet_id, amount) in account_delta.vault().fungible().iter() { - let asset = - FungibleAsset::new(*faucet_id, amount.unsigned_abs()).map_err(CliError::Asset)?; + for (vault_key, amount) in account_delta.vault().fungible().iter() { + let asset = FungibleAsset::new(vault_key.faucet_id(), amount.unsigned_abs()) + .map_err(CliError::Asset)?; let (faucet_fmt, amount_fmt) = faucet_details_map.format_fungible_asset(&asset)?; if amount.is_positive() { @@ -516,14 +516,14 @@ fn print_transaction_details(executed_tx: &ExecutedTransaction) -> Result<(), Cl NonFungibleDeltaAction::Add => { table.add_row(vec![ "Non Fungible Asset", - &asset.faucet_id_prefix().to_hex(), + &asset.faucet_id().prefix().to_hex(), "1", ]); }, NonFungibleDeltaAction::Remove => { table.add_row(vec![ "Non Fungible Asset", - &asset.faucet_id_prefix().to_hex(), + &asset.faucet_id().prefix().to_hex(), "-1", ]); }, diff --git a/bin/miden-cli/src/commands/notes.rs b/bin/miden-cli/src/commands/notes.rs index 2653fde989..80929c72c8 100644 --- a/bin/miden-cli/src/commands/notes.rs +++ b/bin/miden-cli/src/commands/notes.rs @@ -269,7 +269,7 @@ async fn show_note( }, Asset::NonFungible(non_fungible_asset) => ( "Non Fungible Asset", - non_fungible_asset.faucet_id_prefix().to_hex(), + non_fungible_asset.faucet_id().prefix().to_hex(), 1.0.to_string(), ), }; diff --git a/bin/miden-cli/tests/cli.rs b/bin/miden-cli/tests/cli.rs index a9ec2455bc..89ca614e36 100644 --- a/bin/miden-cli/tests/cli.rs +++ b/bin/miden-cli/tests/cli.rs @@ -11,7 +11,7 @@ use miden_client::account::{AccountId, AccountStorageMode}; use miden_client::address::AddressInterface; use miden_client::auth::{RPO_FALCON_SCHEME_ID, TransactionAuthenticator}; use miden_client::builder::ClientBuilder; -use miden_client::crypto::{FeltRng, RpoRandomCoin}; +use miden_client::crypto::{FeltRng, RandomCoin}; use miden_client::keystore::Keystore; use miden_client::note::{ Note, @@ -33,7 +33,7 @@ use miden_client::testing::common::{ execute_tx_and_sync, insert_new_wallet, }; -use miden_client::transaction::{OutputNote, TransactionRequestBuilder}; +use miden_client::transaction::TransactionRequestBuilder; use miden_client::utils::Serializable; use miden_client::{self, Client, DebugMode, Felt}; use miden_client_cli::MIDEN_DIR; @@ -313,7 +313,7 @@ async fn token_symbol_mapping() -> Result<()> { // Create a token symbol mapping file in the MIDEN_DIR directory let token_symbol_map_path = temp_dir.join(MIDEN_DIR).join("token_symbol_map.toml"); let token_symbol_map_content = - format!(r#"BTC = {{ id = "{fungible_faucet_account_id}", decimals = 10 }}"#,); + format!(r#"BTC = {{ id = "{fungible_faucet_account_id}", decimals = 10 }}"#); fs::write(&token_symbol_map_path, token_symbol_map_content).unwrap(); sync_cli(&temp_dir); @@ -379,7 +379,7 @@ async fn import_genesis_accounts_can_be_used_for_transactions() -> Result<()> { let cargo_workspace_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not set"); - let source_path = format!("{cargo_workspace_dir}/../../data/{genesis_account_filename}",); + let source_path = format!("{cargo_workspace_dir}/../../data/{genesis_account_filename}"); std::fs::copy(source_path, new_file_path).unwrap(); } @@ -626,6 +626,9 @@ async fn consume_unauthenticated_note() -> Result<()> { // Mint let note_id = mint_cli(&temp_dir, &wallet_account_id, &fungible_faucet_account_id); + // Wait for the mint transaction to be committed on the node + sync_until_committed_transaction(&temp_dir); + // Consume the note, internally this checks that the note was consumed correctly consume_note_cli(&temp_dir, &wallet_account_id, &[¬e_id]); Ok(()) @@ -713,9 +716,8 @@ async fn debug_mode_outputs_logs() -> Result<()> { // Send transaction and wait for it to be committed client.sync_state().await?; - let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(note.clone())]) - .build()?; + let transaction_request = + TransactionRequestBuilder::new().own_output_notes(vec![note.clone()]).build()?; execute_tx_and_sync(&mut client, account.id(), transaction_request).await?; // Export the note @@ -906,7 +908,7 @@ async fn new_wallet_with_deploy_flag() -> Result<()> { // Verify that the nonce is non-zero (account was deployed) // By convention, a nonce of 0 indicates an undeployed account assert!( - nonce.as_int() > 0, + nonce.as_canonical_u64() > 0, "Account nonce should be non-zero after deployment, but got: {nonce}" ); @@ -1143,8 +1145,9 @@ fn new_wallet_cli(cli_path: &Path, storage_mode: AccountStorageMode) -> String { output.status.success(), "Failed to create wallet {}", String::from_utf8(output.stderr) - .map(|err_msg| format!("with error: {err_msg}")) - .unwrap_or(". Also failed to access the Command's stderr".to_string()) + .map_or(". Also failed to access the Command's stderr".to_string(), |err_msg| format!( + "with error: {err_msg}" + )) ); std::str::from_utf8(&output.stdout) @@ -1171,7 +1174,7 @@ async fn create_rust_client_with_store_path( let mut rng = rand::rng(); let coin_seed: [u64; 4] = rng.random(); - let rng = Box::new(RpoRandomCoin::new(coin_seed.map(Felt::new).into())); + let rng = Box::new(RandomCoin::new(coin_seed.map(Felt::new).into())); let keystore = FilesystemKeyStore::new(temp_dir())?; @@ -1320,7 +1323,7 @@ fn create_account_with_acl_auth() { // Create init storage data file for acl-auth with a test public key let init_storage_data_toml = r#" "miden::standards::auth::singlesig_acl::pub_key" = "0x0000000000000000000000000000000000000000000000000000000000000001" - "miden::standards::auth::singlesig_acl::scheme" = "Falcon512Rpo" + "miden::standards::auth::singlesig_acl::scheme" = "Falcon512Poseidon2" "miden::standards::auth::singlesig_acl::config.num_trigger_procs" = "1" "miden::standards::auth::singlesig_acl::config.allow_unauthorized_output_notes" = "0" "miden::standards::auth::singlesig_acl::config.allow_unauthorized_input_notes" = "0" diff --git a/bin/miden-cli/tests/files/test_cli_advice_inputs_expect_success.masm b/bin/miden-cli/tests/files/test_cli_advice_inputs_expect_success.masm index 031081d11e..f610abaaa2 100644 --- a/bin/miden-cli/tests/files/test_cli_advice_inputs_expect_success.masm +++ b/bin/miden-cli/tests/files/test_cli_advice_inputs_expect_success.masm @@ -4,7 +4,7 @@ begin - # push the key for the advice map onto the stack ("0x0000001000000000000000000000000000000000000000000000000000000000") + # push the key for the advice map onto the stack ("0x0000000000000000000000000000000000000000000000000000001000000000") push.268435456.0.0.0 ## load the values associated with the key from the advice map onto the advice stack diff --git a/bin/miden-cli/tests/files/test_cli_advice_inputs_input.toml b/bin/miden-cli/tests/files/test_cli_advice_inputs_input.toml index 3ff6fb2b55..4c8397f185 100644 --- a/bin/miden-cli/tests/files/test_cli_advice_inputs_input.toml +++ b/bin/miden-cli/tests/files/test_cli_advice_inputs_input.toml @@ -3,7 +3,7 @@ inputs = [ "1", "2", ] }, - { key = "0x0000001000000000000000000000000000000000000000000000000000000000", values = [ + { key = "0x0000000000000000000000000000000000000000000000000000001000000000", values = [ "13", "9", ] }, diff --git a/crates/idxdb-store/src/account/js_bindings.rs b/crates/idxdb-store/src/account/js_bindings.rs index ed0e83de30..e8c78701e5 100644 --- a/crates/idxdb-store/src/account/js_bindings.rs +++ b/crates/idxdb-store/src/account/js_bindings.rs @@ -1,7 +1,6 @@ use alloc::string::String; use alloc::vec::Vec; -use miden_client::Word; use miden_client::account::{StorageMap, StorageSlot}; use miden_client::asset::Asset; use miden_client::utils::Serializable; @@ -184,9 +183,9 @@ pub struct JsVaultAsset { impl JsVaultAsset { pub fn from_asset(asset: &Asset) -> Self { Self { - vault_key: Word::from(asset.vault_key()).to_hex(), - faucet_id_prefix: asset.faucet_id_prefix().to_hex(), - asset: Word::from(asset).to_hex(), + vault_key: asset.vault_key().to_string(), + faucet_id_prefix: asset.faucet_id().prefix().to_hex(), + asset: asset.to_value_word().to_hex(), } } } diff --git a/crates/idxdb-store/src/account/mod.rs b/crates/idxdb-store/src/account/mod.rs index 3f1394e4db..f53f575a24 100644 --- a/crates/idxdb-store/src/account/mod.rs +++ b/crates/idxdb-store/src/account/mod.rs @@ -396,9 +396,10 @@ impl IdxdbStore { let assets = vault_assets_idxdb .into_iter() - .map(|asset| { - let word = Word::try_from(&asset.asset)?; - Ok(Asset::try_from(word)?) + .map(|entry| { + let key_word = Word::try_from(&entry.vault_key)?; + let value_word = Word::try_from(&entry.asset)?; + Ok(Asset::from_key_value_words(key_word, value_word)?) }) .collect::, StoreError>>()?; @@ -436,24 +437,24 @@ impl IdxdbStore { initial_address: Address, ) -> Result<(), StoreError> { upsert_account_code(self.db_id(), account.code()).await.map_err(|js_error| { - StoreError::DatabaseError(format!("failed to insert account code: {js_error:?}",)) + StoreError::DatabaseError(format!("failed to insert account code: {js_error:?}")) })?; - let nonce = account.nonce().as_int(); + let nonce = account.nonce().as_canonical_u64(); upsert_account_storage(self.db_id(), &account.id(), nonce, account.storage()) .await .map_err(|js_error| { - StoreError::DatabaseError(format!("failed to insert account storage:{js_error:?}",)) + StoreError::DatabaseError(format!("failed to insert account storage:{js_error:?}")) })?; upsert_account_asset_vault(self.db_id(), &account.id(), nonce, account.vault()) .await .map_err(|js_error| { - StoreError::DatabaseError(format!("failed to insert account vault:{js_error:?}",)) + StoreError::DatabaseError(format!("failed to insert account vault:{js_error:?}")) })?; upsert_account_record(self.db_id(), account).await.map_err(|js_error| { - StoreError::DatabaseError(format!("failed to insert account record: {js_error:?}",)) + StoreError::DatabaseError(format!("failed to insert account record: {js_error:?}")) })?; insert_account_address(self.db_id(), &account.id(), initial_address) diff --git a/crates/idxdb-store/src/account/models.rs b/crates/idxdb-store/src/account/models.rs index a517fc39a6..f5361886bf 100644 --- a/crates/idxdb-store/src/account/models.rs +++ b/crates/idxdb-store/src/account/models.rs @@ -33,6 +33,7 @@ pub struct StorageMapEntryIdxdbObject { #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AccountAssetIdxdbObject { + pub vault_key: String, pub asset: String, } diff --git a/crates/idxdb-store/src/account/utils.rs b/crates/idxdb-store/src/account/utils.rs index 545aed9f38..5dd492760b 100644 --- a/crates/idxdb-store/src/account/utils.rs +++ b/crates/idxdb-store/src/account/utils.rs @@ -212,7 +212,7 @@ pub fn compute_storage_delta( let old_root = old_map_roots.get(slot_name).copied().unwrap_or(default_map_root); let new_root = smt_forest.update_storage_map_nodes( old_root, - map_delta.entries().iter().map(|(key, value)| (*key.inner(), *value)), + map_delta.entries().iter().map(|(key, value)| (*key, *value)), )?; updated_slots.insert(slot_name.clone(), (new_root, StorageSlotType::Map)); } @@ -236,16 +236,16 @@ pub fn compute_vault_delta( let mut fungible_map: BTreeMap = old_vault_assets .iter() .filter_map(|asset| match asset { - Asset::Fungible(fa) => Some((fa.faucet_id_prefix(), *fa)), + Asset::Fungible(fa) => Some((fa.faucet_id().prefix(), *fa)), Asset::NonFungible(_) => None, }) .collect(); // Process fungible deltas for (faucet_id, delta_amount) in delta.vault().fungible().iter() { - let delta_asset = FungibleAsset::new(*faucet_id, delta_amount.unsigned_abs())?; + let delta_asset = FungibleAsset::new(faucet_id.faucet_id(), delta_amount.unsigned_abs())?; - let asset = match fungible_map.remove(&faucet_id.prefix()) { + let asset = match fungible_map.remove(&faucet_id.faucet_id().prefix()) { Some(existing) => { if *delta_amount >= 0 { existing.add(delta_asset)? @@ -318,7 +318,7 @@ pub async fn apply_transaction_delta( changed_map_entries.push(JsStorageMapEntry { slot_name: slot_name.to_string(), - key: key.inner().to_hex(), + key: Word::from(*key).to_hex(), value: value_str, }); } @@ -330,8 +330,8 @@ pub async fn apply_transaction_delta( for vault_key in removed_vault_keys { changed_assets.push(JsVaultAsset { - vault_key: Word::from(*vault_key).to_hex(), - faucet_id_prefix: vault_key.faucet_id_prefix().to_hex(), + vault_key: vault_key.to_string(), + faucet_id_prefix: vault_key.faucet_id().prefix().to_hex(), asset: String::new(), }); } diff --git a/crates/idxdb-store/src/transaction/mod.rs b/crates/idxdb-store/src/transaction/mod.rs index be7389b7e5..75b73ac8de 100644 --- a/crates/idxdb-store/src/transaction/mod.rs +++ b/crates/idxdb-store/src/transaction/mod.rs @@ -121,7 +121,7 @@ impl IdxdbStore { .vault() .fungible() .iter() - .map(|(faucet_id, _)| faucet_id.prefix().to_hex()) + .map(|(faucet_id, _)| faucet_id.faucet_id().prefix().to_hex()) .collect(); let old_vault_assets = self.get_vault_assets(account_id, fungible_faucet_prefixes).await?; diff --git a/crates/rust-client/Cargo.toml b/crates/rust-client/Cargo.toml index ba205cf2f3..0cc167f55d 100644 --- a/crates/rust-client/Cargo.toml +++ b/crates/rust-client/Cargo.toml @@ -26,6 +26,7 @@ crate-type = ["lib"] [features] default = ["std"] std = [ + "dep:tokio", "miden-protocol/std", "miden-remote-prover-client/std", "miden-remote-prover-client/tx-prover", @@ -39,7 +40,6 @@ tonic = [] [dependencies] # Miden dependencies -miden-mast-package = { default-features = false, version = "0.20" } miden-protocol = { workspace = true } miden-remote-prover-client = { default-features = false, features = ["tx-prover"], workspace = true } miden-standards = { workspace = true } @@ -58,6 +58,7 @@ rand = { workspace = true } serde = { workspace = true } serde_json = { version = "1.0" } thiserror = { workspace = true } +tokio = { features = ["time"], optional = true, workspace = true } tonic = { default-features = false, features = ["codegen"], version = "0.14" } tonic-health = { version = "0.14" } tonic-prost = { version = "0.14" } @@ -66,6 +67,7 @@ uuid = { features = ["js", "serde", "v4"], optional = true, version = "1 [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { features = ["wasm_js"], version = "0.3" } +gloo-timers = { features = ["futures"], version = "0.3" } tonic-web-wasm-client = { default-features = false, version = "0.9" } web-sys = { features = ["Storage", "Window", "console"], version = "0.3" } diff --git a/crates/rust-client/src/account/account_reader.rs b/crates/rust-client/src/account/account_reader.rs index 17198cebbd..85ae3a12eb 100644 --- a/crates/rust-client/src/account/account_reader.rs +++ b/crates/rust-client/src/account/account_reader.rs @@ -119,7 +119,7 @@ impl AccountReader { /// To load the entire vault, use /// [`Client::get_account_vault`](crate::Client::get_account_vault). pub async fn get_balance(&self, faucet_id: AccountId) -> Result { - if let Some(vault_key) = AssetVaultKey::from_account_id(faucet_id) + if let Some(vault_key) = AssetVaultKey::new_fungible(faucet_id) && let Some((Asset::Fungible(fungible_asset), _)) = self.store.get_account_asset(self.account_id, vault_key).await? { diff --git a/crates/rust-client/src/account/mod.rs b/crates/rust-client/src/account/mod.rs index 17e70fbcfa..7a8da9e1fa 100644 --- a/crates/rust-client/src/account/mod.rs +++ b/crates/rust-client/src/account/mod.rs @@ -77,7 +77,6 @@ pub use miden_standards::account::interface::AccountInterfaceExt; use miden_standards::account::wallets::BasicWallet; use super::Client; -use crate::auth::AuthSchemeId; use crate::errors::ClientError; use crate::rpc::domain::account::FetchedAccount; use crate::rpc::node::{EndpointError, GetAccountError}; @@ -106,9 +105,14 @@ pub mod component { no_auth_library, singlesig_acl_library, singlesig_library, - storage_schema_library, }; pub use miden_standards::account::faucets::{BasicFungibleFaucet, NetworkFungibleFaucet}; + pub use miden_standards::account::mint_policies::{ + AuthControlled, + AuthControlledInitConfig, + OwnerControlled, + OwnerControlledInitConfig, + }; pub use miden_standards::account::wallets::BasicWallet; } @@ -192,7 +196,7 @@ impl Client { return Err(ClientError::AccountAlreadyTracked(account.id())); } - if tracked_account.nonce().as_int() > account.nonce().as_int() { + if tracked_account.nonce().as_canonical_u64() > account.nonce().as_canonical_u64() { // If the new account is older than the one being tracked, return an error return Err(ClientError::AccountNonceTooLow); } @@ -424,22 +428,8 @@ pub fn build_wallet_id( }; let auth_scheme = public_key.auth_scheme(); - let auth_component = match auth_scheme { - AuthSchemeId::Falcon512Rpo => { - let auth_component: AccountComponent = - AuthSingleSig::new(public_key.to_commitment(), AuthSchemeId::Falcon512Rpo).into(); - auth_component - }, - AuthSchemeId::EcdsaK256Keccak => { - let auth_component: AccountComponent = - AuthSingleSig::new(public_key.to_commitment(), AuthSchemeId::EcdsaK256Keccak) - .into(); - auth_component - }, - auth_scheme => { - return Err(ClientError::UnsupportedAuthSchemeId(auth_scheme.as_u8())); - }, - }; + let auth_component: AccountComponent = + AuthSingleSig::new(public_key.to_commitment(), auth_scheme).into(); let account = AccountBuilder::new(init_seed) .account_type(account_type) diff --git a/crates/rust-client/src/builder.rs b/crates/rust-client/src/builder.rs index 030080e2ca..7a10e57f24 100644 --- a/crates/rust-client/src/builder.rs +++ b/crates/rust-client/src/builder.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use miden_protocol::assembly::{DefaultSourceManager, SourceManagerSync}; use miden_protocol::block::BlockNumber; -use miden_protocol::crypto::rand::RpoRandomCoin; +use miden_protocol::crypto::rand::RandomCoin; use miden_protocol::{Felt, MAX_TX_EXECUTION_CYCLES, MIN_TX_EXECUTION_CYCLES}; use miden_tx::{ExecutionOptions, LocalTransactionProver}; use rand::Rng; @@ -412,7 +412,7 @@ where } else { let mut seed_rng = rand::rng(); let coin_seed: [u64; 4] = seed_rng.random(); - Box::new(RpoRandomCoin::new(coin_seed.map(Felt::new).into())) + Box::new(RandomCoin::new(coin_seed.map(Felt::new).into())) }; // Set default prover if not provided @@ -468,6 +468,7 @@ where exec_options: ExecutionOptions::new( Some(MAX_TX_EXECUTION_CYCLES), MIN_TX_EXECUTION_CYCLES, + ExecutionOptions::DEFAULT_CORE_TRACE_FRAGMENT_SIZE, false, self.in_debug_mode.into(), ) diff --git a/crates/rust-client/src/errors.rs b/crates/rust-client/src/errors.rs index 39b1c4368b..dd21f3f49f 100644 --- a/crates/rust-client/src/errors.rs +++ b/crates/rust-client/src/errors.rs @@ -18,7 +18,8 @@ use miden_standards::account::interface::AccountInterfaceError; // ================================================================================================ pub use miden_standards::errors::CodeBuilderError; pub use miden_tx::AuthenticationError; -use miden_tx::utils::{DeserializationError, HexParseError}; +use miden_tx::utils::HexParseError; +use miden_tx::utils::serde::DeserializationError; use miden_tx::{NoteCheckerError, TransactionExecutorError, TransactionProverError}; use thiserror::Error; diff --git a/crates/rust-client/src/keystore/fs_keystore.rs b/crates/rust-client/src/keystore/fs_keystore.rs index ae21d52eab..973cd6c4c8 100644 --- a/crates/rust-client/src/keystore/fs_keystore.rs +++ b/crates/rust-client/src/keystore/fs_keystore.rs @@ -13,8 +13,8 @@ use miden_protocol::account::AccountId; use miden_protocol::account::auth::{AuthSecretKey, PublicKey, PublicKeyCommitment, Signature}; use miden_tx::AuthenticationError; use miden_tx::auth::{SigningInputs, TransactionAuthenticator}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use miden_tx::utils::sync::RwLock; -use miden_tx::utils::{Deserializable, Serializable}; use serde::{Deserialize, Serialize}; use super::{KeyStoreError, Keystore}; @@ -79,14 +79,18 @@ impl KeyIndex { /// Saves the index to disk atomically (write to temp file, then rename). fn write_to_file(&self, keys_directory: &Path) -> Result<(), KeyStoreError> { let index_path = keys_directory.join(INDEX_FILE_NAME); - let temp_path = std::env::temp_dir().join(INDEX_FILE_NAME); - let contents = serde_json::to_string_pretty(self).map_err(|err| { KeyStoreError::StorageError(format!("error serializing index: {err:?}")) })?; - // Write to temp file - let mut file = fs::File::create(&temp_path) + let temp_path = unique_temp_index_path(keys_directory); + + // Write to a temp file in the keystore directory so the final rename is isolated from + // other test runs and stays on the same filesystem. + let mut file = fs::OpenOptions::new() + .write(true) + .create_new(true) + .open(&temp_path) .map_err(keystore_error("error creating temp index file"))?; file.write_all(contents.as_bytes()) .map_err(keystore_error("error writing temp index file"))?; @@ -331,6 +335,10 @@ fn key_file_path(keys_directory: &Path, pub_key: PublicKeyCommitment) -> PathBuf keys_directory.join(filename) } +fn unique_temp_index_path(keys_directory: &Path) -> PathBuf { + keys_directory.join(format!(".{INDEX_FILE_NAME}.tmp-{}", rand::random::())) +} + /// Writes an [`AuthSecretKey`] into a file with restrictive permissions (0600 on Unix). #[cfg(unix)] fn write_secret_key_file(file_path: &Path, key: &AuthSecretKey) -> Result<(), KeyStoreError> { diff --git a/crates/rust-client/src/lib.rs b/crates/rust-client/src/lib.rs index 9e093f90f1..6624ee568e 100644 --- a/crates/rust-client/src/lib.rs +++ b/crates/rust-client/src/lib.rs @@ -135,7 +135,7 @@ mod test_utils; pub mod errors; -pub use miden_protocol::utils::{Deserializable, Serializable, SliceReader}; +pub use miden_protocol::utils::serde::{Deserializable, Serializable, SliceReader}; // RE-EXPORTS // ================================================================================================ @@ -212,8 +212,21 @@ pub mod auth { pub use crate::account::component::AuthScheme; - pub const RPO_FALCON_SCHEME_ID: AuthSchemeId = AuthSchemeId::Falcon512Rpo; + pub const RPO_FALCON_SCHEME_ID: AuthSchemeId = AuthSchemeId::Falcon512Poseidon2; pub const ECDSA_K256_KECCAK_SCHEME_ID: AuthSchemeId = AuthSchemeId::EcdsaK256Keccak; + + /// Creates a new authentication secret key for the given scheme using the default RNG. + /// + /// # Errors + /// Returns an error if the given scheme is not supported. + #[cfg(feature = "std")] + pub fn new_auth_secret_key(scheme: AuthSchemeId) -> Result { + match scheme { + AuthSchemeId::Falcon512Poseidon2 => Ok(AuthSecretKey::new_falcon512_poseidon2()), + AuthSchemeId::EcdsaK256Keccak => Ok(AuthSecretKey::new_ecdsa_k256_keccak()), + _ => Err(crate::ClientError::UnsupportedAuthSchemeId(scheme.as_u8())), + } + } } /// Provides types for working with blocks within the Miden network. @@ -226,9 +239,14 @@ pub mod block { /// the `miden_standards` crate. pub mod crypto { pub mod rpo_falcon512 { - pub use miden_protocol::crypto::dsa::falcon512_rpo::{PublicKey, SecretKey, Signature}; + pub use miden_protocol::crypto::dsa::falcon512_poseidon2::{ + PublicKey, + SecretKey, + Signature, + }; } - pub use miden_protocol::crypto::hash::blake::{Blake3_160, Blake3Digest}; + pub use miden_protocol::crypto::hash::blake::Blake3Digest; + pub use miden_protocol::crypto::hash::poseidon2::Poseidon2; pub use miden_protocol::crypto::hash::rpo::Rpo256; pub use miden_protocol::crypto::merkle::mmr::{ Forest, @@ -255,7 +273,7 @@ pub mod crypto { NodeIndex, SparseMerklePath, }; - pub use miden_protocol::crypto::rand::{FeltRng, RpoRandomCoin}; + pub use miden_protocol::crypto::rand::{FeltRng, RandomCoin}; } /// Provides types for working with addresses within the Miden network. @@ -272,8 +290,6 @@ pub mod address { /// Provides types for working with the virtual machine within the Miden network. pub mod vm { - // TODO: Remove this re-export once miden-protocol exposes PackageKind/ProcedureExport. - pub use miden_mast_package::{PackageKind, ProcedureExport}; pub use miden_protocol::vm::{ AdviceInputs, AdviceMap, @@ -281,7 +297,9 @@ pub mod vm { MastArtifact, Package, PackageExport, + PackageKind, PackageManifest, + ProcedureExport, Program, QualifiedProcedureName, Section, @@ -299,7 +317,6 @@ pub use miden_protocol::{ MIN_TX_EXECUTION_CYCLES, ONE, PrettyPrint, - StarkField, Word, ZERO, }; diff --git a/crates/rust-client/src/note_transport/errors.rs b/crates/rust-client/src/note_transport/errors.rs index 147e131bc8..7b2c8e7d6d 100644 --- a/crates/rust-client/src/note_transport/errors.rs +++ b/crates/rust-client/src/note_transport/errors.rs @@ -2,7 +2,7 @@ use alloc::boxed::Box; use alloc::string::String; use core::error::Error; -use miden_protocol::utils::DeserializationError; +use miden_protocol::utils::serde::DeserializationError; use thiserror::Error; #[derive(Debug, Error)] diff --git a/crates/rust-client/src/note_transport/grpc.rs b/crates/rust-client/src/note_transport/grpc.rs index e6eaaa9926..123c1d297b 100644 --- a/crates/rust-client/src/note_transport/grpc.rs +++ b/crates/rust-client/src/note_transport/grpc.rs @@ -6,7 +6,7 @@ use core::task::{Context, Poll}; use futures::Stream; use miden_protocol::note::{NoteHeader, NoteTag}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use miden_tx::utils::sync::RwLock; use tonic::{Request, Streaming}; use tonic_health::pb::HealthCheckRequest; diff --git a/crates/rust-client/src/note_transport/mod.rs b/crates/rust-client/src/note_transport/mod.rs index f2ee091623..89d60d705c 100644 --- a/crates/rust-client/src/note_transport/mod.rs +++ b/crates/rust-client/src/note_transport/mod.rs @@ -10,9 +10,15 @@ use alloc::vec::Vec; use futures::Stream; use miden_protocol::address::Address; use miden_protocol::note::{Note, NoteDetails, NoteFile, NoteHeader, NoteTag}; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use miden_tx::auth::TransactionAuthenticator; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, SliceReader}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + SliceReader, +}; pub use self::errors::NoteTransportError; use crate::{Client, ClientError}; diff --git a/crates/rust-client/src/rpc/domain/account.rs b/crates/rust-client/src/rpc/domain/account.rs index 8d46207bbf..08f91dca22 100644 --- a/crates/rust-client/src/rpc/domain/account.rs +++ b/crates/rust-client/src/rpc/domain/account.rs @@ -13,7 +13,8 @@ use miden_protocol::block::BlockNumber; use miden_protocol::block::account_tree::AccountWitness; use miden_protocol::crypto::merkle::SparseMerklePath; use miden_protocol::crypto::merkle::smt::SmtProof; -use miden_tx::utils::{Deserializable, Serializable, ToHex}; +use miden_tx::utils::ToHex; +use miden_tx::utils::serde::{Deserializable, Serializable}; use thiserror::Error; use crate::alloc::borrow::ToOwned; @@ -475,16 +476,8 @@ impl TryFrom for AccountVaultDetails { let assets = value .assets .into_iter() - .map(|asset| { - let native_digest: Word = asset - .asset - .ok_or(proto::rpc::AccountVaultDetails::missing_field(stringify!(assets)))? - .try_into()?; - native_digest - .try_into() - .map_err(|_| RpcError::DeserializationError("asset".to_string())) - }) - .collect::, RpcError>>()?; + .map(Asset::try_from) + .collect::, _>>()?; Ok(Self { too_many_assets, assets }) } @@ -681,15 +674,15 @@ impl From for Vec { } impl Serializable for AccountStorageRequirements { - fn write_into(&self, target: &mut W) { + fn write_into(&self, target: &mut W) { target.write(&self.0); } } impl Deserializable for AccountStorageRequirements { - fn read_from( + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { Ok(AccountStorageRequirements(source.read()?)) } } diff --git a/crates/rust-client/src/rpc/domain/account_vault.rs b/crates/rust-client/src/rpc/domain/account_vault.rs index 40f11e5f6e..443f71c50e 100644 --- a/crates/rust-client/src/rpc/domain/account_vault.rs +++ b/crates/rust-client/src/rpc/domain/account_vault.rs @@ -4,10 +4,29 @@ use alloc::vec::Vec; use miden_protocol::Word; use miden_protocol::asset::{Asset, AssetVaultKey}; use miden_protocol::block::BlockNumber; -use miden_protocol::errors::AssetError; use crate::rpc::domain::MissingFieldHelper; -use crate::rpc::{RpcError, generated as proto}; +use crate::rpc::{RpcConversionError, RpcError, generated as proto}; + +// ASSET CONVERSION +// ================================================================================================ + +impl TryFrom for Asset { + type Error = RpcConversionError; + + fn try_from(value: proto::primitives::Asset) -> Result { + let key_word: Word = value + .key + .ok_or(proto::primitives::Asset::missing_field(stringify!(key)))? + .try_into()?; + let value_word: Word = value + .value + .ok_or(proto::primitives::Asset::missing_field(stringify!(value)))? + .try_into()?; + Asset::from_key_value_words(key_word, value_word) + .map_err(|e| RpcConversionError::InvalidField(e.to_string())) + } +} // ACCOUNT VAULT INFO // ================================================================================================ @@ -70,32 +89,28 @@ pub struct AccountVaultUpdate { // ACCOUNT VAULT UPDATE CONVERSION // ================================================================================================ -impl TryFrom for Asset { - type Error = RpcError; - - fn try_from(value: proto::primitives::Asset) -> Result { - let word: Word = value - .asset - .ok_or(proto::rpc::SyncAccountVaultResponse::missing_field(stringify!(asset)))? - .try_into()?; - word.try_into() - .map_err(|e: AssetError| RpcError::InvalidResponse(e.to_string())) - } -} - impl TryFrom for AccountVaultUpdate { type Error = RpcError; fn try_from(value: proto::rpc::AccountVaultUpdate) -> Result { let block_num = value.block_num; - let asset: Option = value.asset.map(TryInto::try_into).transpose()?; - let vault_key_inner: Word = value .vault_key .ok_or(proto::rpc::SyncAccountVaultResponse::missing_field(stringify!(vault_key)))? .try_into()?; - let vault_key = AssetVaultKey::new_unchecked(vault_key_inner); + let vault_key = AssetVaultKey::try_from(vault_key_inner) + .map_err(|e| RpcError::InvalidResponse(e.to_string()))?; + + let asset = value.asset.map(Asset::try_from).transpose()?; + + if let Some(ref asset) = asset + && asset.vault_key() != vault_key + { + return Err(RpcError::InvalidResponse( + "account vault update returned mismatched asset key".to_string(), + )); + } Ok(Self { block_num: block_num.into(), diff --git a/crates/rust-client/src/rpc/domain/block.rs b/crates/rust-client/src/rpc/domain/block.rs index 9059ee7c08..fcb109536c 100644 --- a/crates/rust-client/src/rpc/domain/block.rs +++ b/crates/rust-client/src/rpc/domain/block.rs @@ -1,6 +1,6 @@ use miden_protocol::block::{BlockHeader, BlockNumber, FeeParameters}; use miden_protocol::crypto::dsa::ecdsa_k256_keccak; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::utils::serde::{Deserializable, Serializable}; use crate::rpc::domain::MissingFieldHelper; use crate::rpc::errors::RpcConversionError; diff --git a/crates/rust-client/src/rpc/domain/digest.rs b/crates/rust-client/src/rpc/domain/digest.rs index b05e3f04cb..dd0cb2f8a7 100644 --- a/crates/rust-client/src/rpc/domain/digest.rs +++ b/crates/rust-client/src/rpc/domain/digest.rs @@ -4,7 +4,7 @@ use core::fmt::{self, Debug, Display, Formatter}; use hex::ToHex; use miden_protocol::account::StorageMapKey; use miden_protocol::note::NoteId; -use miden_protocol::{Felt, StarkField, Word}; +use miden_protocol::{Felt, Word}; use crate::rpc::errors::RpcConversionError; use crate::rpc::generated as proto; @@ -62,10 +62,10 @@ impl ToHex 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(), } } } @@ -95,10 +95,7 @@ impl TryFrom for [Felt; 4] { type Error = RpcConversionError; fn try_from(value: proto::primitives::Digest) -> Result { - if [value.d0, value.d1, value.d2, value.d3] - .iter() - .all(|v| *v < ::MODULUS) - { + if [value.d0, value.d1, value.d2, value.d3].iter().all(|v| *v < Felt::ORDER) { Ok([ Felt::new(value.d0), Felt::new(value.d1), diff --git a/crates/rust-client/src/rpc/domain/limits.rs b/crates/rust-client/src/rpc/domain/limits.rs index 22d4c81946..e00416f0aa 100644 --- a/crates/rust-client/src/rpc/domain/limits.rs +++ b/crates/rust-client/src/rpc/domain/limits.rs @@ -3,7 +3,13 @@ use core::convert::TryFrom; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use crate::rpc::RpcEndpoint; use crate::rpc::errors::RpcConversionError; diff --git a/crates/rust-client/src/rpc/domain/note.rs b/crates/rust-client/src/rpc/domain/note.rs index 587560b39f..ae0d33e027 100644 --- a/crates/rust-client/src/rpc/domain/note.rs +++ b/crates/rust-client/src/rpc/domain/note.rs @@ -15,7 +15,7 @@ use miden_protocol::note::{ NoteType, }; use miden_protocol::{MastForest, MastNodeId, Word}; -use miden_tx::utils::Deserializable; +use miden_tx::utils::serde::Deserializable; use super::{MissingFieldHelper, RpcConversionError}; use crate::rpc::{RpcError, generated as proto}; @@ -62,7 +62,7 @@ impl TryFrom for NoteMetadata { impl From for proto::note::NoteMetadata { fn from(value: NoteMetadata) -> Self { - use miden_tx::utils::Serializable; + use miden_tx::utils::serde::Serializable; proto::note::NoteMetadata { sender: Some(value.sender().into()), note_type: value.note_type() as i32, @@ -72,6 +72,22 @@ impl From for proto::note::NoteMetadata { } } +impl TryFrom for NoteHeader { + type Error = RpcConversionError; + + fn try_from(value: proto::note::NoteHeader) -> Result { + let note_id = value + .note_id + .ok_or(proto::note::NoteHeader::missing_field(stringify!(note_id)))? + .try_into()?; + let metadata = value + .metadata + .ok_or(proto::note::NoteHeader::missing_field(stringify!(metadata)))? + .try_into()?; + Ok(NoteHeader::new(note_id, metadata)) + } +} + impl TryFrom for NoteInclusionProof { type Error = RpcConversionError; diff --git a/crates/rust-client/src/rpc/domain/smt.rs b/crates/rust-client/src/rpc/domain/smt.rs index 8f14ae178a..f651771802 100644 --- a/crates/rust-client/src/rpc/domain/smt.rs +++ b/crates/rust-client/src/rpc/domain/smt.rs @@ -50,7 +50,7 @@ impl From<&SmtLeaf> for proto::primitives::SmtLeaf { fn from(value: &SmtLeaf) -> Self { match value { SmtLeaf::Empty(index) => proto::primitives::SmtLeaf { - leaf: Some(proto::primitives::smt_leaf::Leaf::EmptyLeafIndex(index.value())), + leaf: Some(proto::primitives::smt_leaf::Leaf::EmptyLeafIndex(index.position())), }, SmtLeaf::Single(entry) => proto::primitives::SmtLeaf { leaf: Some(proto::primitives::smt_leaf::Leaf::Single(entry.into())), diff --git a/crates/rust-client/src/rpc/domain/transaction.rs b/crates/rust-client/src/rpc/domain/transaction.rs index 59de08e7a2..511370e6de 100644 --- a/crates/rust-client/src/rpc/domain/transaction.rs +++ b/crates/rust-client/src/rpc/domain/transaction.rs @@ -168,10 +168,12 @@ impl TryFrom for TransactionHeader { )?; let note_commitments = value - .nullifiers + .input_notes .into_iter() .map(|d| { let word: Word = d + .nullifier + .ok_or(RpcError::ExpectedDataMissing("nullifier".into()))? .try_into() .map_err(|e: RpcConversionError| RpcError::InvalidResponse(e.to_string()))?; Ok(InputNoteCommitment::from(Nullifier::from_raw(word))) @@ -182,8 +184,8 @@ impl TryFrom for TransactionHeader { let output_notes = value .output_notes .into_iter() - .map(TryInto::try_into) - .collect::, RpcError>>()?; + .map(NoteHeader::try_from) + .collect::, _>>()?; let transaction_header = TransactionHeader::new( account_id.try_into()?, diff --git a/crates/rust-client/src/rpc/errors/mod.rs b/crates/rust-client/src/rpc/errors/mod.rs index a01ca2808d..82f8880e9b 100644 --- a/crates/rust-client/src/rpc/errors/mod.rs +++ b/crates/rust-client/src/rpc/errors/mod.rs @@ -8,7 +8,7 @@ use miden_protocol::account::AccountId; use miden_protocol::crypto::merkle::MerkleError; use miden_protocol::errors::NoteError; use miden_protocol::note::NoteId; -use miden_protocol::utils::DeserializationError; +use miden_protocol::utils::serde::DeserializationError; use thiserror::Error; use super::RpcEndpoint; diff --git a/crates/rust-client/src/rpc/mod.rs b/crates/rust-client/src/rpc/mod.rs index 93c8e72eb1..64d03fd37e 100644 --- a/crates/rust-client/src/rpc/mod.rs +++ b/crates/rust-client/src/rpc/mod.rs @@ -300,7 +300,7 @@ pub trait NodeRpcClient: Send + Sync { if let FetchedAccount::Public(account, _) = response { let account = *account; // We should only return an account if it's newer, otherwise we ignore it - if account.nonce().as_int() > local_account.nonce().as_int() { + if account.nonce().as_canonical_u64() > local_account.nonce().as_canonical_u64() { public_accounts.push(account); } } diff --git a/crates/rust-client/src/rpc/tonic_client/mod.rs b/crates/rust-client/src/rpc/tonic_client/mod.rs index 940e247d1e..f331ce8638 100644 --- a/crates/rust-client/src/rpc/tonic_client/mod.rs +++ b/crates/rust-client/src/rpc/tonic_client/mod.rs @@ -13,13 +13,14 @@ use miden_protocol::address::NetworkId; use miden_protocol::block::account_tree::AccountWitness; use miden_protocol::block::{BlockHeader, BlockNumber, ProvenBlock}; use miden_protocol::crypto::merkle::MerklePath; -use miden_protocol::crypto::merkle::mmr::{Forest, MmrProof}; +use miden_protocol::crypto::merkle::mmr::{Forest, MmrPath, MmrProof}; use miden_protocol::crypto::merkle::smt::SmtProof; use miden_protocol::note::{NoteId, NoteScript, NoteTag, Nullifier}; use miden_protocol::transaction::{ProvenTransaction, TransactionInputs}; -use miden_protocol::utils::Deserializable; +use miden_protocol::utils::serde::Deserializable; +use miden_protocol::vm::FutureMaybeSend; use miden_protocol::{EMPTY_WORD, Word}; -use miden_tx::utils::Serializable; +use miden_tx::utils::serde::Serializable; use miden_tx::utils::sync::RwLock; use tonic::Status; use tracing::info; @@ -46,6 +47,8 @@ use crate::rpc::{AccountStateAt, generated as proto}; use crate::rpc::domain::account::AccountStorageRequirements; mod api_client; +mod retry; + use api_client::api_client_wrapper::ApiClient; /// Tracks the pagination state for block-driven endpoints. @@ -140,6 +143,10 @@ pub struct GrpcClient { genesis_commitment: RwLock>, /// Cached RPC limits fetched from the node. limits: RwLock>, + /// Maximum number of retry attempts for rate-limited or transiently unavailable requests. + max_retries: u32, + /// Fallback retry interval in milliseconds when no `retry-after` header is present. + retry_interval_ms: u64, } impl GrpcClient { @@ -152,9 +159,27 @@ impl GrpcClient { timeout_ms, genesis_commitment: RwLock::new(None), limits: RwLock::new(None), + max_retries: retry::DEFAULT_MAX_RETRIES, + retry_interval_ms: retry::DEFAULT_RETRY_INTERVAL_MS, } } + /// Sets the maximum number of retry attempts for rate-limited or transiently unavailable + /// requests. Defaults to 5. + #[must_use] + pub fn with_max_retries(mut self, max_retries: u32) -> Self { + self.max_retries = max_retries; + self + } + + /// Sets the fallback retry interval in milliseconds, used when the server does not provide + /// a `retry-after` header. Defaults to 250ms. + #[must_use] + pub fn with_retry_interval_ms(mut self, retry_interval_ms: u64) -> Self { + self.retry_interval_ms = retry_interval_ms; + self + } + /// Takes care of establishing the RPC connection if not connected yet. It ensures that the /// `rpc_api` field is initialized and returns a write guard to it. async fn ensure_connected(&self) -> Result { @@ -191,6 +216,38 @@ impl GrpcClient { RpcError::from_grpc_error_with_context(endpoint, status, context) } + /// Executes an RPC call and automatically retries transient failures. + /// + /// The provided closure is invoked with a freshly connected [`ApiClient`] on each attempt. + /// Retries are delegated to [`retry::RetryState`], which currently handles gRPC + /// [`tonic::Code::ResourceExhausted`] and [`tonic::Code::Unavailable`] responses, including + /// honoring cooldown delays when the node provides them. + /// + /// Returns the first successful gRPC response. If the call keeps failing after retries are + /// exhausted, or if the error is not retryable, this returns the corresponding [`RpcError`] + /// for the provided [`RpcEndpoint`]. + async fn call_with_retry( + &self, + endpoint: RpcEndpoint, + mut call: F, + ) -> Result, RpcError> + where + F: FnMut(ApiClient) -> Fut, + Fut: FutureMaybeSend, Status>>, + { + let mut retry_state = retry::RetryState::new(self.max_retries, self.retry_interval_ms); + + loop { + let rpc_api = self.ensure_connected().await?; + + match call(rpc_api).await { + Ok(response) => return Ok(response), + Err(status) if retry_state.should_retry(&status).await => {}, + Err(status) => return Err(self.rpc_error_from_status(endpoint, status)), + } + } + } + /// Fetches RPC status without injecting an Accept header. /// /// This instantiates a separate API client without the Accept interceptor, so it does not @@ -217,7 +274,6 @@ impl GrpcClient { &self, account_id: AccountId, ) -> Result<(BlockNumber, AccountProof), RpcError> { - let mut rpc_api = self.ensure_connected().await?; let has_public_state = account_id.has_public_state(); let account_request = { AccountRequest { @@ -240,10 +296,12 @@ impl GrpcClient { }, } }; - let account_response = rpc_api - .get_account(account_request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::GetAccount, status))? + let account_response = self + .call_with_retry(RpcEndpoint::GetAccount, |mut rpc_api| { + let request = account_request.clone(); + async move { rpc_api.get_account(request).await } + }) + .await? .into_inner(); let block_number = account_response.block_num.ok_or(RpcError::ExpectedDataMissing( "GetAccountDetails returned an account without a matching block number for the witness" @@ -277,15 +335,13 @@ impl GrpcClient { .collect(), }), }; - match rpc_api.get_account(account_request).await { - Ok(account_proof) => account_proof.into_inner().try_into(), - Err(err) => Err(RpcError::ConnectionError( - format!( - "failed to fetch account proof for account: {account_id}, got: {err}" - ) - .into(), - )), - } + let response = self + .call_with_retry(RpcEndpoint::GetAccount, |mut rpc_api| { + let request = account_request.clone(); + async move { rpc_api.get_account(request).await } + }) + .await?; + response.into_inner().try_into() } else { account_response.try_into() } @@ -417,12 +473,12 @@ impl NodeRpcClient for GrpcClient { transaction_inputs: Some(transaction_inputs.to_bytes()), }; - let mut rpc_api = self.ensure_connected().await?; - - let api_response = rpc_api - .submit_proven_transaction(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::SubmitProvenTx, status))?; + let api_response = self + .call_with_retry(RpcEndpoint::SubmitProvenTx, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.submit_proven_transaction(request).await } + }) + .await?; Ok(BlockNumber::from(api_response.into_inner().block_num)) } @@ -439,11 +495,11 @@ impl NodeRpcClient for GrpcClient { info!("Calling GetBlockHeaderByNumber: {:?}", request); - let mut rpc_api = self.ensure_connected().await?; - - let api_response = rpc_api.get_block_header_by_number(request).await.map_err(|status| { - self.rpc_error_from_status(RpcEndpoint::GetBlockHeaderByNumber, status) - })?; + let api_response = self + .call_with_retry(RpcEndpoint::GetBlockHeaderByNumber, |mut rpc_api| async move { + rpc_api.get_block_header_by_number(request).await + }) + .await?; let response = api_response.into_inner(); @@ -461,11 +517,14 @@ impl NodeRpcClient for GrpcClient { .ok_or(RpcError::ExpectedDataMissing("MmrPath".into()))? .try_into()?; - Some(MmrProof { - forest: Forest::new(usize::try_from(forest).expect("u64 should fit in usize")), - position: block_header.block_num().as_usize(), - merkle_path, - }) + Some(MmrProof::new( + MmrPath::new( + Forest::new(usize::try_from(forest).expect("u64 should fit in usize")), + block_header.block_num().as_usize(), + merkle_path, + ), + block_header.commitment(), + )) } else { None }; @@ -481,12 +540,12 @@ impl NodeRpcClient for GrpcClient { ids: chunk.iter().map(|id| (*id).into()).collect(), }; - let mut rpc_api = self.ensure_connected().await?; - - let api_response = rpc_api - .get_notes_by_id(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::GetNotesById, status))?; + let api_response = self + .call_with_retry(RpcEndpoint::GetNotesById, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.get_notes_by_id(request).await } + }) + .await?; let response_notes = api_response .into_inner() @@ -512,12 +571,11 @@ impl NodeRpcClient for GrpcClient { let request = proto::rpc::SyncChainMmrRequest { block_range }; - let mut rpc_api = self.ensure_connected().await?; - - let response = rpc_api - .sync_chain_mmr(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::SyncChainMmr, status))?; + let response = self + .call_with_retry(RpcEndpoint::SyncChainMmr, |mut rpc_api| async move { + rpc_api.sync_chain_mmr(request).await + }) + .await?; response.into_inner().try_into() } @@ -563,7 +621,7 @@ impl NodeRpcClient for GrpcClient { updates.sort_by_key(|u| u.block_num); updates .into_iter() - .map(|u| (Word::from(u.vault_key), u.asset)) + .map(|u| (u.vault_key, u.asset)) .collect::>() .into_values() .flatten() @@ -617,8 +675,6 @@ impl NodeRpcClient for GrpcClient { known_codes_by_commitment.insert(account_code.commitment(), account_code); } - let mut rpc_api = self.ensure_connected().await?; - let storage_maps: Vec = storage_requirements.clone().into(); // Only request details for accounts with public state (Public or Network); @@ -646,10 +702,12 @@ impl NodeRpcClient for GrpcClient { details: account_details, }; - let response = rpc_api - .get_account(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::GetAccount, status))? + let response = self + .call_with_retry(RpcEndpoint::GetAccount, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.get_account(request).await } + }) + .await? .into_inner(); let account_witness: AccountWitness = response @@ -698,12 +756,12 @@ impl NodeRpcClient for GrpcClient { let request = proto::rpc::SyncNotesRequest { block_range, note_tags }; - let mut rpc_api = self.ensure_connected().await?; - - let response = rpc_api - .sync_notes(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::SyncNotes, status))?; + let response = self + .call_with_retry(RpcEndpoint::SyncNotes, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.sync_notes(request).await } + }) + .await?; response.into_inner().try_into() } @@ -719,9 +777,6 @@ impl NodeRpcClient for GrpcClient { let limits = self.get_rpc_limits().await?; let mut all_nullifiers = BTreeSet::new(); - // Establish RPC connection once before the loop - let mut rpc_api = self.ensure_connected().await?; - // If the prefixes are too many, we need to chunk them into smaller groups to avoid // violating the RPC limit. 'chunk_nullifiers: for chunk in prefixes.chunks(limits.nullifiers_limit as usize) { @@ -737,9 +792,12 @@ impl NodeRpcClient for GrpcClient { }), }; - let response = rpc_api.sync_nullifiers(request).await.map_err(|status| { - self.rpc_error_from_status(RpcEndpoint::SyncNullifiers, status) - })?; + let response = self + .call_with_retry(RpcEndpoint::SyncNullifiers, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.sync_nullifiers(request).await } + }) + .await?; let response = response.into_inner(); // Convert nullifiers for this batch @@ -788,11 +846,12 @@ impl NodeRpcClient for GrpcClient { nullifiers: chunk.iter().map(|nul| nul.as_word().into()).collect(), }; - let mut rpc_api = self.ensure_connected().await?; - - let response = rpc_api.check_nullifiers(request).await.map_err(|status| { - self.rpc_error_from_status(RpcEndpoint::CheckNullifiers, status) - })?; + let response = self + .call_with_retry(RpcEndpoint::CheckNullifiers, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.check_nullifiers(request).await } + }) + .await?; let mut response = response.into_inner(); let chunk_proofs = response @@ -808,12 +867,11 @@ impl NodeRpcClient for GrpcClient { async fn get_block_by_number(&self, block_num: BlockNumber) -> Result { let request = proto::blockchain::BlockNumber { block_num: block_num.as_u32() }; - let mut rpc_api = self.ensure_connected().await?; - - let response = rpc_api - .get_block_by_number(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::GetBlockByNumber, status))?; + let response = self + .call_with_retry(RpcEndpoint::GetBlockByNumber, |mut rpc_api| async move { + rpc_api.get_block_by_number(request).await + }) + .await?; let response = response.into_inner(); let block = @@ -827,11 +885,11 @@ impl NodeRpcClient for GrpcClient { async fn get_note_script_by_root(&self, root: Word) -> Result { let request = proto::note::NoteScriptRoot { root: Some(root.into()) }; - let mut rpc_api = self.ensure_connected().await?; - - let response = rpc_api.get_note_script_by_root(request).await.map_err(|status| { - self.rpc_error_from_status(RpcEndpoint::GetNoteScriptByRoot, status) - })?; + let response = self + .call_with_retry(RpcEndpoint::GetNoteScriptByRoot, |mut rpc_api| async move { + rpc_api.get_note_script_by_root(request).await + }) + .await?; let response = response.into_inner(); let note_script = NoteScript::try_from( @@ -849,7 +907,6 @@ impl NodeRpcClient for GrpcClient { block_to: Option, account_id: AccountId, ) -> Result { - let mut rpc_api = self.ensure_connected().await?; let mut pagination = BlockPagination::new(block_from, block_to); let mut updates = Vec::new(); @@ -861,9 +918,12 @@ impl NodeRpcClient for GrpcClient { }), account_id: Some(account_id.into()), }; - let response = rpc_api.sync_account_storage_maps(request).await.map_err(|status| { - self.rpc_error_from_status(RpcEndpoint::SyncStorageMaps, status) - })?; + let response = self + .call_with_retry(RpcEndpoint::SyncStorageMaps, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.sync_account_storage_maps(request).await } + }) + .await?; let response = response.into_inner(); let page = response .pagination_info @@ -895,7 +955,6 @@ impl NodeRpcClient for GrpcClient { block_to: Option, account_id: AccountId, ) -> Result { - let mut rpc_api = self.ensure_connected().await?; let mut pagination = BlockPagination::new(block_from, block_to); let mut updates = Vec::new(); @@ -907,9 +966,12 @@ impl NodeRpcClient for GrpcClient { }), account_id: Some(account_id.into()), }; - let response = rpc_api.sync_account_vault(request).await.map_err(|status| { - self.rpc_error_from_status(RpcEndpoint::SyncAccountVault, status) - })?; + let response = self + .call_with_retry(RpcEndpoint::SyncAccountVault, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.sync_account_vault(request).await } + }) + .await?; let response = response.into_inner(); let page = response .pagination_info @@ -950,12 +1012,12 @@ impl NodeRpcClient for GrpcClient { let request = proto::rpc::SyncTransactionsRequest { block_range, account_ids }; - let mut rpc_api = self.ensure_connected().await?; - - let response = rpc_api - .sync_transactions(request) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::SyncTransactions, status))?; + let response = self + .call_with_retry(RpcEndpoint::SyncTransactions, |mut rpc_api| { + let request = request.clone(); + async move { rpc_api.sync_transactions(request).await } + }) + .await?; response.into_inner().try_into() } @@ -973,11 +1035,11 @@ impl NodeRpcClient for GrpcClient { } // Fetch limits from the node - let mut rpc_api = self.ensure_connected().await?; - let response = rpc_api - .get_limits(()) - .await - .map_err(|status| self.rpc_error_from_status(RpcEndpoint::GetLimits, status))?; + let response = self + .call_with_retry(RpcEndpoint::GetLimits, |mut rpc_api| async move { + rpc_api.get_limits(()).await + }) + .await?; let limits = RpcLimits::try_from(response.into_inner()).map_err(RpcError::from)?; // Cache fetched values diff --git a/crates/rust-client/src/rpc/tonic_client/retry.rs b/crates/rust-client/src/rpc/tonic_client/retry.rs new file mode 100644 index 0000000000..2b37c3265a --- /dev/null +++ b/crates/rust-client/src/rpc/tonic_client/retry.rs @@ -0,0 +1,119 @@ +use core::time::Duration; + +use tonic::Status; +use tracing::warn; + +// CONSTS +// ================================================================================================ + +/// Default maximum number of retry attempts for rate-limited requests. +pub(super) const DEFAULT_MAX_RETRIES: u32 = 4; + +/// Default fallback delay (in milliseconds) when no `retry-after` header is present. +pub(super) const DEFAULT_RETRY_INTERVAL_MS: u64 = 100; + +// RETRY STATE +// ================================================================================================ + +/// Tracks retry attempts for a single RPC call and applies the node-provided cooldown policy. +/// +/// The state is intentionally tiny: it only counts how many retries have already been attempted. +/// Delay selection is derived from the current gRPC [`Status`], preferring a non-zero +/// `retry-after` response metadata value when present and falling back to the configured +/// retry interval otherwise. +pub(super) struct RetryState { + attempt: u32, + max_retries: u32, + retry_interval_ms: u64, +} + +impl RetryState { + /// Creates a new retry state for a fresh RPC call. + pub(super) const fn new(max_retries: u32, retry_interval_ms: u64) -> Self { + Self { + attempt: 0, + max_retries, + retry_interval_ms, + } + } + + /// Applies retry policy for the provided status. + /// + /// Returns `true` after waiting the requested cooldown when the error is retryable and the + /// attempt limit has not been reached. Returns `false` for non-retryable statuses or once the + /// retry budget is exhausted. + pub(super) async fn should_retry(&mut self, status: &Status) -> bool { + if self.attempt >= self.max_retries || !is_retryable(status) { + return false; + } + + let delay = retry_delay(status, self.retry_interval_ms); + + warn!( + attempt = self.attempt + 1, + delay_ms = u64::try_from(delay.as_millis()).unwrap_or(u64::MAX), + "rate-limited by node, retrying after delay", + ); + + async_sleep(delay).await; + self.attempt += 1; + true + } +} + +// HELPERS +// ================================================================================================ + +fn is_retryable(status: &Status) -> bool { + matches!(status.code(), tonic::Code::ResourceExhausted | tonic::Code::Unavailable) +} + +fn retry_delay(status: &Status, fallback_ms: u64) -> Duration { + extract_retry_after(status) + .filter(|delay| !delay.is_zero()) + .unwrap_or(Duration::from_millis(fallback_ms)) +} + +fn extract_retry_after(status: &Status) -> Option { + status + .metadata() + .get("retry-after") + .and_then(|v| v.to_str().ok()) + .and_then(|s| s.parse::().ok()) + .map(Duration::from_secs) +} + +#[cfg(not(target_arch = "wasm32"))] +async fn async_sleep(duration: Duration) { + tokio::time::sleep(duration).await; +} + +/// On WASM, sleep using browser timers so retry delays are honored. +#[cfg(target_arch = "wasm32")] +async fn async_sleep(duration: Duration) { + gloo_timers::future::sleep(duration).await; +} + +#[cfg(test)] +mod tests { + use core::time::Duration; + + use tonic::metadata::MetadataMap; + use tonic::{Code, Status}; + + use super::{DEFAULT_RETRY_INTERVAL_MS, retry_delay}; + + fn status_with_retry_after(retry_after: &str) -> Status { + let mut metadata = MetadataMap::new(); + metadata.insert("retry-after", retry_after.parse().unwrap()); + Status::with_metadata(Code::ResourceExhausted, "Too Many Requests! Wait for 0s", metadata) + } + + #[test] + fn zero_retry_after_uses_fallback_delay() { + assert_eq!( + retry_delay(&status_with_retry_after("0"), DEFAULT_RETRY_INTERVAL_MS), + Duration::from_millis(DEFAULT_RETRY_INTERVAL_MS) + ); + } +} diff --git a/crates/rust-client/src/settings/mod.rs b/crates/rust-client/src/settings/mod.rs index e75fd3c91f..2b16454144 100644 --- a/crates/rust-client/src/settings/mod.rs +++ b/crates/rust-client/src/settings/mod.rs @@ -4,7 +4,7 @@ use alloc::string::String; use alloc::vec::Vec; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use super::Client; use crate::errors::ClientError; diff --git a/crates/rust-client/src/store/errors.rs b/crates/rust-client/src/store/errors.rs index 7c9ffac934..f60f144316 100644 --- a/crates/rust-client/src/store/errors.rs +++ b/crates/rust-client/src/store/errors.rs @@ -16,7 +16,8 @@ use miden_protocol::errors::{ StorageMapError, TransactionScriptError, }; -use miden_protocol::utils::{DeserializationError, HexParseError}; +use miden_protocol::utils::HexParseError; +use miden_protocol::utils::serde::DeserializationError; use miden_protocol::{Word, WordError}; use miden_tx::DataStoreError; use thiserror::Error; diff --git a/crates/rust-client/src/store/mod.rs b/crates/rust-client/src/store/mod.rs index 9ee5cc5c08..254e236e11 100644 --- a/crates/rust-client/src/store/mod.rs +++ b/crates/rust-client/src/store/mod.rs @@ -46,7 +46,7 @@ use miden_protocol::crypto::merkle::mmr::{Forest, InOrderIndex, MmrPeaks, Partia use miden_protocol::errors::AccountError; use miden_protocol::note::{NoteId, NoteScript, NoteTag, Nullifier}; use miden_protocol::transaction::TransactionId; -use miden_tx::utils::{Deserializable, Serializable}; +use miden_tx::utils::serde::{Deserializable, Serializable}; use crate::note_transport::{NOTE_TRANSPORT_CURSOR_STORE_SETTING, NoteTransportCursor}; use crate::rpc::{RPC_LIMITS_STORE_SETTING, RpcLimits}; @@ -493,9 +493,19 @@ pub trait Store: Send + Sync { let has_client_notes = has_client_notes.into(); current_partial_mmr.add(current_block.commitment(), has_client_notes); - // Only track the latest leaf if it is relevant (it has client notes) _and_ the forest - // actually has a single leaf tree bit - let track_latest = has_client_notes && current_partial_mmr.forest().has_single_leaf_tree(); + // Build tracked_leaves from blocks that have client notes. + let tracked_headers = self.get_tracked_block_headers().await?; + let mut tracked_leaves = alloc::collections::BTreeSet::new(); + for header in &tracked_headers { + tracked_leaves.insert(header.block_num().as_usize()); + } + + // Also track the latest leaf if it is relevant (it has client notes) _and_ the forest + // actually has a single leaf tree bit. + if has_client_notes && current_partial_mmr.forest().has_single_leaf_tree() { + let latest_leaf = current_partial_mmr.forest().num_leaves().saturating_sub(1); + tracked_leaves.insert(latest_leaf); + } let tracked_nodes = self .get_partial_blockchain_nodes(PartialBlockchainFilter::Forest( @@ -504,7 +514,7 @@ pub trait Store: Send + Sync { .await?; let current_partial_mmr = - PartialMmr::from_parts(current_partial_mmr.peaks(), tracked_nodes, track_latest); + PartialMmr::from_parts(current_partial_mmr.peaks(), tracked_nodes, tracked_leaves)?; Ok(current_partial_mmr) } diff --git a/crates/rust-client/src/store/note_record/input_note_record/mod.rs b/crates/rust-client/src/store/note_record/input_note_record/mod.rs index a3640bf9ff..bdb87b8051 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/mod.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/mod.rs @@ -14,7 +14,7 @@ use miden_protocol::note::{ Nullifier, }; use miden_protocol::transaction::{InputNote, TransactionId}; -use miden_protocol::utils::{ +use miden_protocol::utils::serde::{ ByteReader, ByteWriter, Deserializable, @@ -89,7 +89,7 @@ impl InputNoteRecord { /// Returns the note's commitment, if the record contains the [`NoteMetadata`]. pub fn commitment(&self) -> Option { - self.metadata().map(|m| NoteHeader::new(self.id(), m.clone()).commitment()) + self.metadata().map(|m| NoteHeader::new(self.id(), m.clone()).to_commitment()) } /// Returns the note's assets. diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/committed.rs b/crates/rust-client/src/store/note_record/input_note_record/states/committed.rs index a390311ea4..709d8cc198 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/committed.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/committed.rs @@ -112,18 +112,18 @@ impl NoteStateHandler for CommittedNoteState { } } -impl miden_tx::utils::Serializable for CommittedNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for CommittedNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.inclusion_proof.write_into(target); self.block_note_root.write_into(target); } } -impl miden_tx::utils::Deserializable for CommittedNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for CommittedNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let inclusion_proof = NoteInclusionProof::read_from(source)?; let block_note_root = Word::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs index 4ceae0ce29..eb3df26087 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs @@ -83,8 +83,8 @@ impl NoteStateHandler for ConsumedAuthenticatedLocalNoteState { } } -impl miden_tx::utils::Serializable for ConsumedAuthenticatedLocalNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for ConsumedAuthenticatedLocalNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.inclusion_proof.write_into(target); self.block_note_root.write_into(target); @@ -94,10 +94,10 @@ impl miden_tx::utils::Serializable for ConsumedAuthenticatedLocalNoteState { } } -impl miden_tx::utils::Deserializable for ConsumedAuthenticatedLocalNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for ConsumedAuthenticatedLocalNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let inclusion_proof = NoteInclusionProof::read_from(source)?; let block_note_root = Word::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_external.rs b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_external.rs index 13833ed19e..7c1c9de769 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_external.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_external.rs @@ -73,17 +73,17 @@ impl NoteStateHandler for ConsumedExternalNoteState { } } -impl miden_tx::utils::Serializable for ConsumedExternalNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for ConsumedExternalNoteState { + fn write_into(&self, target: &mut W) { self.nullifier_block_height.write_into(target); self.consumed_tx_order.write_into(target); } } -impl miden_tx::utils::Deserializable for ConsumedExternalNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for ConsumedExternalNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let nullifier_block_height = BlockNumber::read_from(source)?; let consumed_tx_order = Option::::read_from(source)?; Ok(ConsumedExternalNoteState { diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_unauthenticated_local.rs b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_unauthenticated_local.rs index d3ff3b840d..bd9475d673 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_unauthenticated_local.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_unauthenticated_local.rs @@ -78,8 +78,8 @@ impl NoteStateHandler for ConsumedUnauthenticatedLocalNoteState { } } -impl miden_tx::utils::Serializable for ConsumedUnauthenticatedLocalNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for ConsumedUnauthenticatedLocalNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.nullifier_block_height.write_into(target); self.submission_data.write_into(target); @@ -87,10 +87,10 @@ impl miden_tx::utils::Serializable for ConsumedUnauthenticatedLocalNoteState { } } -impl miden_tx::utils::Deserializable for ConsumedUnauthenticatedLocalNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for ConsumedUnauthenticatedLocalNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let nullifier_block_height = BlockNumber::read_from(source)?; let submission_data = NoteSubmissionData::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/expected.rs b/crates/rust-client/src/store/note_record/input_note_record/states/expected.rs index e7cded94e1..c088dd41e3 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/expected.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/expected.rs @@ -113,18 +113,18 @@ impl NoteStateHandler for ExpectedNoteState { } } -impl miden_tx::utils::Serializable for ExpectedNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for ExpectedNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.after_block_num.write_into(target); self.tag.write_into(target); } } -impl miden_tx::utils::Deserializable for ExpectedNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for ExpectedNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = Option::::read_from(source)?; let after_block_num = BlockNumber::read_from(source)?; let tag = Option::::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/invalid.rs b/crates/rust-client/src/store/note_record/input_note_record/states/invalid.rs index 289e908d7c..47dcada3c7 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/invalid.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/invalid.rs @@ -57,7 +57,7 @@ impl NoteStateHandler for InvalidNoteState { .invalid_inclusion_proof .note_path() .verify( - self.invalid_inclusion_proof.location().node_index_in_block().into(), + self.invalid_inclusion_proof.location().block_note_tree_index().into(), compute_note_commitment(note_id, &self.metadata), &block_header.note_root(), ) @@ -108,18 +108,18 @@ impl NoteStateHandler for InvalidNoteState { } } -impl miden_tx::utils::Serializable for InvalidNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for InvalidNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.invalid_inclusion_proof.write_into(target); self.block_note_root.write_into(target); } } -impl miden_tx::utils::Deserializable for InvalidNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for InvalidNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let invalid_inclusion_proof = NoteInclusionProof::read_from(source)?; let block_note_root = Word::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/mod.rs b/crates/rust-client/src/store/note_record/input_note_record/states/mod.rs index fadc7f800f..bb4a171a55 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/mod.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/mod.rs @@ -6,7 +6,7 @@ use miden_protocol::account::AccountId; use miden_protocol::block::{BlockHeader, BlockNumber}; use miden_protocol::note::{NoteId, NoteInclusionProof, NoteMetadata}; use miden_protocol::transaction::TransactionId; -pub use miden_tx::utils::{ +pub use miden_tx::utils::serde::{ ByteReader, ByteWriter, Deserializable, diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/processing_authenticated.rs b/crates/rust-client/src/store/note_record/input_note_record/states/processing_authenticated.rs index ed6b078c04..38fce307f1 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/processing_authenticated.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/processing_authenticated.rs @@ -110,8 +110,8 @@ impl NoteStateHandler for ProcessingAuthenticatedNoteState { } } -impl miden_tx::utils::Serializable for ProcessingAuthenticatedNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for ProcessingAuthenticatedNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.inclusion_proof.write_into(target); self.block_note_root.write_into(target); @@ -119,10 +119,10 @@ impl miden_tx::utils::Serializable for ProcessingAuthenticatedNoteState { } } -impl miden_tx::utils::Deserializable for ProcessingAuthenticatedNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for ProcessingAuthenticatedNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let inclusion_proof = NoteInclusionProof::read_from(source)?; let block_note_root = Word::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/processing_unauthenticated.rs b/crates/rust-client/src/store/note_record/input_note_record/states/processing_unauthenticated.rs index 2a043ffcb9..342f547ed3 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/processing_unauthenticated.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/processing_unauthenticated.rs @@ -99,18 +99,18 @@ impl NoteStateHandler for ProcessingUnauthenticatedNoteState { } } -impl miden_tx::utils::Serializable for ProcessingUnauthenticatedNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for ProcessingUnauthenticatedNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.after_block_num.write_into(target); self.submission_data.write_into(target); } } -impl miden_tx::utils::Deserializable for ProcessingUnauthenticatedNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for ProcessingUnauthenticatedNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let after_block_num = BlockNumber::read_from(source)?; let submission_data = NoteSubmissionData::read_from(source)?; diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/unverified.rs b/crates/rust-client/src/store/note_record/input_note_record/states/unverified.rs index eb378ef3d0..9b673a7592 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/unverified.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/unverified.rs @@ -56,7 +56,7 @@ impl NoteStateHandler for UnverifiedNoteState { .inclusion_proof .note_path() .verify( - self.inclusion_proof.location().node_index_in_block().into(), + self.inclusion_proof.location().block_note_tree_index().into(), compute_note_commitment(note_id, &self.metadata), &block_header.note_root(), ) @@ -129,17 +129,17 @@ impl NoteStateHandler for UnverifiedNoteState { } } -impl miden_tx::utils::Serializable for UnverifiedNoteState { - fn write_into(&self, target: &mut W) { +impl miden_tx::utils::serde::Serializable for UnverifiedNoteState { + fn write_into(&self, target: &mut W) { self.metadata.write_into(target); self.inclusion_proof.write_into(target); } } -impl miden_tx::utils::Deserializable for UnverifiedNoteState { - fn read_from( +impl miden_tx::utils::serde::Deserializable for UnverifiedNoteState { + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let metadata = NoteMetadata::read_from(source)?; let inclusion_proof = NoteInclusionProof::read_from(source)?; Ok(UnverifiedNoteState { metadata, inclusion_proof }) diff --git a/crates/rust-client/src/store/note_record/output_note_record/mod.rs b/crates/rust-client/src/store/note_record/output_note_record/mod.rs index 0857802c3e..c1a7508513 100644 --- a/crates/rust-client/src/store/note_record/output_note_record/mod.rs +++ b/crates/rust-client/src/store/note_record/output_note_record/mod.rs @@ -15,8 +15,14 @@ use miden_protocol::note::{ Nullifier, PartialNote, }; -use miden_protocol::transaction::OutputNote; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_protocol::transaction::RawOutputNote; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use super::NoteRecordError; @@ -185,20 +191,17 @@ impl OutputNoteRecord { } } - /// [`OutputNote`] can always be turned into an [`OutputNoteRecord`] when they're either - /// [`OutputNote::Full`] or [`OutputNote::Partial`] and always fail the conversion if it's - /// [`OutputNote::Header`]. This also mean that `output_note.try_from()` can also be used as a - /// way to filter the full and partial output notes. + /// [`RawOutputNote`] can always be turned into an [`OutputNoteRecord`] when they're either + /// [`RawOutputNote::Full`] or [`RawOutputNote::Partial`]. pub fn try_from_output_note( - output_note: OutputNote, + output_note: RawOutputNote, expected_height: BlockNumber, ) -> Result { match output_note { - OutputNote::Full(note) => Ok(Self::from_full_note(note, expected_height)), - OutputNote::Partial(partial_note) => Ok(Self::from_partial_note(&partial_note, expected_height)), - OutputNote::Header(_) => Err(NoteRecordError::ConversionError( - "Cannot transform a Header output note into an OutputNoteRecord: not enough information".to_string(), - )), + RawOutputNote::Full(note) => Ok(Self::from_full_note(note, expected_height)), + RawOutputNote::Partial(partial_note) => { + Ok(Self::from_partial_note(&partial_note, expected_height)) + }, } } } diff --git a/crates/rust-client/src/store/smt_forest.rs b/crates/rust-client/src/store/smt_forest.rs index c8f91c97bb..51f62a08d0 100644 --- a/crates/rust-client/src/store/smt_forest.rs +++ b/crates/rust-client/src/store/smt_forest.rs @@ -59,7 +59,7 @@ impl AccountSmtForest { return Err(MerkleError::UntrackedKey(vault_key_word).into()); } - let asset = Asset::try_from(asset_word)?; + let asset = Asset::from_key_value_words(vault_key_word, asset_word)?; let witness = AssetWitness::new(proof)?; Ok((asset, witness)) } @@ -158,10 +158,10 @@ impl AccountSmtForest { let entries: Vec<(Word, Word)> = new_assets .map(|asset| { let key: Word = asset.vault_key().into(); - let value: Word = asset.into(); + let value = asset.to_value_word(); (key, value) }) - .chain(removed_vault_keys.map(|key| (key.into(), EMPTY_WORD))) + .chain(removed_vault_keys.map(|vault_key| (vault_key.into(), EMPTY_WORD))) .collect(); if entries.is_empty() { @@ -193,7 +193,7 @@ impl AccountSmtForest { pub fn insert_asset_nodes(&mut self, vault: &AssetVault) -> Result<(), StoreError> { let smt = Smt::with_entries(vault.assets().map(|asset| { let key: Word = asset.vault_key().into(); - let value: Word = asset.into(); + let value = asset.to_value_word(); (key, value) })) .map_err(StoreError::from)?; diff --git a/crates/rust-client/src/sync/block_header.rs b/crates/rust-client/src/sync/block_header.rs index ea10433c17..5ed4330e8a 100644 --- a/crates/rust-client/src/sync/block_header.rs +++ b/crates/rust-client/src/sync/block_header.rs @@ -74,12 +74,13 @@ impl Client { // Fetch the block header and MMR proof from the node let (block_header, path_nodes) = fetch_block_header(self.rpc_api.clone(), block_num, current_partial_mmr).await?; + let tracked_nodes = authenticated_block_nodes(&block_header, path_nodes); // Insert header and MMR nodes self.store .insert_block_header(&block_header, current_partial_mmr.peaks(), true) .await?; - self.store.insert_partial_blockchain_nodes(&path_nodes).await?; + self.store.insert_partial_blockchain_nodes(&tracked_nodes).await?; Ok(block_header) } @@ -116,6 +117,19 @@ pub(crate) fn adjust_merkle_path_for_forest( path_nodes } +fn authenticated_block_nodes( + block_header: &BlockHeader, + mut path_nodes: Vec<(InOrderIndex, Word)>, +) -> Vec<(InOrderIndex, Word)> { + let mut nodes = Vec::with_capacity(path_nodes.len() + 1); + nodes.push(( + InOrderIndex::from_leaf_pos(block_header.block_num().as_usize()), + block_header.commitment(), + )); + nodes.append(&mut path_nodes); + nodes +} + pub(crate) async fn fetch_block_header( rpc_api: Arc, block_num: BlockNumber, @@ -126,7 +140,7 @@ pub(crate) async fn fetch_block_header( // Trim merkle path to keep nodes relevant to our current PartialMmr since the node's MMR // might be of a forest arbitrarily higher let path_nodes = adjust_merkle_path_for_forest( - &mmr_proof.merkle_path, + mmr_proof.merkle_path(), block_num, current_partial_mmr.forest(), ); @@ -142,12 +156,13 @@ pub(crate) async fn fetch_block_header( #[cfg(test)] mod tests { - use miden_protocol::block::BlockNumber; + use miden_protocol::block::{BlockHeader, BlockNumber}; use miden_protocol::crypto::merkle::MerklePath; use miden_protocol::crypto::merkle::mmr::{Forest, InOrderIndex, Mmr, PartialMmr}; + use miden_protocol::transaction::TransactionKernel; use miden_protocol::{Felt, Word}; - use super::adjust_merkle_path_for_forest; + use super::{adjust_merkle_path_for_forest, authenticated_block_nodes}; fn word(n: u64) -> Word { Word::new([Felt::new(n), Felt::new(0), Felt::new(0), Felt::new(0)]) @@ -181,7 +196,7 @@ mod tests { let proof = mmr.open_at(leaf_pos, large_forest).expect("valid proof"); let adjusted_nodes = - adjust_merkle_path_for_forest(&proof.merkle_path, block_num, small_forest); + adjust_merkle_path_for_forest(proof.merkle_path(), block_num, small_forest); let adjusted_path = MerklePath::new(adjusted_nodes.iter().map(|(_, n)| *n).collect()); let peaks = mmr.peaks_at(small_forest).unwrap(); @@ -243,13 +258,27 @@ mod tests { let next_sibling = idx.sibling(); let rightmost = InOrderIndex::from_leaf_pos(small_leaves - 1); assert!(next_sibling <= rightmost); - assert!(proof.merkle_path.depth() as usize > expected_depth); + assert!(proof.merkle_path().depth() as usize > expected_depth); let adjusted = adjust_merkle_path_for_forest( - &proof.merkle_path, + proof.merkle_path(), BlockNumber::from(u32::try_from(leaf_pos).unwrap()), small_forest, ); assert_eq!(adjusted.len(), expected_depth); } + + #[test] + fn authenticated_block_nodes_include_leaf_commitment() { + let block_header = BlockHeader::mock(4, None, None, &[], TransactionKernel.to_commitment()); + let path_nodes = vec![ + (InOrderIndex::from_leaf_pos(4).sibling(), word(10)), + (InOrderIndex::from_leaf_pos(4).parent().sibling(), word(11)), + ]; + + let nodes = authenticated_block_nodes(&block_header, path_nodes.clone()); + + assert_eq!(nodes[0], (InOrderIndex::from_leaf_pos(4), block_header.commitment())); + assert_eq!(&nodes[1..], path_nodes.as_slice()); + } } diff --git a/crates/rust-client/src/sync/mod.rs b/crates/rust-client/src/sync/mod.rs index 0ac105b2f8..287c95de1e 100644 --- a/crates/rust-client/src/sync/mod.rs +++ b/crates/rust-client/src/sync/mod.rs @@ -29,7 +29,7 @@ //! # use miden_client::auth::TransactionAuthenticator; //! # use miden_client::sync::SyncSummary; //! # use miden_client::{Client, ClientError}; -//! # use miden_protocol::{block::BlockHeader, Felt, Word, StarkField}; +//! # use miden_protocol::{block::BlockHeader, Felt, Word}; //! # use miden_protocol::crypto::rand::FeltRng; //! # async fn run_sync(client: &mut Client) -> Result<(), ClientError> { //! // Attempt to synchronize the client's state with the Miden network. @@ -64,7 +64,7 @@ use miden_protocol::block::BlockNumber; use miden_protocol::note::NoteId; use miden_protocol::transaction::TransactionId; use miden_tx::auth::TransactionAuthenticator; -use miden_tx::utils::{Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{Deserializable, DeserializationError, Serializable}; use tracing::{debug, info}; use crate::store::{NoteFilter, TransactionFilter}; @@ -286,7 +286,7 @@ impl SyncSummary { } impl Serializable for SyncSummary { - fn write_into(&self, target: &mut W) { + fn write_into(&self, target: &mut W) { self.block_num.write_into(target); self.new_public_notes.write_into(target); self.committed_notes.write_into(target); @@ -298,7 +298,7 @@ impl Serializable for SyncSummary { } impl Deserializable for SyncSummary { - fn read_from( + fn read_from( source: &mut R, ) -> Result { let block_num = BlockNumber::read_from(source)?; diff --git a/crates/rust-client/src/sync/state_sync.rs b/crates/rust-client/src/sync/state_sync.rs index d6d6043968..099e1dab4f 100644 --- a/crates/rust-client/src/sync/state_sync.rs +++ b/crates/rust-client/src/sync/state_sync.rs @@ -181,11 +181,9 @@ impl StateSync { output_notes, uncommitted_transactions, } = input; - let block_num = u32::try_from( - current_partial_mmr.forest().num_leaves().checked_sub(1).unwrap_or_default(), - ) - .map_err(|_| ClientError::InvalidPartialMmrForest)? - .into(); + let block_num = u32::try_from(current_partial_mmr.forest().num_leaves().saturating_sub(1)) + .map_err(|_| ClientError::InvalidPartialMmrForest)? + .into(); let mut state_sync_update = StateSyncUpdate { block_num, diff --git a/crates/rust-client/src/sync/tag.rs b/crates/rust-client/src/sync/tag.rs index bfc3b08668..1e24ff194d 100644 --- a/crates/rust-client/src/sync/tag.rs +++ b/crates/rust-client/src/sync/tag.rs @@ -3,7 +3,13 @@ use alloc::vec::Vec; use miden_protocol::account::{Account, AccountId}; use miden_protocol::note::{NoteId, NoteTag}; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use tracing::warn; use crate::Client; diff --git a/crates/rust-client/src/test_utils/common.rs b/crates/rust-client/src/test_utils/common.rs index 0d5400d287..787efc48a2 100644 --- a/crates/rust-client/src/test_utils/common.rs +++ b/crates/rust-client/src/test_utils/common.rs @@ -14,14 +14,19 @@ use miden_protocol::account::{Account, AccountComponentMetadata, AccountId, Acco use miden_protocol::asset::{FungibleAsset, TokenSymbol}; use miden_protocol::note::NoteType; use miden_protocol::testing::account_id::ACCOUNT_ID_REGULAR_PRIVATE_ACCOUNT_UPDATABLE_CODE; -use miden_protocol::transaction::{OutputNote, TransactionId}; +use miden_protocol::transaction::TransactionId; use miden_standards::account::auth::AuthSingleSig; use miden_standards::code_builder::CodeBuilder; use rand::RngCore; use tracing::{debug, info}; use uuid::Uuid; -use crate::account::component::{AccountComponent, BasicFungibleFaucet, BasicWallet}; +use crate::account::component::{ + AccountComponent, + AuthControlled, + BasicFungibleFaucet, + BasicWallet, +}; use crate::account::{AccountBuilder, AccountType, StorageSlot}; use crate::auth::AuthSchemeId; use crate::crypto::FeltRng; @@ -76,29 +81,8 @@ pub async fn insert_new_wallet_with_seed( init_seed: [u8; 32], auth_scheme: AuthSchemeId, ) -> Result<(Account, AuthSecretKey), ClientError> { - let (key_pair, auth_component) = match auth_scheme { - AuthSchemeId::Falcon512Rpo => { - let key_pair = AuthSecretKey::new_falcon512_rpo(); - let auth_component = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, - ); - (key_pair, auth_component) - }, - AuthSchemeId::EcdsaK256Keccak => { - let key_pair = AuthSecretKey::new_ecdsa_k256_keccak(); - let auth_component = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - AuthSchemeId::EcdsaK256Keccak, - ); - (key_pair, auth_component) - }, - scheme => { - return Err(ClientError::TransactionRequestError( - TransactionRequestError::UnsupportedAuthSchemeId(scheme.as_u8()), - )); - }, - }; + let key_pair = crate::auth::new_auth_secret_key(auth_scheme)?; + let auth_component = AuthSingleSig::new(key_pair.public_key().to_commitment(), auth_scheme); let account = AccountBuilder::new(init_seed) .account_type(AccountType::RegularAccountImmutableCode) @@ -124,43 +108,22 @@ pub async fn insert_new_fungible_faucet( keystore: &FilesystemKeyStore, auth_scheme: AuthSchemeId, ) -> Result<(Account, AuthSecretKey), ClientError> { - let (key_pair, auth_component) = match auth_scheme { - AuthSchemeId::Falcon512Rpo => { - let key_pair = AuthSecretKey::new_falcon512_rpo(); - let auth_component = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, - ); - (key_pair, auth_component) - }, - AuthSchemeId::EcdsaK256Keccak => { - let key_pair = AuthSecretKey::new_ecdsa_k256_keccak(); - let auth_component = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - AuthSchemeId::EcdsaK256Keccak, - ); - (key_pair, auth_component) - }, - scheme => { - return Err(ClientError::TransactionRequestError( - TransactionRequestError::UnsupportedAuthSchemeId(scheme.as_u8()), - )); - }, - }; + let key_pair = crate::auth::new_auth_secret_key(auth_scheme)?; + let auth_component = AuthSingleSig::new(key_pair.public_key().to_commitment(), auth_scheme); // we need to use an initial seed to create the faucet account let mut init_seed = [0u8; 32]; client.rng().fill_bytes(&mut init_seed); let symbol = TokenSymbol::new("TEST").unwrap(); - let max_supply = Felt::try_from(9_999_999_u64.to_le_bytes().as_slice()) - .expect("u64 can be safely converted to a field element"); + let max_supply = Felt::new(9_999_999_u64); let account = AccountBuilder::new(init_seed) .account_type(AccountType::FungibleFaucet) .storage_mode(storage_mode) .with_auth_component(auth_component) .with_component(BasicFungibleFaucet::new(symbol, 10, max_supply).unwrap()) + .with_component(AuthControlled::allow_all()) .build() .unwrap(); @@ -228,7 +191,9 @@ pub async fn wait_for_tx(client: &mut TestClient, transaction_id: TransactionId) break; }, TransactionStatus::Pending => { - std::thread::sleep(Duration::from_secs(1)); + // Cooldown between polling iterations to reduce pressure on the node's + // rate limiter when many integration tests poll concurrently. + tokio::time::sleep(Duration::from_secs(2)).await; }, TransactionStatus::Discarded(cause) => { anyhow::bail!("transaction was discarded with cause: {cause:?}"); @@ -271,7 +236,7 @@ pub async fn wait_for_blocks(client: &mut TestClient, amount_of_blocks: u32) -> return summary; } - std::thread::sleep(Duration::from_secs(3)); + tokio::time::sleep(Duration::from_secs(3)).await; } } @@ -294,7 +259,7 @@ pub async fn wait_for_blocks_no_sync(client: &mut TestClient, amount_of_blocks: return; } - std::thread::sleep(Duration::from_secs(3)); + tokio::time::sleep(Duration::from_secs(3)).await; } } @@ -312,8 +277,10 @@ pub async fn wait_for_node(client: &mut TestClient) { ); for _try_number in 0..NUMBER_OF_NODE_ATTEMPTS { match client.sync_state().await { - Err(ClientError::RpcError(RpcError::ConnectionError(_))) => { - std::thread::sleep(Duration::from_secs(NODE_TIME_BETWEEN_ATTEMPTS)); + Err(ClientError::RpcError( + RpcError::ConnectionError(_) | RpcError::RequestError { .. }, + )) => { + tokio::time::sleep(Duration::from_secs(NODE_TIME_BETWEEN_ATTEMPTS)).await; }, Err(other_error) => { panic!("Unexpected error: {other_error}"); @@ -491,19 +458,17 @@ pub fn mint_multiple_fungible_asset( let notes = target_id .iter() .map(|account_id| { - OutputNote::Full( - P2idNote::create( - asset.faucet_id(), - *account_id, - vec![asset.into()], - note_type, - NoteAttachment::default(), - rng, - ) - .unwrap(), + P2idNote::create( + asset.faucet_id(), + *account_id, + vec![asset.into()], + note_type, + NoteAttachment::default(), + rng, ) + .unwrap() }) - .collect::>(); + .collect::>(); TransactionRequestBuilder::new().own_output_notes(notes).build().unwrap() } @@ -524,6 +489,10 @@ pub async fn execute_tx_and_consume_output_notes( Box::pin(client.submit_new_transaction(executor, tx_request)).await.unwrap(); + // Brief pause to allow the node to register the first transaction as in-flight before the + // second transaction references its output notes. + tokio::time::sleep(Duration::from_millis(500)).await; + let tx_request = TransactionRequestBuilder::new().input_notes(output_notes).build().unwrap(); Box::pin(client.submit_new_transaction(consumer, tx_request)).await.unwrap() } @@ -576,14 +545,14 @@ pub async fn insert_account_with_custom_component( let custom_component = AccountComponent::new( component_code, storage_slots, - AccountComponentMetadata::new("miden::testing::custom_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::custom_component", AccountType::all()), ) .map_err(ClientError::AccountError)?; let mut init_seed = [0u8; 32]; client.rng().fill_bytes(&mut init_seed); - let key_pair = AuthSecretKey::new_falcon512_rpo_with_rng(client.rng()); + let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); let pub_key = key_pair.public_key(); let account = AccountBuilder::new(init_seed) @@ -591,7 +560,7 @@ pub async fn insert_account_with_custom_component( .storage_mode(storage_mode) .with_auth_component(AuthSingleSig::new( pub_key.to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(BasicWallet) .with_component(custom_component) diff --git a/crates/rust-client/src/test_utils/mock.rs b/crates/rust-client/src/test_utils/mock.rs index d68c5350cd..aedac3d894 100644 --- a/crates/rust-client/src/test_utils/mock.rs +++ b/crates/rust-client/src/test_utils/mock.rs @@ -261,7 +261,7 @@ impl MockRpcApi { let storage_map_info = StorageMapUpdate { block_num: block_number, slot_name: slot_name.clone(), - key: *key.inner(), + key: *key, value: *value, }; updates.push(storage_map_info); @@ -295,7 +295,7 @@ impl MockRpcApi { { Some(NoteSyncRecord { note_index_in_block: u32::from( - note.inclusion_proof().location().node_index_in_block(), + note.inclusion_proof().location().block_note_tree_index(), ), note_id: Some(note.id().into()), metadata: Some(note.metadata().clone().into()), @@ -378,7 +378,7 @@ impl NodeRpcClient for MockRpcApi { Ok(NoteSyncInfo { chain_tip: self.get_chain_tip_block_num(), block_header: next_block, - mmr_path: self.get_mmr().open(block_num.as_usize()).unwrap().merkle_path, + mmr_path: self.get_mmr().open(block_num.as_usize()).unwrap().merkle_path().clone(), notes, }) } diff --git a/crates/rust-client/src/test_utils/note_transport.rs b/crates/rust-client/src/test_utils/note_transport.rs index 11cd753a3a..92f468bf94 100644 --- a/crates/rust-client/src/test_utils/note_transport.rs +++ b/crates/rust-client/src/test_utils/note_transport.rs @@ -8,8 +8,14 @@ use core::task::{Context, Poll}; use chrono::Utc; use futures::Stream; use miden_protocol::note::{NoteHeader, NoteTag}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use miden_tx::utils::sync::RwLock; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; use crate::note_transport::{ NoteInfo, diff --git a/crates/rust-client/src/transaction/mod.rs b/crates/rust-client/src/transaction/mod.rs index 708cbf9029..5bf70abff9 100644 --- a/crates/rust-client/src/transaction/mod.rs +++ b/crates/rust-client/src/transaction/mod.rs @@ -132,6 +132,9 @@ pub use miden_protocol::transaction::{ OutputNote, OutputNotes, ProvenTransaction, + PublicOutputNote, + RawOutputNote, + RawOutputNotes, TransactionArgs, TransactionId, TransactionInputs, @@ -465,7 +468,7 @@ where account_id: AccountId, tx_script: TransactionScript, advice_inputs: AdviceInputs, - foreign_accounts: BTreeSet, + foreign_accounts: BTreeMap, ) -> Result<[Felt; 16], ClientError> { let (fpi_block_number, foreign_account_inputs) = self.retrieve_foreign_account_inputs(foreign_accounts).await?; @@ -742,7 +745,7 @@ where /// retrieve it, this implies a state sync call which may update the client in other ways. async fn retrieve_foreign_account_inputs( &mut self, - foreign_accounts: BTreeSet, + foreign_accounts: BTreeMap, ) -> Result<(Option, Vec), ClientError> { if foreign_accounts.is_empty() { return Ok((None, Vec::new())); @@ -751,7 +754,7 @@ where let block_num = self.get_sync_height().await?; let mut return_foreign_account_inputs = Vec::with_capacity(foreign_accounts.len()); - for foreign_account in foreign_accounts { + for foreign_account in foreign_accounts.into_values() { let foreign_account_inputs = match foreign_account { ForeignAccount::Public(account_id, storage_requirements) => { fetch_public_account_inputs( @@ -810,7 +813,7 @@ where /// notes wouldn't be included. fn get_outgoing_assets( transaction_request: &TransactionRequest, -) -> (BTreeMap, BTreeSet) { +) -> (BTreeMap, Vec) { // Get own notes assets let mut own_notes_assets = match transaction_request.script_template() { Some(TransactionScriptTemplate::SendNotes(notes)) => notes @@ -863,22 +866,20 @@ fn validate_basic_account_request( // Check if the account balance plus incoming assets is greater than or equal to the // outgoing non fungible assets - for non_fungible in non_fungible_set { - match account.vault().has_non_fungible_asset(non_fungible) { + for non_fungible in &non_fungible_set { + match account.vault().has_non_fungible_asset(*non_fungible) { Ok(true) => (), Ok(false) => { // Check if the non fungible asset is in the incoming assets - if !incoming_non_fungible_balance_set.contains(&non_fungible) { + if !incoming_non_fungible_balance_set.contains(non_fungible) { return Err(ClientError::AssetError( - AssetError::NonFungibleFaucetIdTypeMismatch( - non_fungible.faucet_id_prefix(), - ), + AssetError::NonFungibleFaucetIdTypeMismatch(non_fungible.faucet_id()), )); } }, _ => { return Err(ClientError::AssetError(AssetError::NonFungibleFaucetIdTypeMismatch( - non_fungible.faucet_id_prefix(), + non_fungible.faucet_id(), ))); }, } @@ -928,14 +929,14 @@ pub(crate) async fn fetch_public_account_inputs( Ok(account_inputs) } -/// Extracts notes from [`OutputNotes`]. +/// Extracts notes from [`RawOutputNotes`]. /// Used for: /// - Checking the relevance of notes to save them as input notes. /// - Validate hashes versus expected output notes after a transaction is executed. -pub fn notes_from_output(output_notes: &OutputNotes) -> impl Iterator { +pub fn notes_from_output(output_notes: &RawOutputNotes) -> impl Iterator { output_notes.iter().filter_map(|n| match n { - OutputNote::Full(n) => Some(n), - OutputNote::Header(_) | OutputNote::Partial(_) => None, + RawOutputNote::Full(n) => Some(n), + RawOutputNote::Partial(_) => None, }) } diff --git a/crates/rust-client/src/transaction/prover.rs b/crates/rust-client/src/transaction/prover.rs index 91dd4a8c5c..30fa4b187f 100644 --- a/crates/rust-client/src/transaction/prover.rs +++ b/crates/rust-client/src/transaction/prover.rs @@ -20,7 +20,7 @@ impl TransactionProver for LocalTransactionProver { &self, witness: TransactionInputs, ) -> Result { - LocalTransactionProver::prove(self, witness) + LocalTransactionProver::prove(self, witness).await } } diff --git a/crates/rust-client/src/transaction/record.rs b/crates/rust-client/src/transaction/record.rs index 469ba4b73f..e0e23298ae 100644 --- a/crates/rust-client/src/transaction/record.rs +++ b/crates/rust-client/src/transaction/record.rs @@ -5,8 +5,14 @@ use core::fmt; use miden_protocol::Word; use miden_protocol::account::AccountId; use miden_protocol::block::BlockNumber; -use miden_protocol::transaction::{OutputNotes, TransactionId, TransactionScript}; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_protocol::transaction::{RawOutputNotes, TransactionId, TransactionScript}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; // TRANSACTION RECORD // ================================================================================================ @@ -83,7 +89,7 @@ pub struct TransactionDetails { /// Nullifiers of the input notes consumed in the transaction. pub input_note_nullifiers: Vec, /// Output notes generated as a result of the transaction. - pub output_notes: OutputNotes, + pub output_notes: RawOutputNotes, /// Block number for the block against which the transaction was executed. pub block_num: BlockNumber, /// Block number at which the transaction was submitted. @@ -114,7 +120,7 @@ impl Deserializable for TransactionDetails { let init_account_state = Word::read_from(source)?; let final_account_state = Word::read_from(source)?; let input_note_nullifiers = Vec::::read_from(source)?; - let output_notes = OutputNotes::read_from(source)?; + let output_notes = RawOutputNotes::read_from(source)?; let block_num = BlockNumber::read_from(source)?; let submission_height = BlockNumber::read_from(source)?; let expiration_block_num = BlockNumber::read_from(source)?; @@ -228,7 +234,7 @@ impl fmt::Display for TransactionStatus { TransactionStatus::Committed { block_number, .. } => { write!(f, "Committed (Block: {block_number})") }, - TransactionStatus::Discarded(cause) => write!(f, "Discarded ({cause})",), + TransactionStatus::Discarded(cause) => write!(f, "Discarded ({cause})"), } } } diff --git a/crates/rust-client/src/transaction/request/builder.rs b/crates/rust-client/src/transaction/request/builder.rs index 79f10f9b13..7fcab67d12 100644 --- a/crates/rust-client/src/transaction/request/builder.rs +++ b/crates/rust-client/src/transaction/request/builder.rs @@ -24,7 +24,7 @@ use miden_protocol::note::{ NoteType, PartialNote, }; -use miden_protocol::transaction::{OutputNote, TransactionScript}; +use miden_protocol::transaction::TransactionScript; use miden_protocol::vm::AdviceMap; use miden_protocol::{Felt, Word}; use miden_standards::note::{P2idNote, P2ideNote, P2ideNoteStorage, SwapNote}; @@ -54,9 +54,10 @@ pub struct TransactionRequestBuilder { /// Optional arguments of the Notes to be consumed by the transaction. This /// includes both authenticated and unauthenticated notes. input_notes_args: Vec<(NoteId, Option)>, - /// Notes to be created by the transaction. This includes both full and partial output notes. - /// The transaction script will be generated based on these notes. - own_output_notes: Vec, + /// Notes to be created by the transaction. The full note data is needed internally + /// to build the transaction script template. The conversion to [`OutputNote`] (which + /// distinguishes between public/private) happens at the protocol layer, not here. + own_output_notes: Vec, /// A map of recipients of the output notes expected to be generated by the transaction. expected_output_recipients: BTreeMap, /// A map of details and tags of notes we expect to be created as part of future transactions @@ -138,13 +139,10 @@ impl TransactionRequestBuilder { /// If a transaction script template is already set (e.g. by calling `with_custom_script`), the /// [`TransactionRequestBuilder::build`] method will return an error. #[must_use] - pub fn own_output_notes(mut self, notes: impl IntoIterator) -> Self { + pub fn own_output_notes(mut self, notes: impl IntoIterator) -> Self { for note in notes { - if let OutputNote::Full(note) = ¬e { - self.expected_output_recipients - .insert(note.recipient().digest(), note.recipient().clone()); - } - + self.expected_output_recipients + .insert(note.recipient().digest(), note.recipient().clone()); self.own_output_notes.push(note); } @@ -327,7 +325,7 @@ impl TransactionRequestBuilder { rng, )?; - self.own_output_notes(vec![OutputNote::Full(created_note)]).build() + self.own_output_notes(vec![created_note]).build() } /// Consumes the builder and returns a [`TransactionRequest`] for a transaction to send a P2ID @@ -357,7 +355,7 @@ impl TransactionRequestBuilder { let created_note = payment_data.into_note(note_type, rng)?; - self.own_output_notes(vec![OutputNote::Full(created_note)]).build() + self.own_output_notes(vec![created_note]).build() } /// Consumes the builder and returns a [`TransactionRequest`] for a transaction to send a SWAP @@ -394,7 +392,7 @@ impl TransactionRequestBuilder { let payback_tag = NoteTag::with_account_target(swap_data.account_id()); self.expected_future_notes(vec![(payback_note_details, payback_tag)]) - .own_output_notes(vec![OutputNote::Full(created_note)]) + .own_output_notes(vec![created_note]) .build() } @@ -416,7 +414,7 @@ impl TransactionRequestBuilder { scripts: Vec, rng: &mut ClientRng, ) -> Result { - let registration_notes: Vec = scripts + let registration_notes: Vec = scripts .into_iter() .map(|script| { let serial_num = rng.draw_word(); @@ -424,7 +422,7 @@ impl TransactionRequestBuilder { let recipient = NoteRecipient::new(serial_num, script, note_storage); let note_assets = NoteAssets::new(vec![])?; let metadata = NoteMetadata::new(sender_account_id, NoteType::Public); - Ok(OutputNote::Full(Note::new(note_assets, metadata, recipient))) + Ok(Note::new(note_assets, metadata, recipient)) }) .collect::>()?; @@ -464,15 +462,8 @@ impl TransactionRequestBuilder { Some(TransactionScriptTemplate::CustomScript(script)) }, (None, false) => { - let partial_notes = self - .own_output_notes - .into_iter() - .map(|note| match note { - OutputNote::Header(_) => Err(TransactionRequestError::InvalidNoteVariant), - OutputNote::Partial(note) => Ok(note), - OutputNote::Full(note) => Ok(note.into()), - }) - .collect::, _>>()?; + let partial_notes: Vec = + self.own_output_notes.into_iter().map(Into::into).collect(); Some(TransactionScriptTemplate::SendNotes(partial_notes)) }, @@ -487,7 +478,7 @@ impl TransactionRequestBuilder { expected_future_notes: self.expected_future_notes, advice_map: self.advice_map, merkle_store: self.merkle_store, - foreign_accounts: self.foreign_accounts.into_values().collect(), + foreign_accounts: self.foreign_accounts, expiration_delta: self.expiration_delta, ignore_invalid_input_notes: self.ignore_invalid_input_notes, script_arg: self.script_arg, diff --git a/crates/rust-client/src/transaction/request/foreign.rs b/crates/rust-client/src/transaction/request/foreign.rs index fd3b7ad113..3212f0af01 100644 --- a/crates/rust-client/src/transaction/request/foreign.rs +++ b/crates/rust-client/src/transaction/request/foreign.rs @@ -15,7 +15,7 @@ use miden_protocol::account::{ use miden_protocol::asset::{AssetVault, PartialVault}; use miden_protocol::crypto::merkle::smt::SmtProof; use miden_protocol::transaction::AccountInputs; -use miden_tx::utils::{Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{Deserializable, DeserializationError, Serializable}; use super::TransactionRequestError; use crate::rpc::domain::account::{ @@ -102,7 +102,7 @@ impl PartialOrd for ForeignAccount { } impl Serializable for ForeignAccount { - fn write_into(&self, target: &mut W) { + fn write_into(&self, target: &mut W) { match self { ForeignAccount::Public(account_id, storage_requirements) => { target.write(0u8); @@ -118,9 +118,9 @@ impl Serializable for ForeignAccount { } impl Deserializable for ForeignAccount { - fn read_from( + fn read_from( source: &mut R, - ) -> Result { + ) -> Result { let account_type: u8 = source.read_u8()?; match account_type { 0 => { @@ -184,7 +184,7 @@ pub(crate) fn account_proof_into_inputs( account_header.id(), account_header.nonce(), code, - PartialStorage::new(storage_details.header, storage_map_proofs.into_iter())?, + PartialStorage::new(storage_details.header, storage_map_proofs)?, PartialVault::new_full(vault), None, )?, diff --git a/crates/rust-client/src/transaction/request/mod.rs b/crates/rust-client/src/transaction/request/mod.rs index bc79fa7cd7..9b32af250c 100644 --- a/crates/rust-client/src/transaction/request/mod.rs +++ b/crates/rust-client/src/transaction/request/mod.rs @@ -32,7 +32,13 @@ use miden_protocol::vm::AdviceMap; use miden_standards::account::interface::{AccountInterface, AccountInterfaceError}; use miden_standards::code_builder::CodeBuilder; use miden_standards::errors::CodeBuilderError; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use thiserror::Error; mod builder; @@ -93,10 +99,10 @@ pub struct TransactionRequest { advice_map: AdviceMap, /// Initial state of the `MerkleStore` that provides data during runtime. merkle_store: MerkleStore, - /// Foreign account data requirements. At execution time, account data will be retrieved from - /// the network, and injected as advice inputs. Additionally, the account's code will be - /// added to the executor and prover. - foreign_accounts: BTreeSet, + /// Foreign account data requirements keyed by account ID. At execution time, account data + /// will be retrieved from the network, and injected as advice inputs. Additionally, the + /// account's code will be added to the executor and prover. + foreign_accounts: BTreeMap, /// The number of blocks in relation to the transaction's reference block after which the /// transaction will expire. If `None`, the transaction will not expire. expiration_delta: Option, @@ -131,7 +137,7 @@ impl TransactionRequest { } /// Returns the assets held by the transaction's input notes. - pub fn incoming_assets(&self) -> (BTreeMap, BTreeSet) { + pub fn incoming_assets(&self) -> (BTreeMap, Vec) { collect_assets(self.input_notes.iter().flat_map(|note| note.assets().iter())) } @@ -198,8 +204,8 @@ impl TransactionRequest { &self.merkle_store } - /// Returns the IDs of the required foreign accounts for the transaction request. - pub fn foreign_accounts(&self) -> &BTreeSet { + /// Returns the required foreign accounts keyed by account ID. + pub fn foreign_accounts(&self) -> &BTreeMap { &self.foreign_accounts } @@ -348,7 +354,8 @@ impl Serializable for TransactionRequest { self.expected_future_notes.write_into(target); self.advice_map.write_into(target); self.merkle_store.write_into(target); - self.foreign_accounts.write_into(target); + let foreign_accounts: Vec<_> = self.foreign_accounts.values().cloned().collect(); + foreign_accounts.write_into(target); self.expiration_delta.write_into(target); target.write_u8(u8::from(self.ignore_invalid_input_notes)); self.script_arg.write_into(target); @@ -384,7 +391,10 @@ impl Deserializable for TransactionRequest { let advice_map = AdviceMap::read_from(source)?; let merkle_store = MerkleStore::read_from(source)?; - let foreign_accounts = BTreeSet::::read_from(source)?; + let mut foreign_accounts = BTreeMap::new(); + for foreign_account in Vec::::read_from(source)? { + foreign_accounts.entry(foreign_account.account_id()).or_insert(foreign_account); + } let expiration_delta = Option::::read_from(source)?; let ignore_invalid_input_notes = source.read_u8()? == 1; let script_arg = Option::::read_from(source)?; @@ -415,9 +425,9 @@ impl Deserializable for TransactionRequest { /// Accumulates fungible totals and collectable non-fungible assets from an iterator of assets. pub(crate) fn collect_assets<'a>( assets: impl Iterator, -) -> (BTreeMap, BTreeSet) { +) -> (BTreeMap, Vec) { let mut fungible_balance_map = BTreeMap::new(); - let mut non_fungible_set = BTreeSet::new(); + let mut non_fungible_set = Vec::new(); assets.for_each(|asset| match asset { Asset::Fungible(fungible) => { @@ -427,7 +437,9 @@ pub(crate) fn collect_assets<'a>( .or_insert(fungible.amount()); }, Asset::NonFungible(non_fungible) => { - non_fungible_set.insert(*non_fungible); + if !non_fungible_set.contains(non_fungible) { + non_fungible_set.push(*non_fungible); + } }, }); @@ -466,8 +478,6 @@ pub enum TransactionRequestError { InputNoteNotAuthenticated(NoteId), #[error("note {0} has already been consumed")] InputNoteAlreadyConsumed(NoteId), - #[error("internal error: own notes must contain full note data, not just a header")] - InvalidNoteVariant, #[error("sender account {0} is not tracked by this client or does not exist")] InvalidSenderAccount(AccountId), #[error("invalid transaction script")] @@ -517,19 +527,18 @@ mod tests { StorageSlotName, }; use miden_protocol::asset::FungibleAsset; - use miden_protocol::crypto::rand::{FeltRng, RpoRandomCoin}; + use miden_protocol::crypto::rand::{FeltRng, RandomCoin}; use miden_protocol::note::{NoteAttachment, NoteTag, NoteType}; use miden_protocol::testing::account_id::{ ACCOUNT_ID_PRIVATE_FUNGIBLE_FAUCET, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE, ACCOUNT_ID_SENDER, }; - use miden_protocol::transaction::OutputNote; use miden_protocol::{EMPTY_WORD, Felt, Word}; use miden_standards::account::auth::AuthSingleSig; use miden_standards::note::P2idNote; use miden_standards::testing::account_component::MockAccountComponent; - use miden_tx::utils::{Deserializable, Serializable}; + use miden_tx::utils::serde::{Deserializable, Serializable}; use super::{TransactionRequest, TransactionRequestBuilder}; use crate::rpc::domain::account::AccountStorageRequirements; @@ -538,8 +547,11 @@ mod tests { #[test] fn transaction_request_serialization() { assert_transaction_request_serialization_with(|| { - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthScheme::Falcon512Rpo) - .into() + AuthSingleSig::new( + PublicKeyCommitment::from(EMPTY_WORD), + AuthScheme::Falcon512Poseidon2, + ) + .into() }); } @@ -559,7 +571,7 @@ mod tests { let target_id = AccountId::try_from(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE).unwrap(); let faucet_id = AccountId::try_from(ACCOUNT_ID_PRIVATE_FUNGIBLE_FAUCET).unwrap(); - let mut rng = RpoRandomCoin::new(Word::default()); + let mut rng = RandomCoin::new(Word::default()); let mut notes = vec![]; for i in 0..6 { @@ -608,10 +620,7 @@ mod tests { .unwrap(), ForeignAccount::private(&account).unwrap(), ]) - .own_output_notes(vec![ - OutputNote::Full(notes.pop().unwrap()), - OutputNote::Partial(notes.pop().unwrap().into()), - ]) + .own_output_notes(vec![notes.pop().unwrap(), notes.pop().unwrap()]) .script_arg(rng.draw_word()) .auth_arg(rng.draw_word()) .expected_ntx_scripts(vec![notes.first().unwrap().recipient().script().clone()]) diff --git a/crates/rust-client/src/transaction/result.rs b/crates/rust-client/src/transaction/result.rs index 7cffbb41ba..a6e4e57b4c 100644 --- a/crates/rust-client/src/transaction/result.rs +++ b/crates/rust-client/src/transaction/result.rs @@ -7,12 +7,18 @@ use miden_protocol::transaction::{ ExecutedTransaction, InputNote, InputNotes, - OutputNotes, + RawOutputNotes, TransactionArgs, TransactionId, TransactionInputs, }; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use crate::ClientError; @@ -50,7 +56,7 @@ impl TransactionResult { } /// Returns the output notes that were generated as a result of the transaction execution. - pub fn created_notes(&self) -> &OutputNotes { + pub fn created_notes(&self) -> &RawOutputNotes { self.transaction.output_notes() } diff --git a/crates/rust-client/src/transaction/store_update.rs b/crates/rust-client/src/transaction/store_update.rs index 170f89f23d..c9b448203c 100644 --- a/crates/rust-client/src/transaction/store_update.rs +++ b/crates/rust-client/src/transaction/store_update.rs @@ -3,7 +3,13 @@ use alloc::vec::Vec; use miden_protocol::block::BlockNumber; use miden_protocol::note::{NoteDetails, NoteTag}; use miden_protocol::transaction::ExecutedTransaction; -use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use miden_tx::utils::serde::{ + ByteReader, + ByteWriter, + Deserializable, + DeserializationError, + Serializable, +}; use crate::note::NoteUpdateTracker; use crate::sync::NoteTagRecord; diff --git a/crates/rust-client/src/utils.rs b/crates/rust-client/src/utils.rs index b94d21010f..3f31d78cbd 100644 --- a/crates/rust-client/src/utils.rs +++ b/crates/rust-client/src/utils.rs @@ -6,17 +6,15 @@ use alloc::vec::Vec; use core::num::ParseIntError; use miden_standards::account::faucets::BasicFungibleFaucet; -pub use miden_tx::utils::sync::{LazyLock, RwLock, RwLockReadGuard, RwLockWriteGuard}; -pub use miden_tx::utils::{ +pub use miden_tx::utils::serde::{ ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, - ToHex, - bytes_to_hex_string, - hex_to_bytes, }; +pub use miden_tx::utils::sync::{LazyLock, RwLock, RwLockReadGuard, RwLockWriteGuard}; +pub use miden_tx::utils::{ToHex, bytes_to_hex_string, hex_to_bytes}; use crate::alloc::borrow::ToOwned; diff --git a/crates/sqlite-store/src/account/accounts.rs b/crates/sqlite-store/src/account/accounts.rs index 9e69a112ba..9df1c3f4ea 100644 --- a/crates/sqlite-store/src/account/accounts.rs +++ b/crates/sqlite-store/src/account/accounts.rs @@ -319,7 +319,7 @@ impl SqliteStore { Self::insert_account_code(&tx, account.code())?; let account_id = account.id(); - let nonce = account.nonce().as_int(); + let nonce = account.nonce().as_canonical_u64(); Self::insert_storage_slots(&tx, account_id, nonce, account.storage().slots().iter())?; @@ -495,7 +495,7 @@ impl SqliteStore { Self::write_storage_delta( tx, account_id, - final_account_state.nonce().as_int(), + final_account_state.nonce().as_canonical_u64(), &updated_storage_slots, delta, )?; @@ -591,7 +591,7 @@ impl SqliteStore { ) -> Result<(), StoreError> { let account_id = new_account_state.id(); let account_id_hex = account_id.to_hex(); - let nonce = new_account_state.nonce().as_int(); + let nonce = new_account_state.nonce().as_canonical_u64(); let nonce_val = u64_to_value(nonce); // Insert and register account state in the SMT forest (handles old root cleanup) @@ -792,7 +792,7 @@ impl SqliteStore { let code_commitment = account.code_commitment().to_string(); let storage_commitment = account.storage_commitment().to_string(); let vault_root = account.vault_root().to_string(); - let nonce = u64_to_value(account.nonce().as_int()); + let nonce = u64_to_value(account.nonce().as_canonical_u64()); let commitment = account.to_commitment().to_string(); let account_seed = account_seed.map(|seed| seed.to_bytes()); diff --git a/crates/sqlite-store/src/account/helpers.rs b/crates/sqlite-store/src/account/helpers.rs index 75fc7069e7..9c55bd7fc8 100644 --- a/crates/sqlite-store/src/account/helpers.rs +++ b/crates/sqlite-store/src/account/helpers.rs @@ -164,19 +164,22 @@ pub(crate) fn query_vault_assets( conn: &Connection, account_id: AccountId, ) -> Result, StoreError> { - const VAULT_QUERY: &str = "SELECT asset FROM latest_account_assets WHERE account_id = ?"; + const VAULT_QUERY: &str = + "SELECT vault_key, asset FROM latest_account_assets WHERE account_id = ?"; conn.prepare(VAULT_QUERY) .into_store_error()? .query_map(params![account_id.to_hex()], |row| { - let asset: String = row.get(0)?; - Ok(asset) + let vault_key: String = row.get(0)?; + let asset: String = row.get(1)?; + Ok((vault_key, asset)) }) .into_store_error()? .map(|result| { - let asset_str: String = result.into_store_error()?; - let word = Word::try_from(asset_str)?; - Ok(Asset::try_from(word)?) + let (vault_key_str, asset_str): (String, String) = result.into_store_error()?; + let key_word = Word::try_from(vault_key_str)?; + let value_word = Word::try_from(asset_str)?; + Ok(Asset::from_key_value_words(key_word, value_word)?) }) .collect::, StoreError>>() } diff --git a/crates/sqlite-store/src/account/storage.rs b/crates/sqlite-store/src/account/storage.rs index 8e943bbdf1..f3bd7d7e8d 100644 --- a/crates/sqlite-store/src/account/storage.rs +++ b/crates/sqlite-store/src/account/storage.rs @@ -301,7 +301,7 @@ impl SqliteStore { for (slot_name, map_delta) in delta.storage().maps() { let old_root = old_map_roots.get(slot_name).copied().unwrap_or(default_map_root); let entries: Vec<_> = - map_delta.entries().iter().map(|(key, value)| (*key.inner(), *value)).collect(); + map_delta.entries().iter().map(|(key, value)| (*key, *value)).collect(); let new_root = smt_forest.update_storage_map_nodes(old_root, entries.into_iter())?; updated_slots.insert(slot_name.clone(), (new_root, StorageSlotType::Map)); diff --git a/crates/sqlite-store/src/account/tests.rs b/crates/sqlite-store/src/account/tests.rs index 7e4726d6fb..a238b53815 100644 --- a/crates/sqlite-store/src/account/tests.rs +++ b/crates/sqlite-store/src/account/tests.rs @@ -51,12 +51,15 @@ async fn account_code_insertion_no_duplicates() -> anyhow::Result<()> { let account_component = AccountComponent::new( component_code, vec![], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account_code = AccountCode::from_components( &[ - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo) - .into(), + AuthSingleSig::new( + PublicKeyCommitment::from(EMPTY_WORD), + AuthSchemeId::Falcon512Poseidon2, + ) + .into(), account_component, ], AccountType::RegularAccountUpdatableCode, @@ -108,7 +111,7 @@ async fn apply_account_delta_additions() -> anyhow::Result<()> { StorageSlot::with_empty_value(value_slot_name.clone()), StorageSlot::with_empty_map(map_slot_name.clone()), ], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; // Create and insert an account @@ -116,7 +119,7 @@ async fn apply_account_delta_additions() -> anyhow::Result<()> { .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build()?; @@ -137,7 +140,7 @@ async fn apply_account_delta_additions() -> anyhow::Result<()> { FungibleAsset::new(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET)?, 100)? .into(), NonFungibleAsset::new(&NonFungibleAssetDetails::new( - AccountId::try_from(ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET)?.prefix(), + AccountId::try_from(ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET)?, NON_FUNGIBLE_ASSET_DATA.into(), )?)? .into(), @@ -203,14 +206,14 @@ async fn apply_account_delta_removals() -> anyhow::Result<()> { StorageSlot::with_value(value_slot_name.clone(), [ZERO, ZERO, ZERO, ONE].into()), StorageSlot::with_map(map_slot_name.clone(), dummy_map), ], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; // Create and insert an account let assets: Vec = vec![ FungibleAsset::new(AccountId::try_from(ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET)?, 100)?.into(), NonFungibleAsset::new(&NonFungibleAssetDetails::new( - AccountId::try_from(ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET)?.prefix(), + AccountId::try_from(ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET)?, NON_FUNGIBLE_ASSET_DATA.into(), )?)? .into(), @@ -219,7 +222,7 @@ async fn apply_account_delta_removals() -> anyhow::Result<()> { .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .with_assets(assets.clone()) @@ -304,14 +307,14 @@ async fn get_account_storage_item_success() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_value(value_slot_name.clone(), test_value.into())], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -337,14 +340,14 @@ async fn get_account_storage_item_not_found() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_empty_value(value_slot_name)], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -378,14 +381,14 @@ async fn get_account_map_item_success() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_map(map_slot_name.clone(), storage_map)], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -412,14 +415,14 @@ async fn get_account_map_item_value_slot_error() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_empty_value(value_slot_name.clone())], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -443,14 +446,14 @@ async fn get_account_code() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -496,14 +499,14 @@ async fn account_reader_nonce_and_status() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build()?; @@ -572,14 +575,14 @@ async fn account_reader_storage_access() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_value(value_slot_name.clone(), test_value.into())], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -609,14 +612,14 @@ async fn account_reader_addresses_access() -> anyhow::Result<()> { let dummy_component = AccountComponent::new( basic_wallet_library(), vec![], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(dummy_component) .build_existing()?; @@ -708,14 +711,14 @@ async fn setup_account_with_map( let component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_map(map_slot_name.clone(), map)], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(component) .build()?; @@ -876,7 +879,7 @@ async fn undo_account_state_restores_previous_latest() -> anyhow::Result<()> { .interact_with_connection(move |conn| SqliteStore::get_account_header(conn, account_id)) .await? .expect("account should still exist after undo"); - assert_eq!(header.nonce().as_int(), 0); + assert_eq!(header.nonce().as_canonical_u64(), 0); assert_eq!(header.to_commitment(), initial_commitment); Ok(()) @@ -904,14 +907,14 @@ async fn undo_account_state_deletes_account_entirely() -> anyhow::Result<()> { let component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_map(map_slot_name.clone(), map)], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; let account = AccountBuilder::new([0; 32]) .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(component) .with_assets(vec![ @@ -1097,7 +1100,7 @@ async fn undo_after_update_account_state_does_not_resurrect_removed_entries() -> let component = AccountComponent::new( basic_wallet_library(), vec![StorageSlot::with_map(map_slot_name.clone(), initial_map)], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), )?; // Build with build() at nonce 0 — no initial assets @@ -1105,7 +1108,7 @@ async fn undo_after_update_account_state_does_not_resurrect_removed_entries() -> .account_type(AccountType::RegularAccountImmutableCode) .with_auth_component(AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(component) .build()?; @@ -1116,7 +1119,7 @@ async fn undo_after_update_account_state_does_not_resurrect_removed_entries() -> // Step 1+2: Apply delta at nonce 1 adding assets X and Y let asset_x = FungibleAsset::new(faucet_id, 100)?; let asset_y = NonFungibleAsset::new(&NonFungibleAssetDetails::new( - nf_faucet_id.prefix(), + nf_faucet_id, NON_FUNGIBLE_ASSET_DATA.into(), )?)?; @@ -1162,7 +1165,7 @@ async fn undo_after_update_account_state_does_not_resurrect_removed_entries() -> let mut account_updated = account_nonce1.clone(); account_updated.apply_delta(&delta_remove)?; - let updated_nonce = account_updated.nonce().as_int(); + let updated_nonce = account_updated.nonce().as_canonical_u64(); // Call update_account_state with the updated state let smt_forest = store.smt_forest.clone(); @@ -1190,10 +1193,8 @@ async fn undo_after_update_account_state_does_not_resurrect_removed_entries() -> [Felt::new(999), ZERO, ZERO, ZERO].into(), )?; - let asset_z = NonFungibleAsset::new(&NonFungibleAssetDetails::new( - nf_faucet_id.prefix(), - vec![5, 6, 7, 8], - )?)?; + let asset_z = + NonFungibleAsset::new(&NonFungibleAssetDetails::new(nf_faucet_id, vec![5, 6, 7, 8])?)?; let vault_delta_next = AccountVaultDelta::from_iters(vec![asset_z.into()], []); let delta_next = AccountDelta::new(account_id, storage_delta_next, vault_delta_next, ONE)?; @@ -1263,7 +1264,7 @@ async fn undo_after_update_account_state_does_not_resurrect_removed_entries() -> .interact_with_connection(move |conn| SqliteStore::get_account_header(conn, account_id)) .await? .expect("account should exist"); - assert_eq!(header.nonce().as_int(), updated_nonce); + assert_eq!(header.nonce().as_canonical_u64(), updated_nonce); Ok(()) } @@ -1291,7 +1292,7 @@ async fn get_account_header_by_commitment_returns_historical() -> anyhow::Result }) .await? .expect("Initial commitment should exist in historical"); - assert_eq!(header.nonce().as_int(), 0); + assert_eq!(header.nonce().as_canonical_u64(), 0); assert_eq!(header.to_commitment(), initial_commitment); // Look up the post-delta commitment — should find the nonce-1 state in historical @@ -1302,7 +1303,7 @@ async fn get_account_header_by_commitment_returns_historical() -> anyhow::Result }) .await? .expect("Post-delta commitment should exist in historical"); - assert_eq!(header.nonce().as_int(), 1); + assert_eq!(header.nonce().as_canonical_u64(), 1); assert_eq!(header.to_commitment(), post_delta_commitment); Ok(()) diff --git a/crates/sqlite-store/src/account/vault.rs b/crates/sqlite-store/src/account/vault.rs index 2ffc3c02c1..b70bd60a15 100644 --- a/crates/sqlite-store/src/account/vault.rs +++ b/crates/sqlite-store/src/account/vault.rs @@ -31,28 +31,30 @@ impl SqliteStore { .vault() .fungible() .iter() - .map(|(faucet_id, _)| Value::Text(faucet_id.prefix().to_hex())) + .map(|(vault_key, _)| Value::Text(vault_key.faucet_id().prefix().to_hex())) .collect::>(); - const QUERY: &str = "SELECT asset FROM latest_account_assets WHERE account_id = ? AND faucet_id_prefix IN rarray(?)"; + const QUERY: &str = "SELECT vault_key, asset FROM latest_account_assets WHERE account_id = ? AND faucet_id_prefix IN rarray(?)"; Ok(conn .prepare(QUERY) .into_store_error()? .query_map(params![account_id.to_hex(), Rc::new(fungible_faucet_prefixes)], |row| { - let asset: String = row.get(0)?; - Ok(asset) + let vault_key: String = row.get(0)?; + let asset: String = row.get(1)?; + Ok((vault_key, asset)) }) .into_store_error()? .map(|result| { - let asset_str: String = result.into_store_error()?; - let word = Word::try_from(asset_str)?; - Ok(Asset::try_from(word)?) + let (vault_key_str, asset_str): (String, String) = result.into_store_error()?; + let key_word = Word::try_from(vault_key_str)?; + let value_word = Word::try_from(asset_str)?; + Ok(Asset::from_key_value_words(key_word, value_word)?) }) .collect::, StoreError>>()? .into_iter() // SAFETY: all retrieved assets should be fungible - .map(|asset| (asset.faucet_id_prefix(), asset.unwrap_fungible())) + .map(|asset| (asset.faucet_id().prefix(), asset.unwrap_fungible())) .collect()) } @@ -91,10 +93,9 @@ impl SqliteStore { let nonce_val = u64_to_value(nonce); for asset in assets { - let vault_key_word: Word = asset.vault_key().into(); - let vault_key_hex = vault_key_word.to_hex(); - let faucet_prefix_hex = asset.faucet_id_prefix().to_hex(); - let asset_hex = Word::from(asset).to_hex(); + let vault_key_hex = asset.vault_key().to_string(); + let faucet_prefix_hex = asset.faucet_id().prefix().to_hex(); + let asset_hex = asset.to_value_word().to_hex(); latest_stmt .execute(params![&account_id_hex, &vault_key_hex, &faucet_prefix_hex, &asset_hex]) @@ -128,7 +129,7 @@ impl SqliteStore { mut updated_fungible_assets: BTreeMap, delta: &AccountDelta, ) -> Result<(), StoreError> { - let nonce = final_account_state.nonce().as_int(); + let nonce = final_account_state.nonce().as_canonical_u64(); let account_id_hex = account_id.to_hex(); let nonce_val = u64_to_value(nonce); @@ -139,10 +140,10 @@ impl SqliteStore { // We first process the fungible assets. Adding or subtracting them from the vault as // requested. - for (faucet_id, delta) in delta.vault().fungible().iter() { - let delta_asset = FungibleAsset::new(*faucet_id, delta.unsigned_abs())?; + for (vault_key, delta) in delta.vault().fungible().iter() { + let delta_asset = FungibleAsset::new(vault_key.faucet_id(), delta.unsigned_abs())?; - let asset = match updated_fungible_assets.remove(&faucet_id.prefix()) { + let asset = match updated_fungible_assets.remove(&vault_key.faucet_id().prefix()) { Some(asset) => { // If the asset exists, update it accordingly. if *delta >= 0 { @@ -224,7 +225,7 @@ impl SqliteStore { Rc::new( removed_vault_keys .iter() - .map(|k| Value::from(Word::from(*k).to_hex())) + .map(|k| Value::from(k.to_string())) .collect::>(), ), ], @@ -237,13 +238,12 @@ impl SqliteStore { let mut tombstone_stmt = tx.prepare_cached(HISTORICAL_TOMBSTONE_QUERY).into_store_error()?; for vault_key in removed_vault_keys { - let vault_key_word: Word = (*vault_key).into(); - let faucet_prefix_hex = vault_key.faucet_id_prefix().to_hex(); + let faucet_prefix_hex = vault_key.faucet_id().prefix().to_hex(); tombstone_stmt .execute(params![ account_id_hex, nonce_val, - vault_key_word.to_hex(), + vault_key.to_string(), faucet_prefix_hex ]) .into_store_error()?; @@ -272,10 +272,9 @@ impl SqliteStore { let mut hist_stmt = tx.prepare_cached(HISTORICAL_INSERT).into_store_error()?; for asset in updated_assets { - let vault_key_word: Word = asset.vault_key().into(); - let vault_key_hex = vault_key_word.to_hex(); - let faucet_prefix_hex = asset.faucet_id_prefix().to_hex(); - let asset_hex = Word::from(*asset).to_hex(); + let vault_key_hex = asset.vault_key().to_string(); + let faucet_prefix_hex = asset.faucet_id().prefix().to_hex(); + let asset_hex = asset.to_value_word().to_hex(); latest_stmt .execute(params![account_id_hex, &vault_key_hex, &faucet_prefix_hex, &asset_hex]) diff --git a/crates/sqlite-store/src/chain_data.rs b/crates/sqlite-store/src/chain_data.rs index 415bbf588a..aed45b3e89 100644 --- a/crates/sqlite-store/src/chain_data.rs +++ b/crates/sqlite-store/src/chain_data.rs @@ -481,7 +481,7 @@ mod test { let proof = mmr.open(block_num).expect("valid proof"); let mut idx = InOrderIndex::from_leaf_pos(block_num); - for node in proof.merkle_path.nodes() { + for node in proof.merkle_path().nodes() { tracked_nodes.insert(idx.sibling(), *node); idx = idx.parent(); } @@ -566,7 +566,10 @@ mod test { for block_num in tracked_blocks { let partial_proof = partial_mmr.open(block_num).expect("partial mmr query succeeds"); assert!(partial_proof.is_some()); - assert_eq!(partial_proof.unwrap(), mmr.open(block_num).unwrap()); + assert_eq!( + partial_proof.unwrap().merkle_path(), + mmr.open(block_num).unwrap().merkle_path() + ); } } } diff --git a/crates/sqlite-store/src/db_management/utils.rs b/crates/sqlite-store/src/db_management/utils.rs index 06d6d4ab86..abd3eb334e 100644 --- a/crates/sqlite-store/src/db_management/utils.rs +++ b/crates/sqlite-store/src/db_management/utils.rs @@ -2,8 +2,8 @@ use std::string::String; use std::sync::LazyLock; use std::vec::Vec; -use miden_client::crypto::{Blake3_160, Blake3Digest}; use miden_client::store::StoreError; +use miden_protocol::crypto::hash::blake::{Blake3_256, Blake3Digest}; use rusqlite::types::FromSql; use rusqlite::{Connection, OptionalExtension, Result, ToSql, Transaction, params}; use rusqlite_migration::{M, Migrations, SchemaVersion}; @@ -57,7 +57,7 @@ macro_rules! insert_sql { // MIGRATIONS // ================================================================================================ -type Hash = Blake3Digest<20>; +type Hash = Blake3Digest<32>; const MIGRATION_SCRIPTS: [&str; 1] = [include_str!("../store.sql")]; static MIGRATION_HASHES: LazyLock> = LazyLock::new(compute_migration_hashes); @@ -111,8 +111,8 @@ fn compute_migration_hashes() -> Vec { MIGRATION_SCRIPTS .iter() .map(|sql| { - let script_hash = Blake3_160::hash(preprocess_sql(sql).as_bytes()); - accumulator = Blake3_160::merge(&[accumulator, script_hash]); + let script_hash = Blake3_256::hash(preprocess_sql(sql).as_bytes()); + accumulator = Blake3_256::merge(&[accumulator, script_hash]); accumulator }) .collect() diff --git a/crates/testing/miden-client-tests/src/tests.rs b/crates/testing/miden-client-tests/src/tests.rs index e2ffe06448..f6d2ca5932 100644 --- a/crates/testing/miden-client-tests/src/tests.rs +++ b/crates/testing/miden-client-tests/src/tests.rs @@ -1,7 +1,7 @@ use core::future::Future; use core::pin::Pin; use std::boxed::Box; -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use std::env::temp_dir; use std::println; use std::sync::Arc; @@ -63,6 +63,7 @@ use miden_client::transaction::{ TransactionRequestError, TransactionStatus, }; +use miden_client::utils::Serializable; use miden_client::{ClientError, DebugMode}; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::account::{ @@ -82,7 +83,7 @@ use miden_protocol::account::{ StorageSlotName, }; use miden_protocol::asset::{Asset, AssetVaultKey, AssetWitness, FungibleAsset, TokenSymbol}; -use miden_protocol::crypto::rand::{FeltRng, RpoRandomCoin}; +use miden_protocol::crypto::rand::{FeltRng, RandomCoin}; use miden_protocol::note::{ Note, NoteAssets, @@ -102,12 +103,12 @@ use miden_protocol::testing::account_id::{ ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE, }; -use miden_protocol::transaction::{OutputNote, TransactionKernel}; -use miden_protocol::utils::{Deserializable, Serializable}; +use miden_protocol::transaction::{RawOutputNote, TransactionKernel}; use miden_protocol::vm::AdviceInputs; use miden_protocol::{EMPTY_WORD, Felt, ONE, Word}; use miden_standards::account::faucets::BasicFungibleFaucet; use miden_standards::account::interface::AccountInterfaceError; +use miden_standards::account::mint_policies::AuthControlled; use miden_standards::account::wallets::BasicWallet; use miden_standards::note::{NoteConsumptionStatus, P2idNoteStorage, StandardNote}; use miden_standards::testing::mock_account::MockAccountExt; @@ -294,7 +295,7 @@ async fn insert_same_account_twice_fails() { let account = Account::mock( ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); assert!(client.add_account(&account, false).await.is_ok()); @@ -308,14 +309,14 @@ async fn account_code() { let account = Account::mock( ACCOUNT_ID_REGULAR_PRIVATE_ACCOUNT_UPDATABLE_CODE, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); let account_code = account.code(); let account_code_bytes = account_code.to_bytes(); - let reconstructed_code = AccountCode::read_from_bytes(&account_code_bytes).unwrap(); + let reconstructed_code = AccountCode::from_bytes(&account_code_bytes).unwrap(); assert_eq!(*account_code, reconstructed_code); client.add_account(&account, false).await.unwrap(); @@ -330,7 +331,7 @@ async fn get_account_by_id() { let account = Account::mock( ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); client.add_account(&account, false).await.unwrap(); @@ -814,7 +815,7 @@ async fn transaction_request_expiration() { let (_, tx_outputs, ..) = transaction_result.executed_transaction().clone().into_parts(); - assert_eq!(tx_outputs.expiration_block_num, current_height + 5); + assert_eq!(tx_outputs.expiration_block_num(), current_height + 5); } #[tokio::test] @@ -890,10 +891,8 @@ async fn note_without_asset() { let note = Note::new(vault.clone(), metadata, recipient.clone()); // Create and execute transaction - let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(note)]) - .build() - .unwrap(); + let transaction_request = + TransactionRequestBuilder::new().own_output_notes(vec![note]).build().unwrap(); let transaction = Box::pin(client.execute_transaction(wallet.id(), transaction_request.clone())).await; @@ -904,10 +903,8 @@ async fn note_without_asset() { let metadata = NoteMetadata::new(faucet.id(), NoteType::Private).with_tag(tag); let note = Note::new(vault, metadata, recipient); - let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(note)]) - .build() - .unwrap(); + let transaction_request = + TransactionRequestBuilder::new().own_output_notes(vec![note]).build().unwrap(); let error = Box::pin(client.submit_new_transaction(faucet.id(), transaction_request)) .await @@ -972,7 +969,7 @@ async fn execute_program() { wallet.id(), tx_script, AdviceInputs::default(), - BTreeSet::new(), + BTreeMap::new(), )) .await .unwrap(); @@ -2361,11 +2358,11 @@ async fn empty_storage_map() { let component = AccountComponent::new( component_code, vec![map_slot], - AccountComponentMetadata::new("miden::testing::dummy_component").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::dummy_component", AccountType::all()), ) .unwrap(); - let key_pair = AuthSecretKey::new_falcon512_rpo(); + let key_pair = AuthSecretKey::new_falcon512_poseidon2(); let pub_key = key_pair.public_key(); let mut init_seed = [0u8; 32]; @@ -2376,7 +2373,7 @@ async fn empty_storage_map() { .storage_mode(AccountStorageMode::Public) .with_auth_component(AuthSingleSig::new( pub_key.to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(BasicWallet) .with_component(component) @@ -2457,8 +2454,7 @@ async fn storage_and_vault_proofs() { let bump_item_component = AccountComponent::new( bump_component_code, vec![bump_map_slot], - AccountComponentMetadata::new("miden::testing::bump_map_component") - .with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::bump_map_component", AccountType::all()), ) .unwrap(); @@ -2484,7 +2480,7 @@ async fn storage_and_vault_proofs() { ) .unwrap(); - let key_pair = AuthSecretKey::new_falcon512_rpo(); + let key_pair = AuthSecretKey::new_falcon512_poseidon2(); let pub_key = key_pair.public_key(); let mut init_seed = [0u8; 32]; @@ -2495,7 +2491,7 @@ async fn storage_and_vault_proofs() { .storage_mode(AccountStorageMode::Public) .with_auth_component(AuthSingleSig::new( pub_key.to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(BasicWallet) .with_component(bump_item_component) @@ -2549,8 +2545,7 @@ async fn storage_and_vault_proofs() { assert_eq!(account_vault_root, vault.root()); // Check that specific asset proof matches the one in the vault - let vault_key = - AssetVaultKey::from_account_id(faucet_account_id).expect("faucet id is fungible"); + let vault_key = AssetVaultKey::new_fungible(faucet_account_id).unwrap(); let (asset, witness) = client .test_store() .get_account_asset(account_id, vault_key) @@ -2593,7 +2588,7 @@ async fn account_addresses_basic_wallet() { let account = Account::mock( ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); client.add_account(&account, false).await.unwrap(); @@ -2633,7 +2628,7 @@ async fn account_add_address_after_creation() { let account = Account::mock( ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); client.add_account(&account, false).await.unwrap(); @@ -2707,7 +2702,7 @@ async fn consume_note_with_custom_script() { assert!(client.test_store().get_note_script(note_script.root()).await.is_err()); let tx_request = TransactionRequestBuilder::new() - .own_output_notes(vec![OutputNote::Full(custom_note.clone())]) + .own_output_notes(vec![custom_note.clone()]) .build() .unwrap(); let _tx_id = Box::pin(client.submit_new_transaction(sender_id, tx_request)).await.unwrap(); @@ -2762,7 +2757,7 @@ async fn add_account_fails_if_accounts_limit_is_exceeded() { (i << 8).into(), AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, ), ), false, @@ -2778,7 +2773,7 @@ async fn add_account_fails_if_accounts_limit_is_exceeded() { (RpcLimits::default().account_ids_limit << 8).into(), AuthSingleSig::new( PublicKeyCommitment::from(EMPTY_WORD), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, ), ), false, @@ -2929,7 +2924,7 @@ pub async fn create_test_client_builder() let mut rng = rand::rng(); let coin_seed: [u64; 4] = rng.random(); - let rng = RpoRandomCoin::new(coin_seed.map(Felt::new).into()); + let rng = RandomCoin::new(coin_seed.map(Felt::new).into()); let keystore_path = temp_dir(); let keystore = FilesystemKeyStore::new(keystore_path).unwrap(); @@ -2955,14 +2950,14 @@ pub async fn create_prebuilt_mock_chain() -> MockChain { .unwrap(); let note_first = - NoteBuilder::new(mock_account.id(), RpoRandomCoin::new([0, 0, 0, 0].map(Felt::new).into())) + NoteBuilder::new(mock_account.id(), RandomCoin::new([0, 0, 0, 0].map(Felt::new).into())) .note_type(NoteType::Public) .tag(NoteTag::new(0).into()) .build() .unwrap(); let note_second = - NoteBuilder::new(mock_account.id(), RpoRandomCoin::new([0, 0, 0, 1].map(Felt::new).into())) + NoteBuilder::new(mock_account.id(), RandomCoin::new([0, 0, 0, 1].map(Felt::new).into())) .note_type(NoteType::Public) .tag(NoteTag::new(0).into()) .build() @@ -2978,7 +2973,7 @@ pub async fn create_prebuilt_mock_chain() -> MockChain { mock_chain .build_tx_context(TxContextInput::AccountId(mock_account.id()), &[], &[spawn_note_1]) .unwrap() - .extend_expected_output_notes(vec![OutputNote::Full(note_first)]) + .extend_expected_output_notes(vec![RawOutputNote::Full(note_first)]) .build() .unwrap() .execute(), @@ -3000,7 +2995,7 @@ pub async fn create_prebuilt_mock_chain() -> MockChain { mock_chain .build_tx_context(mock_account.id(), &[], &[spawn_note_2]) .unwrap() - .extend_expected_output_notes(vec![OutputNote::Full(note_second.clone())]) + .extend_expected_output_notes(vec![RawOutputNote::Full(note_second.clone())]) .build() .unwrap() .execute(), @@ -3034,7 +3029,7 @@ async fn insert_new_wallet( storage_mode: AccountStorageMode, keystore: &FilesystemKeyStore, ) -> Result { - let key_pair = AuthSecretKey::new_falcon512_rpo_with_rng(client.rng()); + let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); let pub_key = key_pair.public_key(); let mut init_seed = [0u8; 32]; @@ -3045,7 +3040,7 @@ async fn insert_new_wallet( .storage_mode(storage_mode) .with_auth_component(AuthSingleSig::new( pub_key.to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(BasicWallet) .build() @@ -3092,7 +3087,7 @@ async fn insert_new_fungible_faucet( storage_mode: AccountStorageMode, keystore: &FilesystemKeyStore, ) -> Result { - let key_pair = AuthSecretKey::new_falcon512_rpo_with_rng(client.rng()); + let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); let pub_key = key_pair.public_key(); // we need to use an initial seed to create the wallet account @@ -3100,17 +3095,17 @@ async fn insert_new_fungible_faucet( client.rng().fill_bytes(&mut init_seed); let symbol = TokenSymbol::new("TEST").unwrap(); - let max_supply = Felt::try_from(9_999_999_u64.to_le_bytes().as_slice()) - .expect("u64 can be safely converted to a field element"); + let max_supply = Felt::new(9_999_999_u64); let account = AccountBuilder::new(init_seed) .account_type(AccountType::FungibleFaucet) .storage_mode(storage_mode) .with_auth_component(AuthSingleSig::new( pub_key.to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_component(BasicFungibleFaucet::new(symbol, 10, max_supply).unwrap()) + .with_component(AuthControlled::allow_all()) .build() .unwrap(); @@ -3136,8 +3131,7 @@ async fn insert_new_ecdsa_fungible_faucet( client.rng().fill_bytes(&mut init_seed); let symbol = TokenSymbol::new("TEST").unwrap(); - let max_supply = Felt::try_from(9_999_999_u64.to_le_bytes().as_slice()) - .expect("u64 can be safely converted to a field element"); + let max_supply = Felt::new(9_999_999_u64); let account = AccountBuilder::new(init_seed) .account_type(AccountType::FungibleFaucet) @@ -3147,6 +3141,7 @@ async fn insert_new_ecdsa_fungible_faucet( AuthSchemeId::EcdsaK256Keccak, )) .with_component(BasicFungibleFaucet::new(symbol, 10, max_supply).unwrap()) + .with_component(AuthControlled::allow_all()) .build() .unwrap(); @@ -3185,8 +3180,7 @@ async fn storage_and_vault_proofs_ecdsa() { let bump_item_component = AccountComponent::new( bump_component_code, vec![bump_map_slot], - AccountComponentMetadata::new("miden::testing::bump_map_component") - .with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::bump_map_component", AccountType::all()), ) .unwrap(); @@ -3273,8 +3267,7 @@ async fn storage_and_vault_proofs_ecdsa() { assert_eq!(account_vault_root, vault.root()); // Check that specific asset proof matches the one in the vault - let vault_key = - AssetVaultKey::from_account_id(faucet_account_id).expect("faucet id is fungible"); + let vault_key = AssetVaultKey::new_fungible(faucet_account_id).unwrap(); let (asset, witness) = client .test_store() .get_account_asset(account_id, vault_key) diff --git a/crates/testing/miden-client-tests/src/tests/store.rs b/crates/testing/miden-client-tests/src/tests/store.rs index 09b076808a..185cc4a3d6 100644 --- a/crates/testing/miden-client-tests/src/tests/store.rs +++ b/crates/testing/miden-client-tests/src/tests/store.rs @@ -16,10 +16,10 @@ use crate::tests::create_test_client; fn create_account_data(account_id: u128) -> AccountFile { let account = Account::mock( account_id, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); - AccountFile::new(account.clone(), vec![AuthSecretKey::new_falcon512_rpo()]) + AccountFile::new(account.clone(), vec![AuthSecretKey::new_falcon512_poseidon2()]) } fn create_ecdsa_account_data(account_id: u128) -> AccountFile { @@ -28,7 +28,7 @@ fn create_ecdsa_account_data(account_id: u128) -> AccountFile { AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::EcdsaK256Keccak), ); - AccountFile::new(account.clone(), vec![AuthSecretKey::new_falcon512_rpo()]) + AccountFile::new(account.clone(), vec![AuthSecretKey::new_falcon512_poseidon2()]) } pub fn create_initial_accounts_data() -> Vec { @@ -60,7 +60,7 @@ pub async fn try_add_account() { let account = Account::mock( ACCOUNT_ID_PRIVATE_FUNGIBLE_FAUCET, - AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Rpo), + AuthSingleSig::new(PublicKeyCommitment::from(EMPTY_WORD), AuthSchemeId::Falcon512Poseidon2), ); // The mock account has nonce 1, we need it to be 0 for the test. diff --git a/crates/testing/miden-client-tests/src/tests/transaction.rs b/crates/testing/miden-client-tests/src/tests/transaction.rs index 7dc0a5bfd2..3da2cc41ed 100644 --- a/crates/testing/miden-client-tests/src/tests/transaction.rs +++ b/crates/testing/miden-client-tests/src/tests/transaction.rs @@ -18,6 +18,7 @@ use miden_protocol::account::{ AccountComponent, AccountComponentMetadata, AccountStorageMode, + AccountType, StorageMap, StorageMapKey, StorageSlot, @@ -49,14 +50,14 @@ async fn transaction_creates_two_notes() { .unwrap() .into(); - let secret_key = AuthSecretKey::new_falcon512_rpo(); + let secret_key = AuthSecretKey::new_falcon512_poseidon2(); let pub_key = secret_key.public_key(); let account = AccountBuilder::new(Default::default()) .with_component(BasicWallet) .with_auth_component(AuthSingleSig::new( pub_key.to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .with_assets([asset_1, asset_2]) .build_existing() @@ -232,18 +233,17 @@ async fn lazy_foreign_account_loading() { let fpi_component = AccountComponent::new( component_code, vec![map_slot], - AccountComponentMetadata::new("miden::testing::fpi_lazy_component") - .with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::fpi_lazy_component", AccountType::all()), ) .unwrap(); let proc_root = fpi_component.mast_forest().procedure_digests().next().unwrap(); - let secret_key = AuthSecretKey::new_falcon512_rpo(); + let secret_key = AuthSecretKey::new_falcon512_poseidon2(); let foreign_account = AccountBuilder::new(Default::default()) .with_component(fpi_component) .with_auth_component(AuthSingleSig::new( secret_key.public_key().to_commitment(), - AuthSchemeId::Falcon512Rpo, + AuthSchemeId::Falcon512Poseidon2, )) .storage_mode(AccountStorageMode::Public) .build() @@ -290,7 +290,7 @@ async fn lazy_foreign_account_loading() { use miden::protocol::tx begin push.{proc_root} - push.{suffix} push.{prefix} + push.{prefix} push.{suffix} exec.tx::execute_foreign_procedure push.{map_value} assert_eqw end diff --git a/crates/testing/node-builder/src/lib.rs b/crates/testing/node-builder/src/lib.rs index f915c91b3b..fd690bd82a 100644 --- a/crates/testing/node-builder/src/lib.rs +++ b/crates/testing/node-builder/src/lib.rs @@ -18,6 +18,7 @@ use miden_node_block_producer::{ use miden_node_ntx_builder::NtxBuilderConfig; use miden_node_rpc::Rpc; use miden_node_store::{GenesisState, Store}; +use miden_node_utils::clap::{GrpcOptionsExternal, GrpcOptionsInternal, StorageOptions}; use miden_node_utils::crypto::get_rpo_random_coin; use miden_node_validator::{Validator, ValidatorSigner}; use miden_protocol::account::auth::{AuthScheme, AuthSecretKey}; @@ -27,6 +28,7 @@ use miden_protocol::account::{ AccountComponent, AccountComponentMetadata, AccountFile, + AccountType, StorageMap, StorageMapKey, }; @@ -34,7 +36,7 @@ use miden_protocol::asset::{Asset, FungibleAsset, TokenSymbol}; use miden_protocol::block::FeeParameters; use miden_protocol::crypto::dsa::ecdsa_k256_keccak; use miden_protocol::testing::account_id::ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET; -use miden_protocol::utils::Serializable; +use miden_protocol::utils::serde::Serializable; use miden_protocol::{Felt, ONE, Word}; use miden_standards::AuthMethod; use miden_standards::account::auth::AuthSingleSig; @@ -50,7 +52,6 @@ pub const DEFAULT_BLOCK_INTERVAL: u64 = 5_000; pub const DEFAULT_BATCH_INTERVAL: u64 = 2_000; pub const DEFAULT_RPC_PORT: u16 = 57_291; pub const GENESIS_ACCOUNT_FILE: &str = "account.mac"; -const DEFAULT_TIMEOUT_DURATION: Duration = Duration::from_secs(10); /// Builder for configuring and starting a Miden node with all components. pub struct NodeBuilder { @@ -138,10 +139,27 @@ impl NodeBuilder { ); // Bootstrap the store database - Store::bootstrap(genesis_state, &self.data_directory) + let genesis_block = genesis_state + .into_block() .await + .with_context(|| "failed to create genesis block")?; + + Store::bootstrap(&genesis_block, &self.data_directory) .with_context(|| "failed to bootstrap store")?; + // Bootstrap the validator database with the genesis block header so that block + // validation can find the chain tip. + let validator_db = + miden_node_validator::db::load(self.data_directory.join("validator.sqlite3")) + .await + .with_context(|| "failed to initialize validator database")?; + validator_db + .transact("bootstrap_validator", move |conn| { + miden_node_validator::db::upsert_block_header(conn, genesis_block.inner().header()) + }) + .await + .with_context(|| "failed to bootstrap validator with genesis block header")?; + // Start listening on all gRPC urls so that inter-component connections can be created // before each component is fully started up. let grpc_rpc = TcpListener::bind(format!("127.0.0.1:{}", self.rpc_port)) @@ -167,6 +185,13 @@ impl NodeBuilder { .local_addr() .with_context(|| "failed to retrieve the store's ntx-builder gRPC address")?; + let ntx_builder_listener = TcpListener::bind("127.0.0.1:0") + .await + .with_context(|| "failed to bind to ntx-builder gRPC endpoint")?; + let ntx_builder_address = ntx_builder_listener + .local_addr() + .with_context(|| "failed to retrieve the ntx-builder gRPC address")?; + let block_producer_address = available_socket_addr() .await .with_context(|| "failed to bind to block-producer gRPC endpoint")?; @@ -192,6 +217,7 @@ impl NodeBuilder { store_ntx_builder_address, validator_address, self.data_directory.join("ntx-builder.sqlite3"), + Some(ntx_builder_listener), &mut join_set, ); @@ -207,7 +233,7 @@ impl NodeBuilder { async move { Validator { address: validator_address, - grpc_timeout: DEFAULT_TIMEOUT_DURATION, + grpc_options: GrpcOptionsInternal::default(), signer: ValidatorSigner::Local(validator_signer), data_directory: self.data_directory, } @@ -229,12 +255,18 @@ impl NodeBuilder { let validator_url = Url::parse(&format!("http://{validator_address}")) .context("Failed to parse URL")?; + let ntx_builder_url = Some( + Url::parse(&format!("http://{ntx_builder_address}")) + .context("Failed to parse URL")?, + ); + Rpc { listener: grpc_rpc, store_url, block_producer_url, validator_url, - grpc_timeout: DEFAULT_TIMEOUT_DURATION, + ntx_builder_url, + grpc_options: GrpcOptionsExternal::default(), } .serve() .await @@ -290,7 +322,8 @@ impl NodeBuilder { block_producer_listener, ntx_builder_listener, block_prover_url: None, - grpc_timeout: DEFAULT_TIMEOUT_DURATION, + storage_options: StorageOptions::default(), + grpc_options: GrpcOptionsInternal::default(), } .serve() .await @@ -321,7 +354,7 @@ impl NodeBuilder { BlockProducer { block_producer_address, store_url, - grpc_timeout: DEFAULT_TIMEOUT_DURATION, + grpc_options: GrpcOptionsInternal::default(), batch_prover_url: None, validator_url, batch_interval, @@ -343,6 +376,7 @@ impl NodeBuilder { store_address: SocketAddr, validator_address: SocketAddr, database_filepath: PathBuf, + listener: Option, join_set: &mut JoinSet>, ) -> Id { let store_url = @@ -366,10 +400,11 @@ impl NodeBuilder { validator_url, database_filepath, ) + .with_max_cycles(1 << 18) .build() .await .context("failed to build ntx builder")? - .run() + .run(listener) .await .context("failed while serving ntx builder component") }) @@ -408,10 +443,11 @@ impl NodeHandle { fn generate_genesis_account() -> anyhow::Result { let mut rng = ChaCha20Rng::from_seed(random()); - let secret = AuthSecretKey::new_falcon512_rpo_with_rng(&mut get_rpo_random_coin(&mut rng)); + let secret = + AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut get_rpo_random_coin(&mut rng)); let auth_method = AuthMethod::SingleSig { - approver: (secret.public_key().to_commitment(), AuthScheme::Falcon512Rpo), + approver: (secret.public_key().to_commitment(), AuthScheme::Falcon512Poseidon2), }; let account = create_basic_fungible_faucet( @@ -455,18 +491,19 @@ const TEST_ACCOUNT_SEED: [u8; 32] = [0xa; 32]; /// and trigger the `too_many_assets` flag during testing. const NUM_TEST_FAUCETS: u128 = 1501; -const NUM_STORAGE_MAP_ENTRIES: u32 = 2001; +const NUM_STORAGE_MAP_ENTRIES: u32 = 200; const FAUCET_DECIMALS: u8 = 12; const FAUCET_MAX_SUPPLY: u32 = 1 << 30; -const ASSET_AMOUNT_PER_FAUCET: u64 = 100; +const ASSET_AMOUNT_PER_FAUCET: u64 = 75; /// Builds test faucets and an account that triggers the `too_many_assets` flag /// when requested from the node. This is used to test edge cases in account /// retrieval and asset handling. fn build_test_faucets_and_account() -> anyhow::Result> { let mut rng = ChaCha20Rng::from_seed(random()); - let secret = AuthSecretKey::new_falcon512_rpo_with_rng(&mut get_rpo_random_coin(&mut rng)); + let secret = + AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut get_rpo_random_coin(&mut rng)); let faucets = create_test_faucets(&secret)?; let account = create_test_account_with_many_assets(&faucets)?; @@ -498,7 +535,7 @@ fn create_single_test_faucet(index: u128, secret: &AuthSecretKey) -> anyhow::Res .expect("concatenating two 16-byte arrays yields exactly 32 bytes"); let auth_scheme = AuthMethod::SingleSig { - approver: (secret.public_key().to_commitment(), AuthScheme::Falcon512Rpo), + approver: (secret.public_key().to_commitment(), AuthScheme::Falcon512Poseidon2), }; let faucet = create_basic_fungible_faucet( @@ -518,14 +555,15 @@ fn create_single_test_faucet(index: u128, secret: &AuthSecretKey) -> anyhow::Res /// Creates a test account holding assets from all provided faucets. /// The account also includes a large storage map to test storage capacity limits. fn create_test_account_with_many_assets(faucets: &[Account]) -> anyhow::Result { - let sk = - AuthSecretKey::new_falcon512_rpo_with_rng(&mut ChaCha20Rng::from_seed(TEST_ACCOUNT_SEED)); + let sk = AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut ChaCha20Rng::from_seed( + TEST_ACCOUNT_SEED, + )); let storage_map = create_large_storage_map(); let acc_component = AccountComponent::new( basic_wallet_library(), vec![storage_map], - AccountComponentMetadata::new("miden::testing::basic_wallet").with_supports_all_types(), + AccountComponentMetadata::new("miden::testing::basic_wallet", AccountType::all()), ) .expect("basic wallet component should satisfy account component requirements"); @@ -539,7 +577,7 @@ fn create_test_account_with_many_assets(faucets: &[Account]) -> anyhow::Result { // Global state variables. let wasmWebClient = null; let wasmSeed = null; // Seed for the WASM WebClient, if needed. +let wasmStoreName = null; // Store name for the WASM WebClient, if needed. let ready = false; // Indicates if the worker is fully initialized. let messageQueue = []; // Queue for sequential processing. let processing = false; // Flag to ensure one message is processed at a time. @@ -301,7 +302,8 @@ methodHandlers[MethodName.SYNC_STATE_MOCK] = async (args) => { await wasmWebClient.createMockClient( wasmSeed, serializedMockChain, - serializedMockNoteTransportNode + serializedMockNoteTransportNode, + wasmStoreName ); return await methodHandlers[MethodName.SYNC_STATE](); @@ -320,7 +322,8 @@ methodHandlers[MethodName.SUBMIT_NEW_TRANSACTION_MOCK] = async (args) => { await wasmWebClient.createMockClient( wasmSeed, serializedMockChain, - serializedMockNoteTransportNode + serializedMockNoteTransportNode, + wasmStoreName ); const result = await methodHandlers[MethodName.SUBMIT_NEW_TRANSACTION](args); @@ -421,7 +424,7 @@ async function processMessage(event) { self.postMessage({ ready: true }); return; } else if (action === WorkerAction.INIT_MOCK) { - const [seed, logLevel] = args; + const [seed, storeName, logLevel] = args; const wasm = await getWasmOrThrow(); if (logLevel) { @@ -429,9 +432,15 @@ async function processMessage(event) { } wasmWebClient = new wasm.WebClient(); - await wasmWebClient.createMockClient(seed); + await wasmWebClient.createMockClient( + seed, + undefined, + undefined, + storeName + ); wasmSeed = seed; + wasmStoreName = storeName; ready = true; self.postMessage({ ready: true }); return; diff --git a/crates/web-client/package.json b/crates/web-client/package.json index c5e7333365..6c9d78d901 100644 --- a/crates/web-client/package.json +++ b/crates/web-client/package.json @@ -1,6 +1,6 @@ { "name": "@miden-sdk/miden-sdk", - "version": "0.13.1", + "version": "0.14.0", "description": "Miden Wasm SDK", "collaborators": [ "Miden" diff --git a/crates/web-client/src/helpers.rs b/crates/web-client/src/helpers.rs index c61280ab59..3362eb9ca2 100644 --- a/crates/web-client/src/helpers.rs +++ b/crates/web-client/src/helpers.rs @@ -36,30 +36,20 @@ pub(crate) async fn generate_wallet( }; let native_scheme: NativeAuthScheme = auth_scheme.try_into()?; - let (key_pair, auth_component) = match native_scheme { - NativeAuthScheme::Falcon512Rpo => { - let key_pair = AuthSecretKey::new_falcon512_rpo_with_rng(&mut rng); - let auth_component: AccountComponent = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - NativeAuthScheme::Falcon512Rpo, - ) - .into(); - (key_pair, auth_component) + let key_pair = match native_scheme { + NativeAuthScheme::Falcon512Poseidon2 => { + AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut rng) }, NativeAuthScheme::EcdsaK256Keccak => { - let key_pair = AuthSecretKey::new_ecdsa_k256_keccak_with_rng(&mut rng); - let auth_component: AccountComponent = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - NativeAuthScheme::EcdsaK256Keccak, - ) - .into(); - (key_pair, auth_component) + AuthSecretKey::new_ecdsa_k256_keccak_with_rng(&mut rng) }, _ => { let message = format!("unsupported auth scheme: {native_scheme:?}"); return Err(JsValue::from_str(&message)); }, }; + let auth_component: AccountComponent = + AuthSingleSig::new(key_pair.public_key().to_commitment(), native_scheme).into(); let account_type = if mutable { AccountType::RegularAccountUpdatableCode diff --git a/crates/web-client/src/lib.rs b/crates/web-client/src/lib.rs index 402545c458..b5e65a7c1e 100644 --- a/crates/web-client/src/lib.rs +++ b/crates/web-client/src/lib.rs @@ -6,7 +6,7 @@ use core::fmt::Write; use idxdb_store::IdxdbStore; use js_sys::{Function, Reflect}; use miden_client::builder::ClientBuilder; -use miden_client::crypto::RpoRandomCoin; +use miden_client::crypto::RandomCoin; use miden_client::note_transport::NoteTransportClient; use miden_client::note_transport::grpc::GrpcNoteTransportClient; use miden_client::rpc::{Endpoint, GrpcClient, NodeRpcClient}; @@ -47,7 +47,7 @@ pub use web_keystore::WebKeyStore; /// Client authenticator type. Gate with `#[cfg]` to support other keystores, e.g. /// `FilesystemKeyStore` for Node.js. -pub(crate) type ClientAuth = WebKeyStore; +pub(crate) type ClientAuth = WebKeyStore; const BASE_STORE_NAME: &str = "MidenClientDB"; @@ -253,7 +253,7 @@ impl WebClient { rpc_client: Arc, store: Arc, keystore: Arc, - rng: RpoRandomCoin, + rng: RandomCoin, note_transport_client: Option>, debug_mode: bool, ) -> Result<(), JsValue> { @@ -303,7 +303,7 @@ impl WebClient { // HELPERS // ================================================================================================ -pub(crate) fn create_rng(seed: Option>) -> Result { +pub(crate) fn create_rng(seed: Option>) -> Result { let mut rng = match seed { Some(seed_bytes) => { if seed_bytes.len() == 32 { @@ -317,7 +317,7 @@ pub(crate) fn create_rng(seed: Option>) -> Result StdRng::from_os_rng(), }; let coin_seed: [u64; 4] = rng.random(); - Ok(RpoRandomCoin::new(coin_seed.map(Felt::new).into())) + Ok(RandomCoin::new(coin_seed.map(Felt::new).into())) } // ERROR HANDLING HELPERS diff --git a/crates/web-client/src/mock.rs b/crates/web-client/src/mock.rs index 5363235e9e..7790f20cac 100644 --- a/crates/web-client/src/mock.rs +++ b/crates/web-client/src/mock.rs @@ -20,6 +20,7 @@ impl WebClient { seed: Option>, serialized_mock_chain: Option>, serialized_mock_note_transport_node: Option>, + store_name: Option, ) -> Result { let mock_rpc_api = match serialized_mock_chain { Some(chain) => { @@ -40,20 +41,16 @@ impl WebClient { None => Arc::new(MockNoteTransportApi::default()), }; + let store_name = store_name.unwrap_or_else(|| "mock_client_db".to_owned()); + let store = Arc::new( - IdxdbStore::new("mock_client_db".to_owned()) + IdxdbStore::new(store_name.clone()) .await .map_err(|_| JsValue::from_str("Failed to initialize IdxdbStore"))?, ); let rng = create_rng(seed)?; - let keystore = Arc::new(WebKeyStore::new_with_callbacks( - rng, - "mock_client_db".to_owned(), - None, - None, - None, - )); + let keystore = Arc::new(WebKeyStore::new_with_callbacks(rng, store_name, None, None, None)); self.setup_client( mock_rpc_api.clone(), diff --git a/crates/web-client/src/models/account_component.rs b/crates/web-client/src/models/account_component.rs index c9d389042a..126ac10e16 100644 --- a/crates/web-client/src/models/account_component.rs +++ b/crates/web-client/src/models/account_component.rs @@ -5,6 +5,7 @@ use miden_client::account::component::{ }; use miden_client::account::{ AccountComponentCode as NativeAccountComponentCode, + AccountType, StorageSlot as NativeStorageSlot, }; use miden_client::assembly::{Library as NativeLibrary, MastNodeExt}; @@ -50,10 +51,13 @@ impl GetProceduresResultItem { } } -impl From<&(NativeWord, bool)> for GetProceduresResultItem { - fn from(native_get_procedures_result_item: &(NativeWord, bool)) -> Self { +impl From<(miden_protocol::account::AccountProcedureRoot, bool)> for GetProceduresResultItem { + fn from( + native_get_procedures_result_item: (miden_protocol::account::AccountProcedureRoot, bool), + ) -> Self { + let digest_word: NativeWord = native_get_procedures_result_item.0.into(); Self { - digest: native_get_procedures_result_item.0.into(), + digest: digest_word.into(), is_auth: native_get_procedures_result_item.1, } } @@ -78,7 +82,7 @@ impl AccountComponent { NativeAccountComponent::new( native_account_code, native_slots, - AccountComponentMetadata::new("custom"), + AccountComponentMetadata::new("custom", AccountType::all()), ) .map(AccountComponent) .map_err(|e| js_error_with_context(e, "Failed to compile account component")) @@ -87,9 +91,10 @@ impl AccountComponent { /// Marks the component as supporting all account types. #[wasm_bindgen(js_name = "withSupportsAllTypes")] pub fn with_supports_all_types(self) -> Self { - let metadata = self.0.metadata().clone().with_supports_all_types(); let code = self.0.component_code().clone(); let slots = self.0.storage_slots().to_vec(); + let name = self.0.metadata().name(); + let metadata = AccountComponentMetadata::new(name, AccountType::all()); AccountComponent( NativeAccountComponent::new(code, slots, metadata) .expect("reconstructing component with updated metadata should not fail"), @@ -140,7 +145,7 @@ impl AccountComponent { /// Returns all procedures exported by this component. #[wasm_bindgen(js_name = "getProcedures")] pub fn get_procedures(&self) -> Vec { - self.0.get_procedures().iter().map(Into::into).collect() + self.0.procedures().map(Into::into).collect() } fn create_auth_component( @@ -149,7 +154,7 @@ impl AccountComponent { ) -> AccountComponent { match auth_scheme { AuthScheme::AuthRpoFalcon512 => { - let auth = NativeSingleSig::new(commitment, NativeAuthSchemeId::Falcon512Rpo); + let auth = NativeSingleSig::new(commitment, NativeAuthSchemeId::Falcon512Poseidon2); AccountComponent(auth.into()) }, AuthScheme::AuthEcdsaK256Keccak => { @@ -169,7 +174,7 @@ impl AccountComponent { let auth_scheme = match native_secret_key { NativeSecretKey::EcdsaK256Keccak(_) => AuthScheme::AuthEcdsaK256Keccak, - NativeSecretKey::Falcon512Rpo(_) => AuthScheme::AuthRpoFalcon512, + NativeSecretKey::Falcon512Poseidon2(_) => AuthScheme::AuthRpoFalcon512, // This is because the definition of NativeSecretKey has the // '#[non_exhaustive]' attribute, without this catch-all clause, // this is a compiler error. @@ -211,7 +216,7 @@ impl AccountComponent { NativeAccountComponent::new( native_library, native_slots, - AccountComponentMetadata::new("custom"), + AccountComponentMetadata::new("custom", AccountType::all()), ) .map(AccountComponent) .map_err(|e| js_error_with_context(e, "Failed to create account component from package")) @@ -230,7 +235,7 @@ impl AccountComponent { NativeAccountComponent::new( native_library, native_slots, - AccountComponentMetadata::new("custom"), + AccountComponentMetadata::new("custom", AccountType::all()), ) .map(AccountComponent) .map_err(|e| js_error_with_context(e, "Failed to create account component from library")) diff --git a/crates/web-client/src/models/account_delta/vault.rs b/crates/web-client/src/models/account_delta/vault.rs index 3ca8460487..549d41f3da 100644 --- a/crates/web-client/src/models/account_delta/vault.rs +++ b/crates/web-client/src/models/account_delta/vault.rs @@ -50,7 +50,9 @@ impl AccountVaultDelta { .fungible() .iter() .filter(|&(_, &value)| value > 0) - .map(|(faucet_id, &diff)| FungibleAsset::new(&faucet_id.into(), diff.unsigned_abs())) + .map(|(vault_key, &diff)| { + FungibleAsset::new(&vault_key.faucet_id().into(), diff.unsigned_abs()) + }) .collect() } @@ -61,7 +63,9 @@ impl AccountVaultDelta { .fungible() .iter() .filter(|&(_, &value)| value < 0) - .map(|(faucet_id, &diff)| FungibleAsset::new(&faucet_id.into(), diff.unsigned_abs())) + .map(|(vault_key, &diff)| { + FungibleAsset::new(&vault_key.faucet_id().into(), diff.unsigned_abs()) + }) .collect() } } @@ -89,10 +93,10 @@ impl FungibleAssetDeltaItem { } } -impl From<(&NativeAccountId, &i64)> for FungibleAssetDeltaItem { - fn from(native_fungible_asset_delta_item: (&NativeAccountId, &i64)) -> Self { +impl From<(&miden_client::asset::AssetVaultKey, &i64)> for FungibleAssetDeltaItem { + fn from(native_fungible_asset_delta_item: (&miden_client::asset::AssetVaultKey, &i64)) -> Self { Self { - faucet_id: (*native_fungible_asset_delta_item.0).into(), + faucet_id: native_fungible_asset_delta_item.0.faucet_id().into(), amount: *native_fungible_asset_delta_item.1, } } @@ -124,7 +128,9 @@ impl FungibleAssetDelta { /// Returns the delta amount for a given faucet, if present. pub fn amount(&self, faucet_id: &AccountId) -> Option { let native_faucet_id: NativeAccountId = faucet_id.into(); - self.0.amount(&native_faucet_id) + let vault_key = miden_protocol::asset::AssetVaultKey::new_fungible(native_faucet_id) + .expect("faucet_id should be a fungible faucet"); + self.0.amount(&vault_key) } /// Returns the number of distinct fungible assets in the delta. diff --git a/crates/web-client/src/models/account_id.rs b/crates/web-client/src/models/account_id.rs index 0a1883f620..902aa551ef 100644 --- a/crates/web-client/src/models/account_id.rs +++ b/crates/web-client/src/models/account_id.rs @@ -110,8 +110,8 @@ impl AccountId { pub fn from_prefix_suffix(prefix: &Felt, suffix: &Felt) -> Result { let prefix_felt: NativeFelt = (*prefix).into(); let suffix_felt: NativeFelt = (*suffix).into(); - let native_account_id = - NativeAccountId::try_from([prefix_felt, suffix_felt]).map_err(|err| { + let native_account_id = NativeAccountId::try_from_elements(suffix_felt, prefix_felt) + .map_err(|err| { js_error_with_context(err, "error instantiating AccountId from prefix and suffix") })?; Ok(AccountId(native_account_id)) diff --git a/crates/web-client/src/models/auth_scheme.rs b/crates/web-client/src/models/auth_scheme.rs index 738a26c863..e58e797779 100644 --- a/crates/web-client/src/models/auth_scheme.rs +++ b/crates/web-client/src/models/auth_scheme.rs @@ -15,7 +15,7 @@ pub enum AuthScheme { // Compile-time check to ensure both enums stay aligned. const _: () = { - assert!(NativeAuthSchemeId::Falcon512Rpo as u8 == AuthScheme::AuthRpoFalcon512 as u8); + assert!(NativeAuthSchemeId::Falcon512Poseidon2 as u8 == AuthScheme::AuthRpoFalcon512 as u8); assert!(NativeAuthSchemeId::EcdsaK256Keccak as u8 == AuthScheme::AuthEcdsaK256Keccak as u8); }; @@ -24,7 +24,7 @@ impl TryFrom for NativeAuthSchemeId { fn try_from(value: AuthScheme) -> Result { match value { - AuthScheme::AuthRpoFalcon512 => Ok(NativeAuthSchemeId::Falcon512Rpo), + AuthScheme::AuthRpoFalcon512 => Ok(NativeAuthSchemeId::Falcon512Poseidon2), AuthScheme::AuthEcdsaK256Keccak => Ok(NativeAuthSchemeId::EcdsaK256Keccak), } } @@ -35,7 +35,7 @@ impl TryFrom for AuthScheme { fn try_from(value: NativeAuthSchemeId) -> Result { match value { - NativeAuthSchemeId::Falcon512Rpo => Ok(AuthScheme::AuthRpoFalcon512), + NativeAuthSchemeId::Falcon512Poseidon2 => Ok(AuthScheme::AuthRpoFalcon512), NativeAuthSchemeId::EcdsaK256Keccak => Ok(AuthScheme::AuthEcdsaK256Keccak), _ => Err(unsupported_scheme_error(value)), } diff --git a/crates/web-client/src/models/auth_secret_key.rs b/crates/web-client/src/models/auth_secret_key.rs index c363300faa..45d124a173 100644 --- a/crates/web-client/src/models/auth_secret_key.rs +++ b/crates/web-client/src/models/auth_secret_key.rs @@ -22,7 +22,7 @@ impl AuthSecretKey { #[wasm_bindgen(js_name = "rpoFalconWithRNG")] pub fn rpo_falcon_with_rng(seed: Option>) -> Result { let mut rng = Self::try_rng_from_seed(seed)?; - Ok(NativeAuthSecretKey::new_falcon512_rpo_with_rng(&mut rng).into()) + Ok(NativeAuthSecretKey::new_falcon512_poseidon2_with_rng(&mut rng).into()) } #[wasm_bindgen(js_name = "ecdsaWithRNG")] @@ -80,7 +80,7 @@ impl AuthSecretKey { #[wasm_bindgen(js_name = "getRpoFalcon512SecretKeyAsFelts")] pub fn get_rpo_falcon_512_secret_key_as_felts(&self) -> Result, JsValue> { let secret_key_as_bytes = match &self.0 { - NativeAuthSecretKey::Falcon512Rpo(key) => key.to_bytes(), + NativeAuthSecretKey::Falcon512Poseidon2(key) => key.to_bytes(), _ => return Err(JsValue::from_str("Key is not an RPO Falcon 512 key")), }; diff --git a/crates/web-client/src/models/components/auth_falcon512_rpo_multisig.rs b/crates/web-client/src/models/components/auth_falcon512_rpo_multisig.rs index 3b02850727..7181bcbbf0 100644 --- a/crates/web-client/src/models/components/auth_falcon512_rpo_multisig.rs +++ b/crates/web-client/src/models/components/auth_falcon512_rpo_multisig.rs @@ -56,7 +56,7 @@ impl AuthFalcon512RpoMultisigConfig { .into_iter() .map(|word| { let native_word: NativeWord = word.into(); - (PublicKeyCommitment::from(native_word), NativeAuthSchemeId::Falcon512Rpo) + (PublicKeyCommitment::from(native_word), NativeAuthSchemeId::Falcon512Poseidon2) }) .collect(); diff --git a/crates/web-client/src/models/executed_transaction.rs b/crates/web-client/src/models/executed_transaction.rs index 83142caeb5..2689652bae 100644 --- a/crates/web-client/src/models/executed_transaction.rs +++ b/crates/web-client/src/models/executed_transaction.rs @@ -7,7 +7,7 @@ use super::account_header::AccountHeader; use super::account_id::AccountId; use super::block_header::BlockHeader; use super::input_notes::InputNotes; -use super::output_notes::OutputNotes; +use super::raw_output_notes::RawOutputNotes; use super::transaction_args::TransactionArgs; use super::transaction_id::TransactionId; @@ -57,9 +57,9 @@ impl ExecutedTransaction { self.0.input_notes().into() } - /// Returns the output notes produced by the transaction. - #[wasm_bindgen(js_name = "outputNotes")] - pub fn output_notes(&self) -> OutputNotes { + /// Returns the raw output notes produced by the transaction. + #[wasm_bindgen(js_name = "rawOutputNotes")] + pub fn raw_output_notes(&self) -> RawOutputNotes { self.0.output_notes().into() } diff --git a/crates/web-client/src/models/felt.rs b/crates/web-client/src/models/felt.rs index 668ef881da..48d16a8889 100644 --- a/crates/web-client/src/models/felt.rs +++ b/crates/web-client/src/models/felt.rs @@ -19,7 +19,7 @@ impl Felt { /// Returns the integer representation of the field element. #[wasm_bindgen(js_name = "asInt")] pub fn as_int(&self) -> u64 { - self.0.as_int() + self.0.as_canonical_u64() } /// Returns the string representation of the field element. diff --git a/crates/web-client/src/models/fungible_asset.rs b/crates/web-client/src/models/fungible_asset.rs index 2d133acd20..ee191129b6 100644 --- a/crates/web-client/src/models/fungible_asset.rs +++ b/crates/web-client/src/models/fungible_asset.rs @@ -39,7 +39,7 @@ impl FungibleAsset { /// Encodes this asset into the word layout used in the vault. #[wasm_bindgen(js_name = "intoWord")] pub fn into_word(&self) -> Word { - let native_word: NativeWord = self.0.into(); + let native_word: NativeWord = self.0.to_value_word(); native_word.into() } } diff --git a/crates/web-client/src/models/mod.rs b/crates/web-client/src/models/mod.rs index b5bac8061c..74d2c0425a 100644 --- a/crates/web-client/src/models/mod.rs +++ b/crates/web-client/src/models/mod.rs @@ -88,16 +88,16 @@ pub mod note_storage; pub mod note_sync_info; pub mod note_tag; pub mod note_type; -pub mod output_note; pub mod output_note_record; pub mod output_note_state; -pub mod output_notes; pub mod package; pub mod partial_note; pub mod program; pub mod proven_transaction; pub mod provers; pub mod public_key; +pub mod raw_output_note; +pub mod raw_output_notes; pub mod rpo256; pub mod signature; pub mod signing_inputs; @@ -127,11 +127,11 @@ declare_js_miden_arrays! { (crate::models::account_id::AccountId) -> AccountIdArray, (crate::models::foreign_account::ForeignAccount) -> ForeignAccountArray, (crate::models::note_recipient::NoteRecipient) -> NoteRecipientArray, - (crate::models::output_note::OutputNote) -> OutputNoteArray, + (crate::models::note::Note) -> NoteArray, + (crate::models::raw_output_note::RawOutputNote) -> RawOutputNoteArray, (crate::models::storage_slot::StorageSlot) -> StorageSlotArray, (crate::models::transaction_script_inputs::TransactionScriptInputPair) -> TransactionScriptInputPairArray, (crate::models::felt::Felt) -> FeltArray, - (crate::models::output_notes::OutputNotes) -> OutputNotesArray, (crate::models::transaction_request::note_and_args::NoteAndArgs) -> NoteAndArgsArray, (crate::models::transaction_request::note_details_and_tag::NoteDetailsAndTag) -> NoteDetailsAndTagArray, (crate::models::transaction_request::note_id_and_args::NoteIdAndArgs) -> NoteIdAndArgsArray diff --git a/crates/web-client/src/models/note.rs b/crates/web-client/src/models/note.rs index d9feded143..99aa0a2dc3 100644 --- a/crates/web-client/src/models/note.rs +++ b/crates/web-client/src/models/note.rs @@ -1,6 +1,6 @@ use miden_client::asset::Asset as NativeAsset; use miden_client::block::BlockNumber as NativeBlockNumber; -use miden_client::crypto::RpoRandomCoin; +use miden_client::crypto::RandomCoin; use miden_client::note::{Note as NativeNote, NoteAssets as NativeNoteAssets, P2idNote}; use miden_client::{Felt as NativeFelt, Word as NativeWord}; use miden_standards::note::{P2ideNote, P2ideNoteStorage}; @@ -102,7 +102,7 @@ impl Note { ) -> Result { let mut rng = StdRng::from_os_rng(); let coin_seed: [u64; 4] = rng.random(); - let mut rng = RpoRandomCoin::new(coin_seed.map(NativeFelt::new).into()); + let mut rng = RandomCoin::new(coin_seed.map(NativeFelt::new).into()); let native_note_assets: NativeNoteAssets = assets.into(); let native_assets: Vec = native_note_assets.iter().copied().collect(); @@ -133,7 +133,7 @@ impl Note { ) -> Result { let mut rng = StdRng::from_os_rng(); let coin_seed: [u64; 4] = rng.random(); - let mut rng = RpoRandomCoin::new(coin_seed.map(NativeFelt::new).into()); + let mut rng = RandomCoin::new(coin_seed.map(NativeFelt::new).into()); let native_note_assets: NativeNoteAssets = assets.into(); let native_assets: Vec = native_note_assets.iter().copied().collect(); @@ -184,3 +184,15 @@ impl From<&Note> for NativeNote { note.0.clone() } } + +impl From for Vec { + fn from(note_array: crate::models::miden_arrays::NoteArray) -> Self { + note_array.__inner.into_iter().map(Into::into).collect() + } +} + +impl From<&crate::models::miden_arrays::NoteArray> for Vec { + fn from(note_array: &crate::models::miden_arrays::NoteArray) -> Self { + note_array.__inner.iter().cloned().map(Into::into).collect() + } +} diff --git a/crates/web-client/src/models/note_assets.rs b/crates/web-client/src/models/note_assets.rs index bbdc295000..fd5a7c443d 100644 --- a/crates/web-client/src/models/note_assets.rs +++ b/crates/web-client/src/models/note_assets.rs @@ -28,7 +28,9 @@ impl NoteAssets { /// Adds a fungible asset to the collection. pub fn push(&mut self, asset: &FungibleAsset) { - self.0.add_asset(asset.into()).unwrap(); + let mut assets: Vec = self.0.iter().copied().collect(); + assets.push(asset.into()); + self.0 = NativeNoteAssets::new(assets).unwrap(); } /// Returns all fungible assets contained in the note. diff --git a/crates/web-client/src/models/note_file.rs b/crates/web-client/src/models/note_file.rs index cbd3037128..689e1dd7bb 100644 --- a/crates/web-client/src/models/note_file.rs +++ b/crates/web-client/src/models/note_file.rs @@ -5,7 +5,7 @@ use wasm_bindgen::prelude::*; use super::input_note::InputNote; use super::note::Note; -use super::output_note::OutputNote; +use super::raw_output_note::RawOutputNote; use crate::js_error_with_context; use crate::models::note_details::NoteDetails; use crate::models::note_id::NoteId; @@ -125,16 +125,17 @@ impl NoteFile { } } - /// Creates a `NoteFile` from an output note, choosing details when present. - #[wasm_bindgen(js_name = fromOutputNote)] - pub fn from_output_note(note: &OutputNote) -> Self { + /// Creates a `NoteFile` from a raw output note, choosing details when present. + #[wasm_bindgen(js_name = fromRawOutputNote)] + pub fn from_raw_output_note(note: &RawOutputNote) -> Self { let native_note = note.note(); - match (native_note.assets(), native_note.recipient()) { - (Some(assets), Some(recipient)) => { + match native_note.recipient() { + Some(recipient) => { + let assets = native_note.assets(); let details = NativeNoteDetails::new(assets.clone(), recipient.clone()); Self { inner: details.into() } }, - _ => Self { inner: native_note.id().into() }, + None => Self { inner: native_note.id().into() }, } } diff --git a/crates/web-client/src/models/note_header.rs b/crates/web-client/src/models/note_header.rs index 53ec920a62..eb4eefd9bf 100644 --- a/crates/web-client/src/models/note_header.rs +++ b/crates/web-client/src/models/note_header.rs @@ -27,8 +27,9 @@ impl NoteHeader { } /// Returns a commitment to the note ID and metadata. - pub fn commitment(&self) -> Word { - self.0.commitment().into() + #[wasm_bindgen(js_name = "toCommitment")] + pub fn to_commitment(&self) -> Word { + self.0.to_commitment().into() } } diff --git a/crates/web-client/src/models/note_location.rs b/crates/web-client/src/models/note_location.rs index 0fd992afe7..3b8114fe5d 100644 --- a/crates/web-client/src/models/note_location.rs +++ b/crates/web-client/src/models/note_location.rs @@ -15,9 +15,9 @@ impl NoteLocation { } /// Returns the index of the note leaf within the block's note tree. - #[wasm_bindgen(js_name = "nodeIndexInBlock")] - pub fn node_index_in_block(&self) -> u16 { - self.0.node_index_in_block() + #[wasm_bindgen(js_name = "blockNoteTreeIndex")] + pub fn block_note_tree_index(&self) -> u16 { + self.0.block_note_tree_index() } } diff --git a/crates/web-client/src/models/output_note.rs b/crates/web-client/src/models/output_note.rs deleted file mode 100644 index a5cbc86d9c..0000000000 --- a/crates/web-client/src/models/output_note.rs +++ /dev/null @@ -1,124 +0,0 @@ -use miden_client::note::{ - Note as NativeNote, - NoteHeader as NativeNoteHeader, - PartialNote as NativePartialNote, -}; -use miden_client::transaction::OutputNote as NativeOutputNote; -use wasm_bindgen::prelude::*; - -use super::note::Note; -use super::note_assets::NoteAssets; -use super::note_header::NoteHeader; -use super::note_id::NoteId; -use super::note_metadata::NoteMetadata; -use super::partial_note::PartialNote; -use super::word::Word; -use crate::models::miden_arrays::OutputNoteArray; - -/// Representation of a note produced by a transaction (full, partial, or header-only). -#[derive(Clone)] -#[wasm_bindgen] -pub struct OutputNote(NativeOutputNote); - -#[wasm_bindgen] -impl OutputNote { - /// Wraps a full note output. - pub fn full(note: &Note) -> OutputNote { - let native_note: NativeNote = note.into(); - OutputNote(NativeOutputNote::Full(native_note)) - } - - /// Wraps a partial note containing assets and recipient only. - pub fn partial(partial_note: &PartialNote) -> OutputNote { - let native_partial_note: NativePartialNote = partial_note.into(); - OutputNote(NativeOutputNote::Partial(native_partial_note)) - } - - /// Wraps only the header of a note. - pub fn header(note_header: &NoteHeader) -> OutputNote { - let native_note_header: NativeNoteHeader = note_header.into(); - OutputNote(NativeOutputNote::Header(native_note_header)) - } - - /// Returns the assets if they are present. - pub fn assets(&self) -> Option { - self.0.assets().map(Into::into) - } - - /// Returns the note ID for this output. - pub fn id(&self) -> NoteId { - self.0.id().into() - } - - /// Returns the recipient digest if the recipient is known. - #[wasm_bindgen(js_name = "recipientDigest")] - pub fn recipient_digest(&self) -> Option { - self.0.recipient_digest().map(Into::into) - } - - /// Returns the metadata that accompanies this output. - pub fn metadata(&self) -> NoteMetadata { - self.0.metadata().into() - } - - /// Returns a more compact representation if possible (e.g. dropping details). - #[must_use] - pub fn shrink(&self) -> OutputNote { - self.0.shrink().into() - } - - /// Converts into a full note if the data is present. - #[wasm_bindgen(js_name = "intoFull")] - pub fn into_full(self) -> Option { - match self.0 { - NativeOutputNote::Full(note) => Some(note.into()), - _ => None, - } - } - - pub(crate) fn note(&self) -> &NativeOutputNote { - &self.0 - } -} - -// CONVERSIONS -// ================================================================================================ - -impl From for OutputNote { - fn from(native_output_note: NativeOutputNote) -> Self { - OutputNote(native_output_note) - } -} - -impl From<&NativeOutputNote> for OutputNote { - fn from(native_output_note: &NativeOutputNote) -> Self { - OutputNote(native_output_note.clone()) - } -} - -impl From for NativeOutputNote { - fn from(output_note: OutputNote) -> Self { - output_note.0 - } -} - -impl From<&OutputNote> for NativeOutputNote { - fn from(output_note: &OutputNote) -> Self { - output_note.0.clone() - } -} - -// CONVERSIONS -// ================================================================================================ - -impl From for Vec { - fn from(output_notes_array: OutputNoteArray) -> Self { - output_notes_array.__inner.into_iter().map(Into::into).collect() - } -} - -impl From<&OutputNoteArray> for Vec { - fn from(output_notes_array: &OutputNoteArray) -> Self { - output_notes_array.__inner.iter().map(Into::into).collect() - } -} diff --git a/crates/web-client/src/models/proven_transaction.rs b/crates/web-client/src/models/proven_transaction.rs index eff42c7107..a5348ac32a 100644 --- a/crates/web-client/src/models/proven_transaction.rs +++ b/crates/web-client/src/models/proven_transaction.rs @@ -4,7 +4,6 @@ use wasm_bindgen::prelude::*; use wasm_bindgen_futures::js_sys::Uint8Array; use crate::models::account_id::AccountId; -use crate::models::output_notes::OutputNotes; use crate::models::transaction_id::TransactionId; use crate::models::word::Word; use crate::utils::{deserialize_from_uint8array, serialize_to_uint8array}; @@ -51,11 +50,8 @@ impl ProvenTransaction { self.0.expiration_block_num().as_u32() } - /// Returns notes created by this transaction. - #[wasm_bindgen(js_name = "outputNotes")] - pub fn output_notes(&self) -> OutputNotes { - self.0.output_notes().into() - } + // Note: proven output notes are not exposed in the web client yet. + // The web client only exposes raw executed output notes via RawOutputNote/RawOutputNotes. /// Returns the commitment of the reference block. #[wasm_bindgen(js_name = "refBlockCommitment")] diff --git a/crates/web-client/src/models/public_key.rs b/crates/web-client/src/models/public_key.rs index d0d39aee85..51219fddba 100644 --- a/crates/web-client/src/models/public_key.rs +++ b/crates/web-client/src/models/public_key.rs @@ -47,12 +47,12 @@ impl PublicKey { let native_signature: NativeSignature = signature.into(); match native_signature { - NativeSignature::Falcon512Rpo(falcon_signature) => { + NativeSignature::Falcon512Poseidon2(falcon_signature) => { let public_key = miden_client::crypto::rpo_falcon512::PublicKey::recover_from( native_message, &falcon_signature, ); - Ok(NativePublicKey::Falcon512Rpo(public_key).into()) + Ok(NativePublicKey::Falcon512Poseidon2(public_key).into()) }, NativeSignature::EcdsaK256Keccak(_) => Err(JsValue::from_str( "Recovering a public key from an EcdsaK256Keccak signature is not supported yet", diff --git a/crates/web-client/src/models/raw_output_note.rs b/crates/web-client/src/models/raw_output_note.rs new file mode 100644 index 0000000000..c31991e3aa --- /dev/null +++ b/crates/web-client/src/models/raw_output_note.rs @@ -0,0 +1,100 @@ +use miden_client::note::Note as NativeNote; +use miden_client::transaction::RawOutputNote as NativeRawOutputNote; +use wasm_bindgen::prelude::*; + +use super::note::Note; +use super::note_assets::NoteAssets; +use super::note_id::NoteId; +use super::note_metadata::NoteMetadata; +use super::word::Word; +use crate::models::miden_arrays::RawOutputNoteArray; + +/// Representation of a note produced by a transaction (full or partial). +#[derive(Clone)] +#[wasm_bindgen] +pub struct RawOutputNote(NativeRawOutputNote); + +#[wasm_bindgen] +impl RawOutputNote { + /// Wraps a full note output. + pub fn full(note: &Note) -> RawOutputNote { + let native_note: NativeNote = note.into(); + RawOutputNote(NativeRawOutputNote::Full(native_note)) + } + + /// Returns the assets if they are present. + pub fn assets(&self) -> Option { + Some(self.0.assets().into()) + } + + /// Returns the note ID for this output. + pub fn id(&self) -> NoteId { + self.0.id().into() + } + + /// Returns the recipient digest. + #[wasm_bindgen(js_name = "recipientDigest")] + pub fn recipient_digest(&self) -> Word { + self.0.recipient_digest().into() + } + + /// Returns the metadata that accompanies this output. + pub fn metadata(&self) -> NoteMetadata { + self.0.metadata().into() + } + + /// Converts into a full note if the data is present. + #[wasm_bindgen(js_name = "intoFull")] + pub fn into_full(self) -> Option { + match self.0 { + NativeRawOutputNote::Full(note) => Some(note.into()), + NativeRawOutputNote::Partial(_) => None, + } + } + + pub(crate) fn note(&self) -> &NativeRawOutputNote { + &self.0 + } +} + +// CONVERSIONS +// ================================================================================================ + +impl From for RawOutputNote { + fn from(raw_output_note: NativeRawOutputNote) -> Self { + RawOutputNote(raw_output_note) + } +} + +impl From<&NativeRawOutputNote> for RawOutputNote { + fn from(raw_output_note: &NativeRawOutputNote) -> Self { + RawOutputNote(raw_output_note.clone()) + } +} + +impl From for NativeRawOutputNote { + fn from(output_note: RawOutputNote) -> Self { + output_note.0 + } +} + +impl From<&RawOutputNote> for NativeRawOutputNote { + fn from(output_note: &RawOutputNote) -> Self { + output_note.0.clone() + } +} + +// CONVERSIONS +// ================================================================================================ + +impl From for Vec { + fn from(output_notes_array: RawOutputNoteArray) -> Self { + output_notes_array.__inner.into_iter().map(Into::into).collect() + } +} + +impl From<&RawOutputNoteArray> for Vec { + fn from(output_notes_array: &RawOutputNoteArray) -> Self { + output_notes_array.__inner.iter().cloned().map(Into::into).collect() + } +} diff --git a/crates/web-client/src/models/output_notes.rs b/crates/web-client/src/models/raw_output_notes.rs similarity index 65% rename from crates/web-client/src/models/output_notes.rs rename to crates/web-client/src/models/raw_output_notes.rs index 262082e1bf..80e7fb1e62 100644 --- a/crates/web-client/src/models/output_notes.rs +++ b/crates/web-client/src/models/raw_output_notes.rs @@ -1,17 +1,17 @@ -use miden_client::transaction::OutputNotes as NativeOutputNotes; +use miden_client::transaction::RawOutputNotes as NativeRawOutputNotes; use wasm_bindgen::prelude::*; -use super::output_note::OutputNote; +use super::raw_output_note::RawOutputNote; use super::word::Word; /// Contains a list of output notes of a transaction. The list can be empty if the transaction does /// not produce any notes. #[derive(Clone)] #[wasm_bindgen] -pub struct OutputNotes(pub(crate) NativeOutputNotes); +pub struct RawOutputNotes(pub(crate) NativeRawOutputNotes); #[wasm_bindgen] -impl OutputNotes { +impl RawOutputNotes { /// Returns the commitment to all output notes. pub fn commitment(&self) -> Word { self.0.commitment().into() @@ -32,12 +32,12 @@ impl OutputNotes { /// Returns the output note at the specified index. #[wasm_bindgen(js_name = "getNote")] - pub fn get_note(&self, index: u32) -> OutputNote { + pub fn get_note(&self, index: u32) -> RawOutputNote { self.0.get_note(index as usize).into() } /// Returns all output notes as a vector. - pub fn notes(&self) -> Vec { + pub fn notes(&self) -> Vec { self.0.iter().cloned().map(Into::into).collect() } } @@ -45,14 +45,14 @@ impl OutputNotes { // CONVERSIONS // ================================================================================================ -impl From for OutputNotes { - fn from(native_notes: NativeOutputNotes) -> Self { - OutputNotes(native_notes) +impl From for RawOutputNotes { + fn from(native_notes: NativeRawOutputNotes) -> Self { + RawOutputNotes(native_notes) } } -impl From<&NativeOutputNotes> for OutputNotes { - fn from(native_notes: &NativeOutputNotes) -> Self { - OutputNotes(native_notes.clone()) +impl From<&NativeRawOutputNotes> for RawOutputNotes { + fn from(native_notes: &NativeRawOutputNotes) -> Self { + RawOutputNotes(native_notes.clone()) } } diff --git a/crates/web-client/src/models/token_symbol.rs b/crates/web-client/src/models/token_symbol.rs index da4f0391c8..93e3540ad6 100644 --- a/crates/web-client/src/models/token_symbol.rs +++ b/crates/web-client/src/models/token_symbol.rs @@ -23,10 +23,8 @@ impl TokenSymbol { /// Returns the validated symbol string. #[wasm_bindgen(js_name = "toString")] #[allow(clippy::inherent_to_string)] - pub fn to_string(&self) -> Result { - self.0 - .to_string() - .map_err(|err| js_error_with_context(err, "failed to convert token symbol to string")) + pub fn to_string(&self) -> String { + self.0.to_string() } } @@ -41,7 +39,7 @@ impl From for TokenSymbol { impl From<&NativeTokenSymbol> for TokenSymbol { fn from(native_token_symbol: &NativeTokenSymbol) -> Self { - TokenSymbol(*native_token_symbol) + TokenSymbol(native_token_symbol.clone()) } } @@ -53,6 +51,6 @@ impl From for NativeTokenSymbol { impl From<&TokenSymbol> for NativeTokenSymbol { fn from(token_symbol: &TokenSymbol) -> Self { - token_symbol.0 + token_symbol.0.clone() } } diff --git a/crates/web-client/src/models/transaction_record.rs b/crates/web-client/src/models/transaction_record.rs index 8af11a5ad1..85ded5f14b 100644 --- a/crates/web-client/src/models/transaction_record.rs +++ b/crates/web-client/src/models/transaction_record.rs @@ -2,7 +2,7 @@ use miden_client::transaction::TransactionRecord as NativeTransactionRecord; use wasm_bindgen::prelude::*; use super::account_id::AccountId; -use super::output_notes::OutputNotes; +use super::raw_output_notes::RawOutputNotes; use super::transaction_id::TransactionId; use super::transaction_status::TransactionStatus; use super::word::Word; @@ -43,9 +43,9 @@ impl TransactionRecord { self.0.details.input_note_nullifiers.iter().map(Into::into).collect() } - /// Returns the output notes created by this transaction. - #[wasm_bindgen(js_name = "outputNotes")] - pub fn output_notes(&self) -> OutputNotes { + /// Returns the raw output notes created by this transaction. + #[wasm_bindgen(js_name = "rawOutputNotes")] + pub fn raw_output_notes(&self) -> RawOutputNotes { self.0.details.output_notes.clone().into() } diff --git a/crates/web-client/src/models/transaction_request/transaction_request_builder.rs b/crates/web-client/src/models/transaction_request/transaction_request_builder.rs index db33c2653b..df22110baf 100644 --- a/crates/web-client/src/models/transaction_request/transaction_request_builder.rs +++ b/crates/web-client/src/models/transaction_request/transaction_request_builder.rs @@ -8,7 +8,6 @@ use miden_client::note::{ use miden_client::transaction::{ ForeignAccount as NativeForeignAccount, NoteArgs as NativeNoteArgs, - OutputNote as NativeOutputNote, TransactionRequestBuilder as NativeTransactionRequestBuilder, TransactionScript as NativeTransactionScript, }; @@ -19,9 +18,9 @@ use crate::models::advice_map::AdviceMap; use crate::models::miden_arrays::{ ForeignAccountArray, NoteAndArgsArray, + NoteArray, NoteDetailsAndTagArray, NoteRecipientArray, - OutputNoteArray, }; use crate::models::transaction_request::TransactionRequest; use crate::models::transaction_script::TransactionScript; @@ -52,11 +51,11 @@ impl TransactionRequestBuilder { self } - /// Adds notes created by the sender that should be emitted by the transaction. + /// Adds output notes created by the sender that should be emitted by the transaction. #[wasm_bindgen(js_name = "withOwnOutputNotes")] - pub fn with_own_output_notes(mut self, notes: &OutputNoteArray) -> Self { - let native_output_notes: Vec = notes.into(); - self.0 = self.0.own_output_notes(native_output_notes); + pub fn with_own_output_notes(mut self, notes: &NoteArray) -> Self { + let native_notes: Vec = notes.into(); + self.0 = self.0.own_output_notes(native_notes); self } diff --git a/crates/web-client/src/models/transaction_store_update.rs b/crates/web-client/src/models/transaction_store_update.rs index 37571ee3b7..e426402414 100644 --- a/crates/web-client/src/models/transaction_store_update.rs +++ b/crates/web-client/src/models/transaction_store_update.rs @@ -4,7 +4,7 @@ use wasm_bindgen_futures::js_sys::Uint8Array; use crate::models::account_delta::AccountDelta; use crate::models::executed_transaction::ExecutedTransaction; -use crate::models::output_notes::OutputNotes; +use crate::models::raw_output_notes::RawOutputNotes; use crate::models::transaction_request::note_details_and_tag::NoteDetailsAndTag; use crate::utils::{deserialize_from_uint8array, serialize_to_uint8array}; @@ -28,9 +28,9 @@ impl TransactionStoreUpdate { self.0.submission_height().as_u32() } - /// Returns the notes created by the transaction. - #[wasm_bindgen(js_name = "createdNotes")] - pub fn created_notes(&self) -> OutputNotes { + /// Returns the raw output notes created by the transaction. + #[wasm_bindgen(js_name = "createdRawOutputNotes")] + pub fn created_raw_output_notes(&self) -> RawOutputNotes { self.0.executed_transaction().output_notes().into() } diff --git a/crates/web-client/src/models/transaction_summary.rs b/crates/web-client/src/models/transaction_summary.rs index 7eb3fb0420..88017ec242 100644 --- a/crates/web-client/src/models/transaction_summary.rs +++ b/crates/web-client/src/models/transaction_summary.rs @@ -4,7 +4,7 @@ use wasm_bindgen_futures::js_sys::Uint8Array; use super::account_delta::AccountDelta; use super::input_notes::InputNotes; -use super::output_notes::OutputNotes; +use super::raw_output_notes::RawOutputNotes; use super::word::Word; use crate::utils::{deserialize_from_uint8array, serialize_to_uint8array}; @@ -37,9 +37,9 @@ impl TransactionSummary { Ok(self.0.input_notes().into()) } - /// Returns the output notes referenced by the summary. - #[wasm_bindgen(js_name = "outputNotes")] - pub fn output_notes(&self) -> Result { + /// Returns the raw output notes referenced by the summary. + #[wasm_bindgen(js_name = "rawOutputNotes")] + pub fn raw_output_notes(&self) -> Result { Ok(self.0.output_notes().into()) } diff --git a/crates/web-client/src/models/word.rs b/crates/web-client/src/models/word.rs index e784858332..fc824658da 100644 --- a/crates/web-client/src/models/word.rs +++ b/crates/web-client/src/models/word.rs @@ -74,7 +74,7 @@ impl Word { /// Returns the word as an array of u64 values. #[wasm_bindgen(js_name = "toU64s")] pub fn to_u64s(&self) -> Vec { - self.0.iter().map(NativeFelt::as_int).collect::>() + self.0.iter().map(NativeFelt::as_canonical_u64).collect::>() } /// Returns the word as an array of field elements. diff --git a/crates/web-client/src/new_account.rs b/crates/web-client/src/new_account.rs index 4d3d493181..42e9f62ecf 100644 --- a/crates/web-client/src/new_account.rs +++ b/crates/web-client/src/new_account.rs @@ -1,5 +1,5 @@ use miden_client::Felt; -use miden_client::account::component::BasicFungibleFaucet; +use miden_client::account::component::{AuthControlled, BasicFungibleFaucet}; use miden_client::account::{AccountBuilder, AccountComponent, AccountType}; use miden_client::asset::TokenSymbol; use miden_client::auth::{AuthSchemeId as NativeAuthScheme, AuthSecretKey, AuthSingleSig}; @@ -90,35 +90,24 @@ impl WebClient { let mut faucet_rng = StdRng::from_seed(seed); let native_scheme: NativeAuthScheme = auth_scheme.try_into()?; - let (key_pair, auth_component) = match native_scheme { - NativeAuthScheme::Falcon512Rpo => { - let key_pair = AuthSecretKey::new_falcon512_rpo_with_rng(&mut faucet_rng); - let auth_component: AccountComponent = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - NativeAuthScheme::Falcon512Rpo, - ) - .into(); - (key_pair, auth_component) + let key_pair = match native_scheme { + NativeAuthScheme::Falcon512Poseidon2 => { + AuthSecretKey::new_falcon512_poseidon2_with_rng(&mut faucet_rng) }, NativeAuthScheme::EcdsaK256Keccak => { - let key_pair = AuthSecretKey::new_ecdsa_k256_keccak_with_rng(&mut faucet_rng); - let auth_component: AccountComponent = AuthSingleSig::new( - key_pair.public_key().to_commitment(), - NativeAuthScheme::EcdsaK256Keccak, - ) - .into(); - (key_pair, auth_component) + AuthSecretKey::new_ecdsa_k256_keccak_with_rng(&mut faucet_rng) }, _ => { let message = format!("unsupported auth scheme: {native_scheme:?}"); return Err(JsValue::from_str(&message)); }, }; + let auth_component: AccountComponent = + AuthSingleSig::new(key_pair.public_key().to_commitment(), native_scheme).into(); let symbol = TokenSymbol::new(token_symbol).map_err(|e| JsValue::from_str(&e.to_string()))?; - let max_supply = Felt::try_from(max_supply.to_le_bytes().as_slice()) - .expect("u64 can be safely converted to a field element"); + let max_supply = Felt::new(max_supply); let mut init_seed = [0u8; 32]; faucet_rng.fill_bytes(&mut init_seed); @@ -131,6 +120,7 @@ impl WebClient { BasicFungibleFaucet::new(symbol, decimals, max_supply) .map_err(|err| js_error_with_context(err, "failed to create new faucet"))?, ) + .with_component(AuthControlled::allow_all()) .build() { Ok(result) => result, diff --git a/crates/web-client/src/web_keystore.rs b/crates/web-client/src/web_keystore.rs index dd05941cfc..154f8ec09b 100644 --- a/crates/web-client/src/web_keystore.rs +++ b/crates/web-client/src/web_keystore.rs @@ -140,8 +140,8 @@ impl TransactionAuthenticator for WebKeyStore { let mut rng = self.rng.write(); let signature = match secret_key { - Some(AuthSecretKey::Falcon512Rpo(k)) => { - Signature::Falcon512Rpo(k.sign_with_rng(message, &mut rng)) + Some(AuthSecretKey::Falcon512Poseidon2(k)) => { + Signature::Falcon512Poseidon2(k.sign_with_rng(message, &mut rng)) }, Some(AuthSecretKey::EcdsaK256Keccak(k)) => Signature::EcdsaK256Keccak(k.sign(message)), Some(other_k) => other_k.sign(message), diff --git a/crates/web-client/test/account.test.ts b/crates/web-client/test/account.test.ts index b77225c6b9..88596ad2be 100644 --- a/crates/web-client/test/account.test.ts +++ b/crates/web-client/test/account.test.ts @@ -162,7 +162,8 @@ test.describe("getAccounts tests", () => { }); test.describe("get public account with details", () => { - test("assets and storage with too many assets/entries are retrieved", async ({ + // FIXME: Skipped due to node returning internal error for this account's proof + test.fixme("assets and storage with too many assets/entries are retrieved", async ({ page, }) => { test.skip( diff --git a/crates/web-client/test/fpi.test.ts b/crates/web-client/test/fpi.test.ts index f6f6e01226..e5719ca0ea 100644 --- a/crates/web-client/test/fpi.test.ts +++ b/crates/web-client/test/fpi.test.ts @@ -96,8 +96,8 @@ export const testStandardFpi = async (page: Page): Promise => { procref.::miden::testing::fpi_component::get_fpi_map_item # push the foreign account id - push.{account_id_suffix} push.{account_id_prefix} - # => [foreign_id_prefix, foreign_id_suffix, FOREIGN_PROC_ROOT, storage_item_index] + push.{account_id_prefix} push.{account_id_suffix} + # => [foreign_id_suffix, foreign_id_prefix, FOREIGN_PROC_ROOT, storage_item_index] exec.tx::execute_foreign_procedure push.9.12.18.30 assert_eqw diff --git a/crates/web-client/test/global.test.d.ts b/crates/web-client/test/global.test.d.ts index 11220632f2..b9cdc80a6b 100644 --- a/crates/web-client/test/global.test.d.ts +++ b/crates/web-client/test/global.test.d.ts @@ -43,11 +43,10 @@ import { NoteRecipient, NoteTag, NoteType, - OutputNote, - OutputNotesArray, Package, ProcedureThreshold, PublicKey, + RawOutputNote, Rpo256, RpcClient, Signature, @@ -138,11 +137,10 @@ declare global { NoteScript: typeof NoteScript; NoteTag: typeof NoteTag; NoteType: typeof NoteType; - OutputNote: typeof OutputNote; - OutputNotesArray: typeof OutputNotesArray; Package: typeof Package; ProcedureThreshold: typeof ProcedureThreshold; PublicKey: typeof PublicKey; + RawOutputNote: typeof RawOutputNote; Rpo256: typeof Rpo256; Signature: typeof Signature; SigningInputs: typeof SigningInputs; diff --git a/crates/web-client/test/import_export.test.ts b/crates/web-client/test/import_export.test.ts index 9408ad7f4c..2fcb3ce9b1 100644 --- a/crates/web-client/test/import_export.test.ts +++ b/crates/web-client/test/import_export.test.ts @@ -262,8 +262,8 @@ test.describe("export and import note", () => { window.NoteType.Public, new window.NoteAttachment() ); - return window.NoteFile.fromOutputNote( - window.OutputNote.full(p2IdNote) + return window.NoteFile.fromRawOutputNote( + window.RawOutputNote.full(p2IdNote) ).noteType(); }, { noteId } diff --git a/crates/web-client/test/miden_client_api.test.ts b/crates/web-client/test/miden_client_api.test.ts index afeee77a8c..41d77795b7 100644 --- a/crates/web-client/test/miden_client_api.test.ts +++ b/crates/web-client/test/miden_client_api.test.ts @@ -36,7 +36,7 @@ test.describe("MidenClient API - Mock Chain", () => { ids: [mintTxId.toHex()], }); const mintedNoteId = txRecords[0] - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString(); @@ -773,15 +773,15 @@ test.describe("MidenClient API - Mock Chain", () => { return { hasSummary: summary != null, - hasOutputNotes: typeof summary.outputNotes === "function", - outputNotesCount: summary.outputNotes().numNotes(), + hasRawOutputNotes: typeof summary.rawOutputNotes === "function", + rawOutputNotesCount: summary.rawOutputNotes().numNotes(), hasAccountDelta: typeof summary.accountDelta === "function", }; }); expect(result.hasSummary).toBe(true); - expect(result.hasOutputNotes).toBe(true); - expect(result.outputNotesCount).toBeGreaterThan(0); + expect(result.hasRawOutputNotes).toBe(true); + expect(result.rawOutputNotesCount).toBeGreaterThan(0); expect(result.hasAccountDelta).toBe(true); }); diff --git a/crates/web-client/test/mockchain.test.ts b/crates/web-client/test/mockchain.test.ts index f1b4786c8d..ecde94171e 100644 --- a/crates/web-client/test/mockchain.test.ts +++ b/crates/web-client/test/mockchain.test.ts @@ -43,7 +43,7 @@ const mockChainTest = async (testingPage: Page) => { } const mintedNoteId = mintTransactionRecord - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString(); diff --git a/crates/web-client/test/new_transactions.test.ts b/crates/web-client/test/new_transactions.test.ts index f663d614ed..9ff713ac70 100644 --- a/crates/web-client/test/new_transactions.test.ts +++ b/crates/web-client/test/new_transactions.test.ts @@ -77,7 +77,7 @@ const multipleMintsTest = async ( result.createdNoteIds.push( mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString() @@ -87,7 +87,7 @@ const multipleMintsTest = async ( ); result.numOutputNotesCreated += mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .numNotes(); } @@ -447,11 +447,8 @@ export const customTransaction = async ( // Creating First Custom Transaction Request to Mint the Custom Note - const outputNote = window.OutputNote.full(note); let transactionRequest = new window.TransactionRequestBuilder() - .withOwnOutputNotes( - new window.MidenArrays.OutputNoteArray([outputNote]) - ) + .withOwnOutputNotes(new window.MidenArrays.NoteArray([note])) .build(); // Execute and Submit Transaction @@ -578,15 +575,8 @@ const customTxWithMultipleNotes = async ( let note1 = new window.Note(noteAssets1, noteMetadata, noteRecipient1); let note2 = new window.Note(noteAssets2, noteMetadata, noteRecipient2); - const notes = [ - window.OutputNote.full(note1), - window.OutputNote.full(note2), - ]; - - const outputNotes = new window.MidenArrays.OutputNoteArray(notes); - let transactionRequest = new window.TransactionRequestBuilder() - .withOwnOutputNotes(outputNotes) + .withOwnOutputNotes(new window.MidenArrays.NoteArray([note1, note2])) .build(); let transactionUpdate = await window.helpers.executeAndApplyTransaction( @@ -622,18 +612,16 @@ const submitExpiredTransaction = async ( const noteAssets = new window.NoteAssets([ new window.FungibleAsset(faucetAccountId, BigInt(10)), ]); - const outputNote = window.OutputNote.full( - window.Note.createP2IDNote( - senderAccountId, - targetAccountId, - noteAssets, - window.NoteType.Public, - new window.Felt(0n) - ) + const note = window.Note.createP2IDNote( + senderAccountId, + targetAccountId, + noteAssets, + window.NoteType.Public, + new window.Felt(0n) ); const transactionRequest = new window.TransactionRequestBuilder() - .withOwnOutputNotes(new window.OutputNotesArray([outputNote])) + .withOwnOutputNotes(new window.MidenArrays.NoteArray([note])) .withExpirationDelta(2) .build(); @@ -970,7 +958,7 @@ export const discardedTransaction = async ( ); let createdNotes = mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes(); let createdNoteIds = createdNotes.map((note: Note) => note.id().toString()); await window.helpers.waitForTransaction( @@ -1014,7 +1002,7 @@ export const discardedTransaction = async ( ); let sendCreatedNotes = sendTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes(); let sendCreatedNoteIds = sendCreatedNotes.map((note: Note) => note.id().toString() @@ -1268,9 +1256,7 @@ export const counterAccountComponent = async ( let note = new window.Note(noteAssets, noteMetadata, noteRecipient); let transactionRequest = new window.TransactionRequestBuilder() - .withOwnOutputNotes( - new window.MidenArrays.OutputNoteArray([window.OutputNote.full(note)]) - ) + .withOwnOutputNotes(new window.MidenArrays.NoteArray([note])) .build(); let transactionUpdate = await window.helpers.executeAndApplyTransaction( @@ -1598,7 +1584,7 @@ test.describe("submitNewTransactionWithProver tests", () => { const createdNoteIds = mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes() .map((note: Note) => note.id().toString()); @@ -1648,7 +1634,7 @@ test.describe("submitNewTransactionWithProver tests", () => { const sentNoteIds = sendTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes() .map((note: Note) => note.id().toString()); @@ -1677,7 +1663,7 @@ test.describe("submitNewTransactionWithProver tests", () => { return { inputNotesCount: summary.inputNotes().numNotes(), - outputNotesCount: summary.outputNotes().numNotes(), + rawOutputNotesCount: summary.rawOutputNotes().numNotes(), inputNoteIds: summary .inputNotes() .notes() @@ -1687,7 +1673,7 @@ test.describe("submitNewTransactionWithProver tests", () => { }); expect(result.inputNotesCount).toBe(1); - expect(result.outputNotesCount).toBe(0); + expect(result.rawOutputNotesCount).toBe(0); expect(result.inputNoteIds).toEqual(result.sentNoteIds); }); @@ -1722,14 +1708,14 @@ test.describe("submitNewTransactionWithProver tests", () => { return { inputNotesCount: summary.inputNotes().numNotes(), - outputNotesCount: summary.outputNotes().numNotes(), + rawOutputNotesCount: summary.rawOutputNotes().numNotes(), saltHex: summary.salt().toHex(), expectedSaltHex: expectedSalt.toHex(), }; }); expect(result.inputNotesCount).toBe(0); - expect(result.outputNotesCount).toBe(0); + expect(result.rawOutputNotesCount).toBe(0); expect(result.saltHex).toBe(result.expectedSaltHex); }); }); diff --git a/crates/web-client/test/notes.test.ts b/crates/web-client/test/notes.test.ts index 4be24184a6..372a1cf18c 100644 --- a/crates/web-client/test/notes.test.ts +++ b/crates/web-client/test/notes.test.ts @@ -295,12 +295,8 @@ test.describe("createP2IDNote and createP2IDENote", () => { new window.NoteAttachment() ); - let outputNote = window.OutputNote.full(p2IdNote); - let transactionRequest = new window.TransactionRequestBuilder() - .withOwnOutputNotes( - new window.MidenArrays.OutputNoteArray([outputNote]) - ) + .withOwnOutputNotes(new window.MidenArrays.NoteArray([p2IdNote])) .build(); let transactionUpdate = await window.helpers.executeAndApplyTransaction( @@ -314,7 +310,7 @@ test.describe("createP2IDNote and createP2IDENote", () => { let createdNoteId = transactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString(); @@ -404,12 +400,8 @@ test.describe("createP2IDNote and createP2IDENote", () => { new window.NoteAttachment() ); - let outputNote = window.OutputNote.full(p2IdeNote); - let transactionRequest = new window.TransactionRequestBuilder() - .withOwnOutputNotes( - new window.MidenArrays.OutputNoteArray([outputNote]) - ) + .withOwnOutputNotes(new window.MidenArrays.NoteArray([p2IdeNote])) .build(); let transactionUpdate = await window.helpers.executeAndApplyTransaction( @@ -423,7 +415,7 @@ test.describe("createP2IDNote and createP2IDENote", () => { let createdNoteId = transactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString(); diff --git a/crates/web-client/test/playwright.global.setup.ts b/crates/web-client/test/playwright.global.setup.ts index 415d036dcb..1c245cddeb 100644 --- a/crates/web-client/test/playwright.global.setup.ts +++ b/crates/web-client/test/playwright.global.setup.ts @@ -11,6 +11,7 @@ function generateStoreName(testInfo: TestInfo): string { const TEST_SERVER_PORT = 8080; const MIDEN_NODE_PORT = 57291; const REMOTE_TX_PROVER_PORT = 50051; +const REMOTE_PROVER_TIMEOUT_MS = 120_000; // Check if running against localhost (vs devnet/testnet) export function isLocalhost(): boolean { @@ -83,7 +84,7 @@ export const test = base.extend<{ forEachTest: void }>({ await page.goto("http://localhost:8080"); await page.evaluate( - async ({ rpcUrl, proverUrl, storeName }) => { + async ({ rpcUrl, proverUrl, storeName, remoteProverTimeoutMs }) => { // Import the sdk classes and attach them // to the window object for testing const sdkExports = await import("./index.js"); @@ -114,7 +115,7 @@ export const test = base.extend<{ forEachTest: void }>({ window.remoteProverInstance = window.TransactionProver.newRemoteProver( window.remoteProverUrl, - BigInt(20_000) + BigInt(remoteProverTimeoutMs) ); } @@ -150,26 +151,49 @@ export const test = base.extend<{ forEachTest: void }>({ prover ) => { const client = window.client; + + const t0 = performance.now(); const result = await client.executeTransaction( accountId, transactionRequest ); + const t1 = performance.now(); + console.debug( + `[timing] executeTransaction: ${(t1 - t0).toFixed(0)}ms` + ); - const useRemoteProver = - prover != null && window.remoteProverUrl != null; - const proverToUse = useRemoteProver - ? window.TransactionProver.newRemoteProver( - window.remoteProverUrl, - null - ) - : window.TransactionProver.newLocalProver(); + const proverToUse = + prover ?? window.TransactionProver.newLocalProver(); + const t2 = performance.now(); const proven = await client.proveTransaction(result, proverToUse); + const t3 = performance.now(); + console.debug( + `[timing] proveTransaction: ${(t3 - t2).toFixed(0)}ms` + ); + + const t4 = performance.now(); const submissionHeight = await client.submitProvenTransaction( proven, result ); - return await client.applyTransaction(result, submissionHeight); + const t5 = performance.now(); + console.debug( + `[timing] submitProvenTransaction: ${(t5 - t4).toFixed(0)}ms` + ); + + const t6 = performance.now(); + const txUpdate = await client.applyTransaction( + result, + submissionHeight + ); + const t7 = performance.now(); + console.debug( + `[timing] applyTransaction: ${(t7 - t6).toFixed(0)}ms` + ); + console.debug(`[timing] total: ${(t7 - t0).toFixed(0)}ms`); + + return txUpdate; }; window.helpers.waitForBlocks = async (amountOfBlocks) => { @@ -225,6 +249,7 @@ export const test = base.extend<{ forEachTest: void }>({ rpcUrl: getRpcUrl(), proverUrl: getProverUrl() ?? null, storeName, + remoteProverTimeoutMs: REMOTE_PROVER_TIMEOUT_MS, } ); await use(); diff --git a/crates/web-client/test/webClientTestUtils.ts b/crates/web-client/test/webClientTestUtils.ts index 88ce86c650..8f749b4b4d 100644 --- a/crates/web-client/test/webClientTestUtils.ts +++ b/crates/web-client/test/webClientTestUtils.ts @@ -72,10 +72,12 @@ export const mintTransaction = async ( return { transactionId: mintTransactionResult.executedTransaction().id().toHex(), - numOutputNotesCreated: mintTransactionResult.createdNotes().numNotes(), + numOutputNotesCreated: mintTransactionResult + .createdRawOutputNotes() + .numNotes(), nonce: mintTransactionResult.accountDelta().nonceDelta().toString(), createdNoteId: mintTransactionResult - .createdNotes() + .createdRawOutputNotes() .notes()[0] .id() .toString(), @@ -143,7 +145,7 @@ export const mintPublicTransaction = async ( transactionId: mintTransactionUpdate.executedTransaction().id().toHex(), numOutputNotesCreated: mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .numNotes(), nonce: mintTransactionUpdate .executedTransaction() @@ -152,7 +154,7 @@ export const mintPublicTransaction = async ( .toString(), createdNoteId: mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString(), @@ -226,7 +228,7 @@ export const sendTransaction = async ( let createdNote = mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .intoFull(); @@ -265,7 +267,7 @@ export const sendTransaction = async ( ); let sendCreatedNotes = sendTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes(); let sendCreatedNoteIds = sendCreatedNotes.map((note) => note.id().toString() @@ -791,7 +793,7 @@ export const mintAndConsumeTransaction = async ( let createdNote = mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .intoFull(); @@ -829,7 +831,7 @@ export const mintAndConsumeTransaction = async ( .toHex(), numOutputNotesCreated: mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .numNotes(), nonce: mintTransactionUpdate .executedTransaction() @@ -838,7 +840,7 @@ export const mintAndConsumeTransaction = async ( .toString(), createdNoteId: mintTransactionUpdate .executedTransaction() - .outputNotes() + .rawOutputNotes() .notes()[0] .id() .toString(), diff --git a/crates/web-client/yarn.lock b/crates/web-client/yarn.lock index eb2bfd251c..510165c5f2 100644 --- a/crates/web-client/yarn.lock +++ b/crates/web-client/yarn.lock @@ -93,7 +93,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -173,131 +173,11 @@ estree-walker "^2.0.2" picomatch "^4.0.2" -"@rollup/rollup-android-arm-eabi@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz#a6742c74c7d9d6d604ef8a48f99326b4ecda3d82" - integrity sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg== - -"@rollup/rollup-android-arm64@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz#97247be098de4df0c11971089fd2edf80a5da8cf" - integrity sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q== - "@rollup/rollup-darwin-arm64@4.59.0": version "4.59.0" resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz" integrity sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg== -"@rollup/rollup-darwin-x64@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz#36dfd7ed0aaf4d9d89d9ef983af72632455b0246" - integrity sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w== - -"@rollup/rollup-freebsd-arm64@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz#2f87c2074b4220260fdb52a9996246edfc633c22" - integrity sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA== - -"@rollup/rollup-freebsd-x64@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz#9b5a26522a38a95dc06616d1939d4d9a76937803" - integrity sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg== - -"@rollup/rollup-linux-arm-gnueabihf@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz#86aa4859385a8734235b5e40a48e52d770758c3a" - integrity sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw== - -"@rollup/rollup-linux-arm-musleabihf@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz#cbe70e56e6ece8dac83eb773b624fc9e5a460976" - integrity sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA== - -"@rollup/rollup-linux-arm64-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz#d14992a2e653bc3263d284bc6579b7a2890e1c45" - integrity sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA== - -"@rollup/rollup-linux-arm64-musl@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz#2fdd1ddc434ea90aeaa0851d2044789b4d07f6da" - integrity sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA== - -"@rollup/rollup-linux-loong64-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz#8a181e6f89f969f21666a743cd411416c80099e7" - integrity sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg== - -"@rollup/rollup-linux-loong64-musl@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz#904125af2babc395f8061daa27b5af1f4e3f2f78" - integrity sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q== - -"@rollup/rollup-linux-ppc64-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz#a57970ac6864c9a3447411a658224bdcf948be22" - integrity sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA== - -"@rollup/rollup-linux-ppc64-musl@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz#bb84de5b26870567a4267666e08891e80bb56a63" - integrity sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA== - -"@rollup/rollup-linux-riscv64-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz#72d00d2c7fb375ce3564e759db33f17a35bffab9" - integrity sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg== - -"@rollup/rollup-linux-riscv64-musl@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz#4c166ef58e718f9245bd31873384ba15a5c1a883" - integrity sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg== - -"@rollup/rollup-linux-s390x-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz#bb5025cde9a61db478c2ca7215808ad3bce73a09" - integrity sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w== - -"@rollup/rollup-linux-x64-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz#9b66b1f9cd95c6624c788f021c756269ffed1552" - integrity sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg== - -"@rollup/rollup-linux-x64-musl@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz#b007ca255dc7166017d57d7d2451963f0bd23fd9" - integrity sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg== - -"@rollup/rollup-openbsd-x64@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz#e8b357b2d1aa2c8d76a98f5f0d889eabe93f4ef9" - integrity sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ== - -"@rollup/rollup-openharmony-arm64@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz#96c2e3f4aacd3d921981329831ff8dde492204dc" - integrity sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA== - -"@rollup/rollup-win32-arm64-msvc@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz#2d865149d706d938df8b4b8f117e69a77646d581" - integrity sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A== - -"@rollup/rollup-win32-ia32-msvc@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz#abe1593be0fa92325e9971c8da429c5e05b92c36" - integrity sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA== - -"@rollup/rollup-win32-x64-gnu@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz#c4af3e9518c9a5cd4b1c163dc81d0ad4d82e7eab" - integrity sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA== - -"@rollup/rollup-win32-x64-msvc@4.59.0": - version "4.59.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz#4584a8a87b29188a4c1fe987a9fcf701e256d86c" - integrity sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA== - "@shikijs/engine-oniguruma@^3.13.0": version "3.13.0" resolved "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.13.0.tgz" @@ -320,7 +200,7 @@ dependencies: "@shikijs/types" "3.13.0" -"@shikijs/types@3.13.0", "@shikijs/types@^3.13.0": +"@shikijs/types@^3.13.0", "@shikijs/types@3.13.0": version "3.13.0" resolved "https://registry.npmjs.org/@shikijs/types/-/types-3.13.0.tgz" integrity sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw== @@ -358,7 +238,7 @@ resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== -"@types/estree@*", "@types/estree@1.0.8", "@types/estree@^1.0.0": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@1.0.8": version "1.0.8" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== @@ -527,9 +407,14 @@ b4a@^1.6.4, b4a@^1.6.6: resolved "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz" integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + balanced-match@^4.0.2: version "4.0.4" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz" integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== bare-events@^2.0.0, bare-events@^2.2.0: @@ -578,9 +463,9 @@ basic-auth@^2.0.1: dependencies: safe-buffer "5.1.2" -basic-ftp@>=5.2.0, basic-ftp@^5.0.2: +basic-ftp@^5.0.2: version "5.2.0" - resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.2.0.tgz#7c2dff63c918bde60e6bad1f2ff93dcf5137a40a" + resolved "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz" integrity sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw== binary-extensions@^2.0.0: @@ -588,10 +473,35 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== +binaryen@^121.0.0: + version "121.0.0" + resolved "https://registry.npmjs.org/binaryen/-/binaryen-121.0.0.tgz" + integrity sha512-St5LX+CmVdDQMf+DDHWdne7eDK+8tH9TE4Kc+Xk3s5+CzVYIKeJbWuXgsKVbkdLJXGUc2eflFqjThQy555mBag== + +brace-expansion@^1.1.7: + version "1.1.12" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + +brace-expansion@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + brace-expansion@^5.0.2: version "5.0.4" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.4.tgz#614daaecd0a688f660bbbc909a8748c3d80d4336" - integrity sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg== dependencies: balanced-match "^4.0.2" @@ -627,7 +537,7 @@ builtin-modules@^3.3.0: call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== dependencies: es-errors "^1.3.0" @@ -635,7 +545,7 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: call-bound@^1.0.2: version "1.0.4" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz" integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== dependencies: call-bind-apply-helpers "^1.0.2" @@ -750,16 +660,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + colorette@^1.1.0: version "1.4.0" resolved "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz" @@ -770,6 +680,11 @@ commondir@^1.0.1: resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + corser@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz" @@ -826,13 +741,6 @@ data-uri-to-buffer@^6.0.2: resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz" integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== -debug@4, debug@^4.1.1, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - debug@^3.2.7: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" @@ -840,6 +748,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.1.1, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@4: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" @@ -864,7 +779,7 @@ degenerator@^5.0.0: escodegen "^2.1.0" esprima "^4.0.1" -devtools-protocol@0.0.1330662: +devtools-protocol@*, devtools-protocol@0.0.1330662: version "0.0.1330662" resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1330662.tgz" integrity sha512-pzh6YQ8zZfz3iKlCvgzVCu22NdpZ8hNmwU6WnQjNVquh0A9iVosPtNLWDwaWVGyrntQlltPFztTMK5Cg6lfCuw== @@ -893,7 +808,7 @@ dir-glob@^3.0.1: dunder-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz" integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== dependencies: call-bind-apply-helpers "^1.0.1" @@ -941,7 +856,7 @@ error-ex@^1.3.1: es-define-property@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz" integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== es-errors@^1.3.0: @@ -951,7 +866,7 @@ es-errors@^1.3.0: es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz" integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== dependencies: es-errors "^1.3.0" @@ -1124,16 +1039,16 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - fsevents@~2.3.2: version "2.3.3" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +fsevents@2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -1151,7 +1066,7 @@ get-func-name@^2.0.1: get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== dependencies: call-bind-apply-helpers "^1.0.2" @@ -1167,7 +1082,7 @@ get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: get-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz" integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== dependencies: dunder-proto "^1.0.1" @@ -1221,7 +1136,18 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.3, glob@^8.1.0: +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +glob@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -1248,7 +1174,7 @@ globby@10.0.1: gopd@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0: @@ -1268,7 +1194,7 @@ has-flag@^4.0.0: has-symbols@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== hasown@^2.0.2: @@ -1587,7 +1513,7 @@ markdown-it@^14.1.0: math-intrinsics@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== mdurl@^2.0.0: @@ -1613,13 +1539,34 @@ mime@^1.6.0: resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -minimatch@>=10.2.1, minimatch@^10.0.0, minimatch@^3.1.1, minimatch@^5.0.1, minimatch@^5.1.6, minimatch@^9.0.5: +minimatch@^10.0.0: version "10.2.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.4.tgz#465b3accbd0218b8281f5301e27cedc697f96fde" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz" integrity sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg== dependencies: brace-expansion "^5.0.2" +minimatch@^3.1.1: + version "3.1.5" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz" + integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1, minimatch@^5.1.6: + version "5.1.9" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz" + integrity sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.5: + version "9.0.9" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz" + integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg== + dependencies: + brace-expansion "^2.0.2" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -1632,7 +1579,7 @@ minipass@^7.0.4, minipass@^7.1.2: minizlib@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-3.1.0.tgz#6ad76c3a8f10227c9b51d1c9ac8e30b27f5a251c" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz" integrity sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw== dependencies: minipass "^7.1.2" @@ -1706,7 +1653,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: object-inspect@^1.13.3: version "1.13.4" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== once@^1.3.0, once@^1.3.1, once@^1.4.0: @@ -1921,9 +1868,9 @@ puppeteer@^23.1.0: puppeteer-core "23.3.0" typed-query-selector "^2.12.0" -qs@>=6.14.1, qs@^6.4.0: +qs@^6.4.0: version "6.15.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.0.tgz#db8fd5d1b1d2d6b5b33adaf87429805f1909e7b3" + resolved "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz" integrity sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ== dependencies: side-channel "^1.1.0" @@ -2007,9 +1954,9 @@ rollup-plugin-copy@^3.5.0: globby "10.0.1" is-plain-object "^3.0.0" -rollup@>=4.59.0, rollup@^4.59.0: +rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^2.14.0||^3.0.0||^4.0.0, rollup@^2.68.0||^3.0.0||^4.0.0, rollup@^2.78.0||^3.0.0||^4.0.0, rollup@^4.59.0: version "4.59.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.59.0.tgz#cf74edac17c1486f562d728a4d923a694abdf06f" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz" integrity sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg== dependencies: "@types/estree" "1.0.8" @@ -2048,7 +1995,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@5.1.2, safe-buffer@^5.1.0: +safe-buffer@^5.1.0, safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -2089,7 +2036,7 @@ shebang-regex@^3.0.0: side-channel-list@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz" integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: es-errors "^1.3.0" @@ -2097,7 +2044,7 @@ side-channel-list@^1.0.0: side-channel-map@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + resolved "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz" integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== dependencies: call-bound "^1.0.2" @@ -2107,7 +2054,7 @@ side-channel-map@^1.0.1: side-channel-weakmap@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + resolved "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz" integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== dependencies: call-bound "^1.0.2" @@ -2118,7 +2065,7 @@ side-channel-weakmap@^1.0.2: side-channel@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz" integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== dependencies: es-errors "^1.3.0" @@ -2279,10 +2226,8 @@ tar-stream@^3.1.5: fast-fifo "^1.2.0" streamx "^2.15.0" -tar@>=7.5.8, tar@^7.4.3: +tar@^7.4.3: version "7.5.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.11.tgz#1250fae45d98806b36d703b30973fa8e0a6d8868" - integrity sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ== dependencies: "@isaacs/fs-minipass" "^4.0.0" chownr "^3.0.0" @@ -2328,7 +2273,7 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@^2.0.1: +tslib@*, tslib@^2.0.1: version "2.8.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -2343,7 +2288,7 @@ typedoc-plugin-markdown@^4.8.1: resolved "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.9.0.tgz" integrity sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw== -typedoc@^0.28.1: +typedoc@^0.28.1, typedoc@0.28.x: version "0.28.13" resolved "https://registry.npmjs.org/typedoc/-/typedoc-0.28.13.tgz" integrity sha512-dNWY8msnYB2a+7Audha+aTF1Pu3euiE7ySp53w8kEsXoYw7dMouV5A1UsTUY345aB152RHnmRMDiovuBi7BD+w== @@ -2354,7 +2299,7 @@ typedoc@^0.28.1: minimatch "^9.0.5" yaml "^2.8.1" -typescript@^5.5.4: +typescript@^5.5.4, typescript@>=2.7, typescript@>=3.7.0, typescript@>=4.9.5, "typescript@5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x": version "5.5.4" resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz" integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== diff --git a/docs/external/src/rust-client/cli/index.md b/docs/external/src/rust-client/cli/index.md index 850e264cd9..d9a0bbf037 100644 --- a/docs/external/src/rust-client/cli/index.md +++ b/docs/external/src/rust-client/cli/index.md @@ -402,7 +402,7 @@ The file referenced by `--inputs-path` should contain a TOML array of inline tab The input file should contain a TOML table called `inputs`, as in the following example: ```toml -inputs = [ { key = "0x0000001000000000000000000000000000000000000000000000000000000000", values = ["13", "9"]}, { key = "0x0000000000000000000000000000000000000000000000000000000000000000" , values = ["1", "2"]}, ] +inputs = [ { key = "0x0000000000000000000000000000000000000000000000000000001000000000", values = ["13", "9"]}, { key = "0x0000000000000000000000000000000000000000000000000000000000000000" , values = ["1", "2"]}, ] ``` ### `note-transport` diff --git a/docs/typedoc/web-client/README.md b/docs/typedoc/web-client/README.md index 87a7e66821..93eca62697 100644 --- a/docs/typedoc/web-client/README.md +++ b/docs/typedoc/web-client/README.md @@ -24,8 +24,8 @@ - [NoteFile](classes/NoteFile.md) - [NoteId](classes/NoteId.md) - [NoteTag](classes/NoteTag.md) -- [OutputNote](classes/OutputNote.md) - [OutputNoteRecord](classes/OutputNoteRecord.md) +- [RawOutputNote](classes/RawOutputNote.md) - [SyncSummary](classes/SyncSummary.md) - [TransactionId](classes/TransactionId.md) - [TransactionProver](classes/TransactionProver.md) diff --git a/docs/typedoc/web-client/classes/NoteFile.md b/docs/typedoc/web-client/classes/NoteFile.md index 6463736a37..2b1e02dce7 100644 --- a/docs/typedoc/web-client/classes/NoteFile.md +++ b/docs/typedoc/web-client/classes/NoteFile.md @@ -235,17 +235,17 @@ Creates a `NoteFile` from a note ID. *** -### fromOutputNote() +### fromRawOutputNote() -> `static` **fromOutputNote**(`note`): `NoteFile` +> `static` **fromRawOutputNote**(`note`): `NoteFile` -Creates a `NoteFile` from an output note, choosing details when present. +Creates a `NoteFile` from a raw output note, choosing details when present. #### Parameters ##### note -[`OutputNote`](OutputNote.md) +[`RawOutputNote`](RawOutputNote.md) #### Returns diff --git a/docs/typedoc/web-client/classes/OutputNote.md b/docs/typedoc/web-client/classes/RawOutputNote.md similarity index 53% rename from docs/typedoc/web-client/classes/OutputNote.md rename to docs/typedoc/web-client/classes/RawOutputNote.md index d0d078fe2f..30b77479f2 100644 --- a/docs/typedoc/web-client/classes/OutputNote.md +++ b/docs/typedoc/web-client/classes/RawOutputNote.md @@ -2,11 +2,11 @@ *** -[@miden-sdk/miden-sdk](../README.md) / OutputNote +[@miden-sdk/miden-sdk](../README.md) / RawOutputNote -# Class: OutputNote +# Class: RawOutputNote -Representation of a note produced by a transaction (full, partial, or header-only). +Representation of a note produced by a transaction (full or partial). ## Methods @@ -82,7 +82,7 @@ Returns the metadata that accompanies this output. > **recipientDigest**(): [`Word`](Word.md) -Returns the recipient digest if the recipient is known. +Returns the recipient digest. #### Returns @@ -90,21 +90,9 @@ Returns the recipient digest if the recipient is known. *** -### shrink() - -> **shrink**(): `OutputNote` - -Returns a more compact representation if possible (e.g. dropping details). - -#### Returns - -`OutputNote` - -*** - ### full() -> `static` **full**(`note`): `OutputNote` +> `static` **full**(`note`): `RawOutputNote` Wraps a full note output. @@ -116,40 +104,4 @@ Wraps a full note output. #### Returns -`OutputNote` - -*** - -### header() - -> `static` **header**(`note_header`): `OutputNote` - -Wraps only the header of a note. - -#### Parameters - -##### note\_header - -`NoteHeader` - -#### Returns - -`OutputNote` - -*** - -### partial() - -> `static` **partial**(`partial_note`): `OutputNote` - -Wraps a partial note containing assets and recipient only. - -#### Parameters - -##### partial\_note - -`PartialNote` - -#### Returns - -`OutputNote` +`RawOutputNote` diff --git a/docs/typedoc/web-client/classes/TransactionRecord.md b/docs/typedoc/web-client/classes/TransactionRecord.md index dd1d28f951..a3b5ed768f 100644 --- a/docs/typedoc/web-client/classes/TransactionRecord.md +++ b/docs/typedoc/web-client/classes/TransactionRecord.md @@ -126,15 +126,15 @@ Returns the nullifiers of the consumed input notes. *** -### outputNotes() +### rawOutputNotes() -> **outputNotes**(): `OutputNotes` +> **rawOutputNotes**(): `RawOutputNotes` -Returns the output notes created by this transaction. +Returns the raw output notes created by this transaction. #### Returns -`OutputNotes` +`RawOutputNotes` *** diff --git a/docs/typedoc/web-client/classes/TransactionSummary.md b/docs/typedoc/web-client/classes/TransactionSummary.md index 88afad03b9..5b9afd2554 100644 --- a/docs/typedoc/web-client/classes/TransactionSummary.md +++ b/docs/typedoc/web-client/classes/TransactionSummary.md @@ -54,15 +54,15 @@ Returns the input notes referenced by the summary. *** -### outputNotes() +### rawOutputNotes() -> **outputNotes**(): `OutputNotes` +> **rawOutputNotes**(): `RawOutputNotes` -Returns the output notes referenced by the summary. +Returns the raw output notes referenced by the summary. #### Returns -`OutputNotes` +`RawOutputNotes` *** diff --git a/docs/typedoc/web-client/functions/createP2IDENote.md b/docs/typedoc/web-client/functions/createP2IDENote.md index 1f1f7ff691..77192bcbb7 100644 --- a/docs/typedoc/web-client/functions/createP2IDENote.md +++ b/docs/typedoc/web-client/functions/createP2IDENote.md @@ -6,7 +6,7 @@ # Function: createP2IDENote() -> **createP2IDENote**(`options`): [`OutputNote`](../classes/OutputNote.md) +> **createP2IDENote**(`options`): [`RawOutputNote`](../classes/RawOutputNote.md) Creates a P2IDE (Pay-to-ID with Expiration) note. @@ -18,4 +18,4 @@ Creates a P2IDE (Pay-to-ID with Expiration) note. ## Returns -[`OutputNote`](../classes/OutputNote.md) +[`RawOutputNote`](../classes/RawOutputNote.md) diff --git a/docs/typedoc/web-client/functions/createP2IDNote.md b/docs/typedoc/web-client/functions/createP2IDNote.md index 9d36f8db87..d6fba8dd8f 100644 --- a/docs/typedoc/web-client/functions/createP2IDNote.md +++ b/docs/typedoc/web-client/functions/createP2IDNote.md @@ -6,7 +6,7 @@ # Function: createP2IDNote() -> **createP2IDNote**(`options`): [`OutputNote`](../classes/OutputNote.md) +> **createP2IDNote**(`options`): [`RawOutputNote`](../classes/RawOutputNote.md) Creates a P2ID (Pay-to-ID) note. @@ -18,4 +18,4 @@ Creates a P2ID (Pay-to-ID) note. ## Returns -[`OutputNote`](../classes/OutputNote.md) +[`RawOutputNote`](../classes/RawOutputNote.md) diff --git a/packages/react-sdk/examples/wallet/package.json b/packages/react-sdk/examples/wallet/package.json index 6208a82740..9e82d7c447 100644 --- a/packages/react-sdk/examples/wallet/package.json +++ b/packages/react-sdk/examples/wallet/package.json @@ -9,13 +9,13 @@ "preview": "vite preview" }, "dependencies": { - "@miden-sdk/miden-sdk": "^0.13.0", - "@miden-sdk/react": "^0.13.3", + "@miden-sdk/miden-sdk": "^0.14.0", + "@miden-sdk/react": "^0.14.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { - "@miden-sdk/vite-plugin": "^0.13.4", + "@miden-sdk/vite-plugin": "^0.14.0", "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", "@vitejs/plugin-react": "^4.2.0", diff --git a/packages/react-sdk/package.json b/packages/react-sdk/package.json index 52b93456d8..649a343bfd 100644 --- a/packages/react-sdk/package.json +++ b/packages/react-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@miden-sdk/react", - "version": "0.13.4", + "version": "0.14.0", "description": "React hooks library for Miden Web Client", "main": "dist/index.js", "module": "dist/index.mjs", @@ -28,7 +28,7 @@ "test:all": "VITE_CJS_IGNORE_WARNING=1 vitest run && playwright test" }, "peerDependencies": { - "@miden-sdk/miden-sdk": "^0.13.0", + "@miden-sdk/miden-sdk": "^0.14.0", "react": ">=18.0.0" }, "dependencies": { diff --git a/packages/react-sdk/src/__tests__/mocks/miden-sdk.ts b/packages/react-sdk/src/__tests__/mocks/miden-sdk.ts index 73fb241633..6ce0de3b57 100644 --- a/packages/react-sdk/src/__tests__/mocks/miden-sdk.ts +++ b/packages/react-sdk/src/__tests__/mocks/miden-sdk.ts @@ -244,17 +244,13 @@ export const MockFungibleAsset = class FungibleAsset { export const MockNoteAttachment = class NoteAttachment {}; -export const MockOutputNoteArray = class OutputNoteArray { +export const MockNoteArray = class NoteArray { notes: unknown[]; constructor(notes: unknown[]) { this.notes = notes; } }; -export const MockOutputNote = { - full: vi.fn((note: unknown) => ({ note })), -}; - export const MockNoteAndArgs = class NoteAndArgs { note: unknown; args: unknown; @@ -441,8 +437,7 @@ export const createMockSdkModule = ( NoteAssets: MockNoteAssets, FungibleAsset: MockFungibleAsset, NoteAttachment: MockNoteAttachment, - OutputNoteArray: MockOutputNoteArray, - OutputNote: MockOutputNote, + NoteArray: MockNoteArray, NoteAndArgs: MockNoteAndArgs, NoteAndArgsArray: MockNoteAndArgsArray, TransactionRequestBuilder: MockTransactionRequestBuilder, diff --git a/packages/react-sdk/src/__tests__/setup.ts b/packages/react-sdk/src/__tests__/setup.ts index 4fe95f7231..303d16f4b6 100644 --- a/packages/react-sdk/src/__tests__/setup.ts +++ b/packages/react-sdk/src/__tests__/setup.ts @@ -198,15 +198,12 @@ vi.mock("@miden-sdk/miden-sdk", () => { (_scheme: unknown, _words: unknown[]) => new (class NoteAttachment {})() ), }), - OutputNoteArray: class OutputNoteArray { + NoteArray: class NoteArray { notes: unknown[]; constructor(notes: unknown[]) { this.notes = notes; } }, - OutputNote: { - full: vi.fn((note: unknown) => ({ note })), - }, NoteAndArgs: class NoteAndArgs { note: unknown; args: unknown; diff --git a/packages/react-sdk/src/hooks/useMultiSend.ts b/packages/react-sdk/src/hooks/useMultiSend.ts index af77d2b39d..78d81122b8 100644 --- a/packages/react-sdk/src/hooks/useMultiSend.ts +++ b/packages/react-sdk/src/hooks/useMultiSend.ts @@ -6,8 +6,7 @@ import { NoteAssets, NoteAttachment, NoteType, - OutputNote, - OutputNoteArray, + NoteArray, TransactionRequestBuilder, } from "@miden-sdk/miden-sdk"; import type { @@ -134,7 +133,6 @@ export function useMultiSend(): UseMultiSendResult { ); const recipientAddress = parseAddress(to, receiverId); return { - outputNote: OutputNote.full(note), note, recipientAddress, noteType: resolvedNoteType, @@ -143,9 +141,7 @@ export function useMultiSend(): UseMultiSendResult { ); const txRequest = new TransactionRequestBuilder() - .withOwnOutputNotes( - new OutputNoteArray(outputs.map((o) => o.outputNote)) - ) + .withOwnOutputNotes(new NoteArray(outputs.map((o) => o.note))) .build(); const txSenderId = parseAccountId(options.from); diff --git a/packages/react-sdk/src/hooks/useSend.ts b/packages/react-sdk/src/hooks/useSend.ts index 10e4f044f6..a63475b3b8 100644 --- a/packages/react-sdk/src/hooks/useSend.ts +++ b/packages/react-sdk/src/hooks/useSend.ts @@ -6,8 +6,7 @@ import { NoteAssets, NoteAttachment, NoteType, - OutputNote, - OutputNoteArray, + NoteArray, TransactionRequestBuilder, } from "@miden-sdk/miden-sdk"; import type { SendOptions, SendResult, TransactionStage } from "../types"; @@ -168,9 +167,7 @@ export function useSend(): UseSendResult { ); const txRequest = new TransactionRequestBuilder() - .withOwnOutputNotes( - new OutputNoteArray([OutputNote.full(p2idNote)]) - ) + .withOwnOutputNotes(new NoteArray([p2idNote])) .build(); const execFromId = parseAccountId(options.from); @@ -217,7 +214,7 @@ export function useSend(): UseSendResult { attachment ); txRequest = new TransactionRequestBuilder() - .withOwnOutputNotes(new OutputNoteArray([OutputNote.full(note)])) + .withOwnOutputNotes(new NoteArray([note])) .build(); } else { txRequest = client.newSendTransactionRequest( diff --git a/packages/vite-plugin/package.json b/packages/vite-plugin/package.json index 252dc5fc7a..5b83ff5022 100644 --- a/packages/vite-plugin/package.json +++ b/packages/vite-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@miden-sdk/vite-plugin", - "version": "0.13.4", + "version": "0.14.0", "description": "Vite plugin for Miden dApps — WASM dedup, COOP/COEP headers, and gRPC-web proxy", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d9a424cef9..d5f2b18b88 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.91" +channel = "1.93" components = ["clippy", "rust-src", "rustfmt"] profile = "minimal" targets = ["wasm32-unknown-unknown"] diff --git a/scripts/check-react-sdk-sync.js b/scripts/check-react-sdk-sync.js index 4acb80e5d4..448d056cdd 100644 --- a/scripts/check-react-sdk-sync.js +++ b/scripts/check-react-sdk-sync.js @@ -46,7 +46,11 @@ if (!versionMatch) { const major = Number(versionMatch[1]); const minor = Number(versionMatch[2]); -const expectedRange = `^${major}.${minor}.0`; +const patch = Number(versionMatch[3]); +const prerelease = versionMatch[4] || ""; +const expectedRange = prerelease + ? `^${major}.${minor}.${patch}${prerelease}` + : `^${major}.${minor}.0`; const peerDeps = reactSdkPkg.peerDependencies || {}; const actualRange = peerDeps["@miden-sdk/miden-sdk"];