diff --git a/CHANGELOG.md b/CHANGELOG.md index f1dd9b5fa7..b84d63e112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ ### Changes - Added a non-fungible (NFT) faucet (`NonFungibleFaucet`): the asset value is an off-chain salted commitment `hash(user_data, salt)`, and an on-chain asset-status registry keyed by `[hash0, hash1, 0, 0]` enforces per-commitment uniqueness and permanent burn. Added `create_user_non_fungible_faucet` / `create_network_non_fungible_faucet` APIs, the `mint_nft` / `burn_nft` note scripts (`NonFungibleMintNote` / `NonFungibleBurnNote`), a `compute_commitment` helper, and reuses `TokenMetadata` (with `external_link` surfaced as `contract_uri`) and `TokenPolicyManager` for mint/burn/transfer policies ([#3106](https://github.com/0xMiden/protocol/pull/3106)). - [BREAKING] Refactored the mint policy interface so it is shared across fungible and non-fungible faucets: `policy_manager::execute_mint_policy` (and the mint policy `check_policy` predicates) now operate on the full `ASSET_VALUE` word instead of an `amount` ([#3106](https://github.com/0xMiden/protocol/pull/3106)). + +- [BREAKING] Updated Miden VM dependencies to v0.24, Miden crypto dependencies to v0.27, and the MSRV to 1.96 ([#3064](https://github.com/0xMiden/protocol/issues/3064)). +- [BREAKING] Updated Miden VM dependencies to v0.24, Miden crypto dependencies to v0.27, and the MSRV to 1.96 ([#3064](https://github.com/0xMiden/protocol/issues/3064), [#3146](https://github.com/0xMiden/protocol/pull/3146)). - [BREAKING] Replaced the `P2idNote` marker type and its `P2idNote::create` factory with a `P2idNote` struct built via a `bon` typestate builder (`P2idNote::builder()`). P2ID notes must now carry at least one asset; a `P2idNote` converts into a `Note` via `Note::from`, and the builder offers `.asset()`/`.assets()`, `.attachment()`/`.attachments()`, and `.generate_serial_number()` ([#2283](https://github.com/0xMiden/protocol/issues/2283)). - [BREAKING] Replaced the `MintNote` marker type and its `MintNote::create` factory with a struct built via a `bon` typestate builder (`MintNote::builder()`); a `MintNote` converts into a `Note` via `Note::from` ([#2283](https://github.com/0xMiden/protocol/issues/2283)). - [BREAKING] Replaced the `BurnNote` marker type and its `BurnNote::create` factory with a struct built via a `bon` typestate builder (`BurnNote::builder()`); a `BurnNote` converts into a `Note` via `Note::from` ([#2283](https://github.com/0xMiden/protocol/issues/2283)). diff --git a/Cargo.lock b/Cargo.lock index 6a10ed19fa..4ec8b08d93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,12 +19,12 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ - "crypto-common 0.1.7", - "generic-array", + "crypto-common", + "inout", ] [[package]] @@ -207,15 +207,6 @@ version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" -[[package]] -name = "ascii-canvas" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" -dependencies = [ - "term", -] - [[package]] name = "assert_matches" version = "1.5.0" @@ -245,9 +236,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64ct" @@ -287,36 +278,12 @@ dependencies = [ "miden-standards", "miden-testing", "miden-tx", - "rand 0.9.4", + "rand 0.10.1", "serde", "serde_json", "tokio", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" version = "1.3.2" @@ -343,15 +310,6 @@ dependencies = [ "cpufeatures 0.3.0", ] -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.12.1" @@ -436,26 +394,26 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures 0.3.0", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "1c9ed179664f12fd6f155f6dd632edf5f3806d48c228c67ff78366f2a0eb6b5e" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] @@ -487,13 +445,13 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common 0.1.7", + "block-buffer", + "crypto-common", "inout", - "zeroize", ] [[package]] @@ -521,6 +479,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "colorchoice" version = "1.0.5" @@ -541,9 +505,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" @@ -560,6 +524,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -655,46 +625,49 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "hybrid-array", + "rand_core 0.10.1", ] [[package]] -name = "crypto-common" -version = "0.2.2" +name = "ctutils" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" dependencies = [ - "hybrid-array", + "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "c906a87e53a36ff795d72e06e8162a83c5436e3ea89e942a9cb9fc083f0a384f" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures 0.3.0", "curve25519-dalek-derive", - "digest 0.10.7", + "digest", "fiat-crypto", "rustc_version 0.4.1", "subtle", @@ -789,9 +762,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" dependencies = [ "const-oid", "zeroize", @@ -820,26 +793,16 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common 0.1.7", - "subtle", -] - [[package]] name = "digest" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.1", - "crypto-common 0.2.2", + "block-buffer", + "const-oid", + "crypto-common", + "ctutils", ] [[package]] @@ -856,23 +819,24 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0-rc.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "b7c72d1455753a703ad4b90ed2a759f2bc4562024a303176439cf6e593b5ade4" dependencies = [ "der", - "digest 0.10.7", + "digest", "elliptic-curve", "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -880,14 +844,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "1685663e23882cd8517dcbcb1c23a6ebff4433c22dfb681d760219b62cd1b849" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] @@ -900,33 +865,25 @@ checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "3273f1195b6f6253ebda493d6742c8baa9b26a291674cd96d92a0f09e90e9b46" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "crypto-common", + "digest", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] -[[package]] -name = "ena" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" -dependencies = [ - "log", -] - [[package]] name = "env_filter" version = "2.0.0" @@ -1005,19 +962,19 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" @@ -1046,21 +1003,12 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", "spin 0.9.8", ] @@ -1167,30 +1115,6 @@ dependencies = [ "windows-result", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - [[package]] name = "getrandom" version = "0.3.4" @@ -1198,11 +1122,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] @@ -1212,8 +1134,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", + "wasm-bindgen", ] [[package]] @@ -1230,12 +1155,12 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -1276,29 +1201,31 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ + "subtle", "typenum", + "zeroize", ] [[package]] @@ -1343,11 +1270,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -1439,25 +1366,16 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0-rc.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "905d38bdbb43bb506efa0a428b3e969ff244549832a86b18591492f503adfe37" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", + "primeorder", "sha2", - "signature", -] - -[[package]] -name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", + "wnaf", ] [[package]] @@ -1470,36 +1388,6 @@ dependencies = [ "cpufeatures 0.3.0", ] -[[package]] -name = "lalrpop" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools 0.14.0", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "sha3 0.10.9", - "string_cache", - "term", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" -dependencies = [ - "rustversion", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -1589,9 +1477,9 @@ dependencies = [ [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "6a4bd6b4492fd2fccbbe1b66ef7bef81943e3afb4a89b057a4e4b9488a2906c3" dependencies = [ "miden-core", "miden-crypto", @@ -1605,6 +1493,7 @@ dependencies = [ "alloy-sol-types", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", "miden-crypto", "miden-protocol", @@ -1620,14 +1509,13 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "8b3dada5eeb5a11fc837bb1a211944baec05c362daec5ee51771660db892cd21" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", "proptest", "thiserror", @@ -1636,9 +1524,9 @@ dependencies = [ [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "1e8c7e16af3b0fae66a6718cc84ce30bed9098825b87505b0e9e82856c65d03e" dependencies = [ "env_logger", "log", @@ -1654,15 +1542,13 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "50370591ec06be1a8b25a9ba0478b526d4d631e55b66b38094cf9e0952a797ee" dependencies = [ - "aho-corasick", "env_logger", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1677,6 +1563,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89fc0c1acb2af6d6d7ef3f1254a373ac10371f2b81e7b313c9dad4f6b4b34801" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-block-prover" version = "0.16.0" @@ -1687,9 +1585,9 @@ dependencies = [ [[package]] name = "miden-core" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "793507a39dd6bb0bc796f3305ada4201fbdae5ccbe80d69904364bb1ec8be47f" dependencies = [ "derive_more", "log", @@ -1699,25 +1597,24 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "proptest", - "proptest-derive", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "f1456d3ba4bfca531d68c30eda37da0f9c8f253fedaa487bd951766247233207" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", "miden-crypto", + "miden-mast-package", "miden-package-registry", "miden-processor", "miden-utils-sync", @@ -1726,9 +1623,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "bb57a3fbdf2bdc51bd024050719c65929d0545f4cca225000f99678f62935f02" dependencies = [ "blake3", "cc", @@ -1755,14 +1652,12 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.1", + "rand_chacha 0.10.0", "rayon", "serde", "sha2", - "sha3 0.10.9", + "sha3 0.12.0", "subtle", "thiserror", "x25519-dalek", @@ -1770,9 +1665,9 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "4ee301b99abeeb640f9f5eaa7c11f731bab5b2e7671cbaebed606da5ff1a4a2b" dependencies = [ "quote", "syn 2.0.118", @@ -1780,9 +1675,9 @@ dependencies = [ [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "433d7accc2ee944f84e05db89771477337ae31fcbafe9b42c8493d6e78e3557c" dependencies = [ "memchr", "miden-crypto", @@ -1799,9 +1694,9 @@ dependencies = [ [[package]] name = "miden-field" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "06741437192077e3fec0a0685ef05ea883aa3823bc0722ae56b178233db2812f" dependencies = [ "miden-serde-utils", "num-bigint", @@ -1827,11 +1722,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "abf4dca41a33d65992ad877746539b48fbc367101d2ed3161d3b727140af3aaf" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1840,9 +1736,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "7087fe7fa147cd443848844afdf54ffa8be697bd8d7b8304662fd6b252a01aa2" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1863,10 +1759,11 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "f34ec81059706731c6ba4d9a07c296f4173b3757a39d3bd142aaf86e166f9d18" dependencies = [ + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", @@ -1912,9 +1809,9 @@ dependencies = [ [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "8030437598f39db6756b485ecf50f652961d9b9e3a358264b79d2a1af4f1d621" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1928,14 +1825,15 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "a4d2290ad4a1184672bc49385246eae53b28d9eeedcad2e2a465e229535cb8fb" dependencies = [ "itertools 0.14.0", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -1946,9 +1844,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "f06dd2af5f359ed257297900a3598288a44689445089422225d734b98ab90086" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1970,7 +1868,7 @@ dependencies = [ "bech32", "criterion", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -1983,8 +1881,8 @@ dependencies = [ "miden-utils-sync", "miden-verifier", "pprof", - "rand 0.9.4", - "rand_chacha", + "rand 0.10.1", + "rand_chacha 0.10.0", "rand_xoshiro", "regex", "rstest", @@ -1998,24 +1896,35 @@ dependencies = [ [[package]] name = "miden-prover" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a91bcc00840b01126cd54e3b68ce3235def2ed48803f2eeb36a035d6951fbc1" +checksum = "a5f9ec0f99d597676534ef2354d08fca4d32983760ec446b3a858e6edca5e1bd" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", "miden-processor", "serde", + "serde-wincode", "tracing", + "wincode", +] + +[[package]] +name = "miden-rowan" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" +dependencies = [ + "hashbrown", + "rustc-hash", ] [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "b8a89e64d3ccd5b51b0ef08cdfc36e1bbd1402448275520eb0208de740125509" dependencies = [ "p3-field", "p3-goldilocks", @@ -2030,10 +1939,11 @@ dependencies = [ "bon", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core-lib", "miden-protocol", "miden-standards", - "rand 0.9.4", + "rand 0.10.1", "regex", "thiserror", "walkdir", @@ -2041,9 +1951,9 @@ dependencies = [ [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "3ca940751e1ca7abc33a9b8eaaad4cdd6f153613380ad2c3626134bab6aafb91" dependencies = [ "p3-challenger", "p3-field", @@ -2053,9 +1963,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "bcc3510d500d4ce676652ef24539e2be4f04ae63d0bf8299799ca16d79b66a9d" dependencies = [ "p3-field", "p3-symmetric", @@ -2079,8 +1989,8 @@ dependencies = [ "miden-tx", "miden-tx-batch", "primitive-types", - "rand 0.9.4", - "rand_chacha", + "rand 0.10.1", + "rand_chacha 0.10.0", "rstest", "serde", "serde_json", @@ -2096,7 +2006,7 @@ dependencies = [ "miden-protocol", "miden-prover", "miden-standards", - "rand_chacha", + "rand_chacha 0.10.0", "thiserror", ] @@ -2113,9 +2023,9 @@ dependencies = [ [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "2c006cdb21821eda843d1022394579bfbec68ee7ddd59de3a9423319e63a47e7" dependencies = [ "proc-macro2", "quote", @@ -2124,11 +2034,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "b2b1fac011911175970b25c74254b84673771100e2ba541bfbf0a72263156f1e" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -2136,9 +2045,9 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "f43b8612181db14d824b6b48013489af0eec1f89289a42029f9dbba6e350060d" dependencies = [ "miden-crypto", "proptest", @@ -2148,9 +2057,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "56d103e41139d7d55cf59e09823cc2fd5c0e560d2b7aac679803869dd0932597" dependencies = [ "lock_api", "loom", @@ -2160,24 +2069,25 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "7294a3cd5a656bf4adb4ecb4b5ca13043f2c891802f66c3c242c6e06a5e16ebd" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", "serde", + "serde-wincode", "thiserror", "tracing", + "wincode", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "ff8e411205251d07ec902559d80f097e66fedb644e0c35dc4cad431c10b99a4d" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -2196,21 +2106,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nix" version = "0.26.4" @@ -2264,17 +2159,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - [[package]] name = "num-format" version = "0.4.4" @@ -2357,12 +2241,6 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "owo-colors" version = "4.3.0" @@ -2371,9 +2249,9 @@ checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "a3e18b22bf85451382098e54da526733c7f390f83d4141b3b8b93e98e805df55" dependencies = [ "p3-field", "p3-matrix", @@ -2382,9 +2260,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "1be4f62b2e8cc5c9b2bc0bfb0b1a98dcaaa2f5c25b167f04c8ac6123537a604b" dependencies = [ "blake3", "p3-symmetric", @@ -2393,9 +2271,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "272b2cfdcd3cf1affeab292aa7888ed7e4c156e0d5ffc19612c86553941db178" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -2407,24 +2285,24 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "1dc420990b39aa4cdb78ac248d5defe97f760c1056aeceb160dcf3e62baf4eb7" dependencies = [ "itertools 0.14.0", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.1", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "ab37408c6c964e7e18c2305a15e31bc784aa20eb82eb513b4850aaa13ee445d3" dependencies = [ "itertools 0.14.0", "num-bigint", @@ -2438,9 +2316,9 @@ dependencies = [ [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "cdf8c89d8e833f93c488bd207786cd2d525a9f93de7f00363bca5652c88110a4" dependencies = [ "num-bigint", "p3-challenger", @@ -2458,9 +2336,9 @@ dependencies = [ [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "1868cb9c763e5786f89d531e15b9899f9dd3ba96768645294b99fd9df861b530" dependencies = [ "p3-symmetric", "p3-util", @@ -2469,9 +2347,9 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "a7c5e32dd61fa6341f8ce7abe2a97e9c3f8a93d9ea17bf4f675a2f6c987b658e" dependencies = [ "itertools 0.14.0", "p3-field", @@ -2484,18 +2362,18 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "49c17330c94d04221bafe310d2c13afedd9d26bb57a63ec088b68b6cfe64b357" dependencies = [ "rayon", ] [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "09ea6f54d4436d44f14841f78238b79199b83ea983a4a2fa3c4d16202f28f119" dependencies = [ "p3-dft", "p3-field", @@ -2506,9 +2384,9 @@ dependencies = [ [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "12d3acd0d5f0ba2e8a1c903e80c92e778368b68c2e551a6c30fc3982a4be023e" dependencies = [ "itertools 0.14.0", "num-bigint", @@ -2524,26 +2402,27 @@ dependencies = [ "paste", "rand 0.10.1", "serde", - "spin 0.10.0", + "spin 0.12.1", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "9cccfe593f85f87681f885c32f1447ea7afe12b3c9b11b4149c4534edacacb51" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", "rand 0.10.1", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "d28bb6596f38c493d7a590e3b7d30eae86cbcfc325fb44f652ec3540933bcaa0" dependencies = [ "p3-field", "p3-mds", @@ -2554,9 +2433,9 @@ dependencies = [ [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "284db1f284c4007eeb65cef4656426c93192af9bd9703b7f3afbf7faab274500" dependencies = [ "itertools 0.14.0", "p3-field", @@ -2566,9 +2445,9 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "f241f0faa735a03b1af8c923b4728a9fac5e4a26e573a087656c354a784dfcae" dependencies = [ "rayon", "serde", @@ -2605,23 +2484,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "petgraph" -version = "0.7.1" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pin-project-lite" @@ -2631,9 +2497,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -2669,12 +2535,11 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "a00baa632505d05512f48a963e16051c54fda9a95cc9acea1a4e3c90991c4a2e" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures 0.3.0", "universal-hash", ] @@ -2725,12 +2590,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2741,6 +2600,31 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "primefield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" +dependencies = [ + "crypto-bigint", + "crypto-common", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0-rc.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e56e6d67fdf5744e9e245ae571450fe584b91f5af261d0e40163b618e53a1f6" +dependencies = [ + "elliptic-curve", + "primefield", + "serdect", +] + [[package]] name = "primitive-types" version = "0.14.0" @@ -2811,7 +2695,7 @@ dependencies = [ "bitflags 2.13.0", "num-traits", "rand 0.9.4", - "rand_chacha", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -2887,7 +2771,7 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] @@ -2897,6 +2781,8 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2910,14 +2796,21 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" +dependencies = [ + "ppv-lite86", + "rand_core 0.10.1", +] + [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] [[package]] name = "rand_core" @@ -2934,15 +2827,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xorshift" version = "0.4.0" @@ -2954,11 +2838,11 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +checksum = "662effc7698e08ea324d3acccf8d9d7f7bf79b9785e270a174ea36e56900c91d" dependencies = [ - "rand_core 0.9.5", + "rand_core 0.10.1", ] [[package]] @@ -3027,12 +2911,12 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "9935425142ac6e252364413291d96c8bc9898d0876a801824c7af4eae397b689" dependencies = [ + "ctutils", "hmac", - "subtle", ] [[package]] @@ -3166,14 +3050,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -3225,6 +3109,17 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a62dfa6ae65cb073dfe001fb076eaf827fd4267fcba7eb3be2fee4f1e69ccb5" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -3279,35 +3174,46 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", + "cpufeatures 0.3.0", + "digest", ] [[package]] name = "sha3" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" dependencies = [ - "digest 0.10.7", - "keccak 0.1.6", + "digest", + "keccak", ] [[package]] name = "sha3" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ - "digest 0.11.3", - "keccak 0.2.0", + "digest", + "keccak", + "sponge-cursor", ] [[package]] @@ -3327,20 +3233,14 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", + "digest", + "rand_core 0.10.1", ] -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - [[package]] name = "slab" version = "0.4.12" @@ -3380,16 +3280,31 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spin" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd5231412d905519dca6a5deb0327d407be68d6c941feec004533401d3a0a715" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] +[[package]] +name = "sponge-cursor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -3414,18 +3329,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" -[[package]] -name = "string_cache" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] - [[package]] name = "strip-ansi-escapes" version = "0.2.1" @@ -3522,15 +3425,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "term" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -3826,12 +3720,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ - "crypto-common 0.1.7", - "subtle", + "crypto-common", + "ctutils", ] [[package]] @@ -3890,12 +3784,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - [[package]] name = "wasip2" version = "1.0.4+wasi-0.2.12" @@ -3991,6 +3879,18 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "wincode" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "657690780ce23e6f66576a782ffd88eb353512381817029cc1d7a99154bb6d1f" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-link" version = "0.2.1" @@ -4030,14 +3930,25 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +[[package]] +name = "wnaf" +version = "0.14.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86421f2a70c9e6cab8d84c99fb62d8761d355bd1285443a7e7ccad15aa515f2" +dependencies = [ + "ff", + "group", + "hybrid-array", +] + [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "eee64e8620caa64914d669b1f68f858aaff54e2d0f9ad3b30a613b58a1baa83e" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 294c15af92..7b42b9379a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ exclude = [".github/"] homepage = "https://miden.xyz" license = "MIT" repository = "https://github.com/0xMiden/protocol" -rust-version = "1.90" +rust-version = "1.96" version = "0.16.0" [profile.release] @@ -45,17 +45,17 @@ miden-tx = { default-features = false, path = "crates/miden-tx", versi miden-tx-batch = { default-features = false, path = "crates/miden-tx-batch", version = "0.16" } # Miden dependencies -miden-assembly = { default-features = false, version = "0.23" } -miden-assembly-syntax = { default-features = false, version = "0.23" } -miden-core = { default-features = false, version = "0.23" } -miden-core-lib = { default-features = false, version = "0.23" } -miden-crypto = { default-features = false, version = "0.25" } -miden-crypto-derive = { default-features = false, version = "0.25" } -miden-mast-package = { default-features = false, version = "0.23" } -miden-processor = { default-features = false, version = "0.23" } -miden-prover = { default-features = false, version = "0.23" } -miden-utils-sync = { default-features = false, version = "0.23" } -miden-verifier = { default-features = false, version = "0.23" } +miden-assembly = { default-features = false, version = "0.24" } +miden-assembly-syntax = { default-features = false, version = "0.24" } +miden-core = { default-features = false, version = "0.24" } +miden-core-lib = { default-features = false, version = "0.24" } +miden-crypto = { default-features = false, version = "0.27" } +miden-crypto-derive = { default-features = false, version = "0.27" } +miden-mast-package = { default-features = false, version = "0.24" } +miden-processor = { default-features = false, version = "0.24" } +miden-prover = { default-features = false, version = "0.24" } +miden-utils-sync = { default-features = false, version = "0.24" } +miden-verifier = { default-features = false, version = "0.24" } # External dependencies alloy-sol-types = { default-features = false, version = "1.5" } @@ -65,8 +65,8 @@ bon = { default-features = false, version = "3" } criterion = { default-features = false, version = "0.5" } fs-err = { default-features = false, version = "3" } primitive-types = { default-features = false, version = "0.14" } -rand = { default-features = false, version = "0.9" } -rand_chacha = { default-features = false, version = "0.9" } +rand = { default-features = false, version = "0.10" } +rand_chacha = { default-features = false, version = "0.10" } regex = { version = "1.11" } rstest = { version = "0.26" } serde = { default-features = false, version = "1.0" } diff --git a/README.md b/README.md index 0f5a0fbe68..7302aabc13 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/0xMiden/protocol/blob/main/LICENSE) [![test](https://github.com/0xMiden/protocol/actions/workflows/test.yml/badge.svg)](https://github.com/0xMiden/protocol/actions/workflows/test.yml) [![build](https://github.com/0xMiden/protocol/actions/workflows/build.yml/badge.svg)](https://github.com/0xMiden/protocol/actions/workflows/build.yml) -[![RUST_VERSION](https://img.shields.io/badge/rustc-1.90+-lightgray.svg)](https://www.rust-lang.org/tools/install) +[![RUST_VERSION](https://img.shields.io/badge/rustc-1.96+-lightgray.svg)](https://www.rust-lang.org/tools/install) [![GitHub Release](https://img.shields.io/github/release/0xMiden/protocol)](https://github.com/0xMiden/protocol/releases/) Description and core structures for the Miden Rollup protocol. diff --git a/bin/bench-transaction/Cargo.toml b/bin/bench-transaction/Cargo.toml index 3b7f864030..62a4ad664e 100644 --- a/bin/bench-transaction/Cargo.toml +++ b/bin/bench-transaction/Cargo.toml @@ -13,6 +13,34 @@ version = "0.1.0" [lib] doctest = false +[features] +# Transaction benchmarks use the concurrent proving stack. That stack requires `std`, so keep it +# behind a default feature to avoid enabling it in no-default workspace library builds. +concurrent = [ + "dep:anyhow", + "dep:miden-agglayer", + "dep:miden-processor", + "dep:miden-protocol", + "dep:miden-standards", + "dep:miden-testing", + "dep:miden-tx", + "dep:rand", + "dep:serde", + "dep:serde_json", + "dep:tokio", + "miden-agglayer/testing", + "miden-processor/concurrent", + "miden-protocol/testing", + "miden-tx/concurrent", + "serde/derive", + "serde/std", + "serde_json/preserve_order", + "serde_json/std", + "tokio/macros", + "tokio/rt", +] +default = ["concurrent"] + [[bench]] harness = false name = "time_counting_benchmarks" @@ -20,19 +48,19 @@ path = "src/time_counting_benchmarks/prove.rs" [dependencies] # Workspace dependencies -miden-agglayer = { features = ["testing"], workspace = true } -miden-processor = { features = ["concurrent"], workspace = true } -miden-protocol = { features = ["testing"], workspace = true } -miden-standards = { workspace = true } -miden-testing = { workspace = true } -miden-tx = { features = ["concurrent"], workspace = true } +miden-agglayer = { optional = true, workspace = true } +miden-processor = { optional = true, workspace = true } +miden-protocol = { optional = true, workspace = true } +miden-standards = { optional = true, workspace = true } +miden-testing = { optional = true, workspace = true } +miden-tx = { optional = true, workspace = true } # External dependencies -anyhow = { workspace = true } -rand = { workspace = true } -serde = { features = ["derive", "std"], workspace = true } -serde_json = { features = ["preserve_order", "std"], workspace = true } -tokio = { features = ["macros", "rt"], workspace = true } +anyhow = { optional = true, workspace = true } +rand = { optional = true, workspace = true } +serde = { optional = true, workspace = true } +serde_json = { optional = true, workspace = true } +tokio = { optional = true, workspace = true } [dev-dependencies] criterion = { features = ["async_tokio", "html_reports"], workspace = true } diff --git a/bin/bench-transaction/src/context_setups.rs b/bin/bench-transaction/src/context_setups.rs index d998176cf0..f90ae1651c 100644 --- a/bin/bench-transaction/src/context_setups.rs +++ b/bin/bench-transaction/src/context_setups.rs @@ -24,7 +24,7 @@ use miden_protocol::{Felt, Word}; use miden_standards::code_builder::CodeBuilder; use miden_standards::note::StandardNote; use miden_testing::{Auth, MockChain, TransactionContext}; -use rand::Rng; +use rand::RngExt; // P2ID NOTE SETUPS // ================================================================================================ diff --git a/bin/bench-transaction/src/cycle_counting_benchmarks/utils.rs b/bin/bench-transaction/src/cycle_counting_benchmarks/utils.rs index 7159925b0e..71a2bc0cde 100644 --- a/bin/bench-transaction/src/cycle_counting_benchmarks/utils.rs +++ b/bin/bench-transaction/src/cycle_counting_benchmarks/utils.rs @@ -119,7 +119,7 @@ impl From for TraceMeasurements { ); let ace_rows = chiplets.trace_len().saturating_sub(known + 1); Self { - core_rows: summary.main_trace_len(), + core_rows: summary.trace_len(), chiplets_rows: chiplets.trace_len(), range_rows: summary.range_trace_len(), chiplets_shape: ChipletsTraceShape { diff --git a/bin/bench-transaction/src/lib.rs b/bin/bench-transaction/src/lib.rs index 882a85de80..e325708a73 100644 --- a/bin/bench-transaction/src/lib.rs +++ b/bin/bench-transaction/src/lib.rs @@ -1 +1,4 @@ +#![cfg_attr(not(feature = "concurrent"), no_std)] + +#[cfg(feature = "concurrent")] pub mod context_setups; diff --git a/crates/miden-agglayer/Cargo.toml b/crates/miden-agglayer/Cargo.toml index c314c4e322..a0d654f076 100644 --- a/crates/miden-agglayer/Cargo.toml +++ b/crates/miden-agglayer/Cargo.toml @@ -46,11 +46,12 @@ serde = { features = ["derive"], workspace = true } serde_json = { features = ["std"], workspace = true } [build-dependencies] -fs-err = { workspace = true } -miden-assembly = { workspace = true } -miden-core = { workspace = true } -miden-crypto = { workspace = true } -miden-protocol = { features = ["testing"], workspace = true } -miden-standards = { workspace = true } -regex = { workspace = true } -walkdir = { workspace = true } +fs-err = { workspace = true } +miden-assembly = { workspace = true } +miden-assembly-syntax = { workspace = true } +miden-core = { workspace = true } +miden-crypto = { workspace = true } +miden-protocol = { features = ["testing"], workspace = true } +miden-standards = { workspace = true } +regex = { workspace = true } +walkdir = { workspace = true } diff --git a/crates/miden-agglayer/asm/agglayer/bridge/bridge_in.masm b/crates/miden-agglayer/asm/agglayer/bridge/bridge_in.masm index cdd622435a..b666823c14 100644 --- a/crates/miden-agglayer/asm/agglayer/bridge/bridge_in.masm +++ b/crates/miden-agglayer/asm/agglayer/bridge/bridge_in.masm @@ -1,7 +1,7 @@ use agglayer::bridge::bridge_config use agglayer::bridge::bridge_in_output use agglayer::bridge::leaf_utils -use agglayer::common::constants::MIDEN_NETWORK_ID +use {MIDEN_NETWORK_ID} from agglayer::common::constants use agglayer::common::utils use agglayer::common::asset_conversion use agglayer::common::eth_address @@ -11,8 +11,8 @@ use miden::core::mem use miden::core::word use miden::protocol::active_account use miden::protocol::native_account -use miden::protocol::types::DoubleWord -use miden::protocol::types::MemoryAddress +use {DoubleWord} from miden::protocol::types +use {MemoryAddress} from miden::protocol::types # ERRORS # ================================================================================================= diff --git a/crates/miden-agglayer/asm/agglayer/bridge/bridge_in_output.masm b/crates/miden-agglayer/asm/agglayer/bridge/bridge_in_output.masm index 37ae1925c1..acd05bf771 100644 --- a/crates/miden-agglayer/asm/agglayer/bridge/bridge_in_output.masm +++ b/crates/miden-agglayer/asm/agglayer/bridge/bridge_in_output.masm @@ -1,15 +1,15 @@ -use agglayer::bridge::bridge_in::CLAIM_OUTPUT_NOTE_FAUCET_AMOUNT -use agglayer::bridge::bridge_in::CLAIM_PROOF_DATA_KEY_MEM_ADDR +use {CLAIM_OUTPUT_NOTE_FAUCET_AMOUNT} from agglayer::bridge::bridge_in +use {CLAIM_PROOF_DATA_KEY_MEM_ADDR} from agglayer::bridge::bridge_in use miden::protocol::asset use miden::protocol::native_account use miden::protocol::note -use miden::protocol::note::NOTE_TYPE_PUBLIC +use {NOTE_TYPE_PUBLIC} from miden::protocol::note use miden::protocol::output_note use miden::standards::note_tag -use miden::standards::note_tag::DEFAULT_TAG +use {DEFAULT_TAG} from miden::standards::note_tag use miden::standards::notes::p2id use miden::standards::attachments::network_account_target -use miden::standards::note::execution_hint::ALWAYS +use {ALWAYS} from miden::standards::note::execution_hint # CONSTANTS # ================================================================================================= diff --git a/crates/miden-agglayer/asm/agglayer/bridge/bridge_out.masm b/crates/miden-agglayer/asm/agglayer/bridge/bridge_out.masm index ffa068bbf2..46be0ae24c 100644 --- a/crates/miden-agglayer/asm/agglayer/bridge/bridge_out.masm +++ b/crates/miden-agglayer/asm/agglayer/bridge/bridge_out.masm @@ -5,18 +5,18 @@ use miden::protocol::native_account use miden::protocol::note use miden::standards::data_structures::double_word_array use miden::standards::attachments::network_account_target -use miden::standards::note_tag::DEFAULT_TAG -use miden::standards::note::execution_hint::ALWAYS -use miden::protocol::types::MemoryAddress +use {DEFAULT_TAG} from miden::standards::note_tag +use {ALWAYS} from miden::standards::note::execution_hint +use {MemoryAddress} from miden::protocol::types use miden::protocol::output_note use miden::core::crypto::hashes::poseidon2 -use agglayer::common::constants::MIDEN_NETWORK_ID +use {MIDEN_NETWORK_ID} from agglayer::common::constants use agglayer::common::utils use agglayer::common::asset_conversion use agglayer::bridge::bridge_config use agglayer::bridge::leaf_utils use agglayer::bridge::merkle_tree_frontier -use agglayer::common::eth_address::EthereumAddressFormat +use {EthereumAddressFormat} from agglayer::common::eth_address # ERRORS # ================================================================================================= @@ -82,7 +82,7 @@ const ATTACHMENT_SCHEME_LOC=12 # ------------------------------------------------------------------------------------------------- const LEAF_TYPE_ASSET=0 -use miden::protocol::note::NOTE_TYPE_PUBLIC +use {NOTE_TYPE_PUBLIC} from miden::protocol::note const BURN_NOTE_NUM_STORAGE_ITEMS=0 # PUBLIC INTERFACE diff --git a/crates/miden-agglayer/asm/agglayer/bridge/canonical_zeros.masm b/crates/miden-agglayer/asm/agglayer/bridge/canonical_zeros.masm index 11ceaae5da..1c32693700 100644 --- a/crates/miden-agglayer/asm/agglayer/bridge/canonical_zeros.masm +++ b/crates/miden-agglayer/asm/agglayer/bridge/canonical_zeros.masm @@ -101,7 +101,7 @@ const ZERO_30_R = [1787682571, 2128594844, 578217418, 903308566] const ZERO_31_L = [2340505732, 1648733876, 2660540036, 3759582231] const ZERO_31_R = [2389186238, 4049365781, 1653344606, 2840985724] -use ::agglayer::common::utils::mem_store_double_word +use {mem_store_double_word} from ::agglayer::common::utils #! Inputs: [zeros_ptr] diff --git a/crates/miden-agglayer/asm/agglayer/bridge/leaf_utils.masm b/crates/miden-agglayer/asm/agglayer/bridge/leaf_utils.masm index 2ef1cbf4a2..1b8f9f8078 100644 --- a/crates/miden-agglayer/asm/agglayer/bridge/leaf_utils.masm +++ b/crates/miden-agglayer/asm/agglayer/bridge/leaf_utils.masm @@ -1,6 +1,6 @@ use miden::core::crypto::hashes::keccak256 -use miden::protocol::types::DoubleWord -use miden::protocol::types::MemoryAddress +use {DoubleWord} from miden::protocol::types +use {MemoryAddress} from miden::protocol::types # CONSTANTS # ================================================================================================= diff --git a/crates/miden-agglayer/asm/agglayer/bridge/merkle_tree_frontier.masm b/crates/miden-agglayer/asm/agglayer/bridge/merkle_tree_frontier.masm index 26add7c242..7fdd8df342 100644 --- a/crates/miden-agglayer/asm/agglayer/bridge/merkle_tree_frontier.masm +++ b/crates/miden-agglayer/asm/agglayer/bridge/merkle_tree_frontier.masm @@ -1,7 +1,7 @@ use miden::core::crypto::hashes::keccak256 -use ::agglayer::bridge::canonical_zeros::load_zeros_to_memory -use ::agglayer::common::utils::mem_store_double_word -use ::agglayer::common::utils::mem_load_double_word +use {load_zeros_to_memory} from ::agglayer::bridge::canonical_zeros +use {mem_store_double_word} from ::agglayer::common::utils +use {mem_load_double_word} from ::agglayer::common::utils # A Merkle Tree Frontier (MTF) is a data structure based on an Merkle Mountain Range (MMR), which # combines some features of an MMR and an SMT. diff --git a/crates/miden-agglayer/asm/agglayer/common/asset_conversion.masm b/crates/miden-agglayer/asm/agglayer/common/asset_conversion.masm index 832f1a770b..f6a05acabf 100644 --- a/crates/miden-agglayer/asm/agglayer/common/asset_conversion.masm +++ b/crates/miden-agglayer/asm/agglayer/common/asset_conversion.masm @@ -1,7 +1,7 @@ use miden::core::math::u64 use miden::core::word use agglayer::common::utils -use ::miden::protocol::asset::FUNGIBLE_ASSET_MAX_AMOUNT +use {FUNGIBLE_ASSET_MAX_AMOUNT} from ::miden::protocol::asset # ERRORS # ================================================================================================= diff --git a/crates/miden-agglayer/asm/agglayer/common/utils.masm b/crates/miden-agglayer/asm/agglayer/common/utils.masm index 79a1fe8c5f..0a68555bde 100644 --- a/crates/miden-agglayer/asm/agglayer/common/utils.masm +++ b/crates/miden-agglayer/asm/agglayer/common/utils.masm @@ -1,7 +1,7 @@ # Utility module containing helper procedures for double word handling and byte manipulation. -use miden::protocol::types::DoubleWord -use miden::protocol::types::MemoryAddress +use {DoubleWord} from miden::protocol::types +use {MemoryAddress} from miden::protocol::types # BYTE MANIPULATION # ================================================================================================= diff --git a/crates/miden-agglayer/asm/agglayer/faucet/mod.masm b/crates/miden-agglayer/asm/agglayer/faucet/mod.masm index 4b47a1ef60..70bc0fc1c2 100644 --- a/crates/miden-agglayer/asm/agglayer/faucet/mod.masm +++ b/crates/miden-agglayer/asm/agglayer/faucet/mod.masm @@ -17,7 +17,7 @@ #! - the amount about to be burned is greater than the outstanding supply of the asset. #! #! Invocation: call -pub use ::miden::standards::faucets::fungible::receive_and_burn +pub use {receive_and_burn} from ::miden::standards::faucets::fungible #! Re-export the fungible faucet's `mint_and_send` procedure. #! @@ -27,4 +27,4 @@ pub use ::miden::standards::faucets::fungible::receive_and_burn #! Outputs: [note_idx, pad(15)] #! #! Invocation: call -pub use ::miden::standards::faucets::fungible::mint_and_send +pub use {mint_and_send} from ::miden::standards::faucets::fungible diff --git a/crates/miden-agglayer/asm/components/bridge.masm b/crates/miden-agglayer/asm/components/bridge.masm index e8028400f9..c703cc74b7 100644 --- a/crates/miden-agglayer/asm/components/bridge.masm +++ b/crates/miden-agglayer/asm/components/bridge.masm @@ -10,9 +10,9 @@ # - `claim` for bridge-in # - `bridge_out` for bridge-out -pub use ::agglayer::bridge::bridge_config::register_faucet -pub use ::agglayer::bridge::bridge_config::store_faucet_metadata_hash -pub use ::agglayer::bridge::bridge_config::update_ger -pub use ::agglayer::bridge::bridge_config::remove_ger -pub use ::agglayer::bridge::bridge_in::claim -pub use ::agglayer::bridge::bridge_out::bridge_out +pub use {register_faucet} from ::agglayer::bridge::bridge_config +pub use {store_faucet_metadata_hash} from ::agglayer::bridge::bridge_config +pub use {update_ger} from ::agglayer::bridge::bridge_config +pub use {remove_ger} from ::agglayer::bridge::bridge_config +pub use {claim} from ::agglayer::bridge::bridge_in +pub use {bridge_out} from ::agglayer::bridge::bridge_out diff --git a/crates/miden-agglayer/asm/components/faucet.masm b/crates/miden-agglayer/asm/components/faucet.masm index 83202199da..29a3a045dd 100644 --- a/crates/miden-agglayer/asm/components/faucet.masm +++ b/crates/miden-agglayer/asm/components/faucet.masm @@ -7,5 +7,5 @@ # gated by the active mint policy) # - `receive_and_burn` for bridge-out -pub use ::agglayer::faucet::mint_and_send -pub use ::agglayer::faucet::receive_and_burn +pub use {mint_and_send} from ::agglayer::faucet +pub use {receive_and_burn} from ::agglayer::faucet diff --git a/crates/miden-agglayer/asm/note_scripts/b2agg.masm b/crates/miden-agglayer/asm/note_scripts/b2agg.masm index 30764588d5..d64f0fd725 100644 --- a/crates/miden-agglayer/asm/note_scripts/b2agg.masm +++ b/crates/miden-agglayer/asm/note_scripts/b2agg.masm @@ -4,7 +4,7 @@ use miden::protocol::active_account use miden::protocol::active_note use miden::protocol::asset use miden::standards::attachments::network_account_target -use miden::standards::wallets::basic->basic_wallet +use miden::standards::wallets::basic as basic_wallet # CONSTANTS # ================================================================================================= diff --git a/crates/miden-agglayer/asm/note_scripts/claim.masm b/crates/miden-agglayer/asm/note_scripts/claim.masm index d8bdfdd65f..15ede064b9 100644 --- a/crates/miden-agglayer/asm/note_scripts/claim.masm +++ b/crates/miden-agglayer/asm/note_scripts/claim.masm @@ -1,4 +1,4 @@ -use agglayer::bridge::bridge_in -> bridge +use agglayer::bridge::bridge_in as bridge use miden::protocol::active_note use miden::core::crypto::hashes::poseidon2 use miden::standards::attachments::network_account_target diff --git a/crates/miden-agglayer/build.rs b/crates/miden-agglayer/build.rs index 64a2334c4d..7b2ed217b8 100644 --- a/crates/miden-agglayer/build.rs +++ b/crates/miden-agglayer/build.rs @@ -1,15 +1,25 @@ -use std::collections::{BTreeSet, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::env; use std::fmt::Write; use std::path::Path; use std::sync::Arc; use fs_err as fs; -use miden_assembly::diagnostics::{IntoDiagnostic, NamedSource, Result, WrapErr}; -use miden_assembly::{Assembler, Library, Report}; +use miden_assembly::diagnostics::{IntoDiagnostic, Result, WrapErr}; +use miden_assembly::{ + Assembler, + Linkage, + ModuleParser, + Path as MasmPath, + Report, + SourceManager, + ast, +}; +use miden_assembly_syntax::Parse; use miden_core::Word; use miden_crypto::hash::keccak::{Keccak256, Keccak256Digest}; use miden_protocol::account::{AccountCode, AccountComponent, AccountComponentMetadata}; +use miden_protocol::assembly::Library; use miden_protocol::note::NoteScriptRoot; use miden_protocol::transaction::TransactionKernel; use miden_standards::account::access::Authority; @@ -37,6 +47,40 @@ const AGGLAYER_ERRORS_RS_FILE: &str = "agglayer_errors.rs"; const AGGLAYER_ERRORS_ARRAY_NAME: &str = "AGGLAYER_ERRORS"; const AGGLAYER_GLOBAL_CONSTANTS_FILE_NAME: &str = "agglayer_constants.rs"; +enum ModuleSource { + File { + file_path: std::path::PathBuf, + module_path: miden_assembly::PathBuf, + kind: ast::ModuleKind, + }, + Inline { + source: String, + module_path: miden_assembly::PathBuf, + kind: ast::ModuleKind, + }, +} + +impl Parse for ModuleSource { + fn parse( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> std::result::Result, Report> { + match self { + ModuleSource::File { file_path, module_path, kind } => { + let mut parser = ModuleParser::new(Some(kind)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_file(Some(module_path.as_path()), file_path, source_manager) + }, + ModuleSource::Inline { source, module_path, kind } => { + let mut parser = ModuleParser::new(Some(kind)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_str(Some(module_path.as_path()), source, source_manager) + }, + } + } +} + // PRE-PROCESSING // ================================================================================================ @@ -67,7 +111,7 @@ fn main() -> Result<()> { compile_agglayer_lib(&source_dir, &target_dir, TransactionKernel::assembler())?; let mut assembler = TransactionKernel::assembler(); - assembler.link_static_library(agglayer_lib)?; + assembler.link_package(Arc::new(agglayer_lib), Linkage::Static)?; // compile account components (thin wrappers per component) and return their libraries let component_libraries = compile_account_components( @@ -112,14 +156,15 @@ fn compile_agglayer_lib( // Add the miden-standards library to the assembler so agglayer components can use it let standards_lib = miden_standards::StandardsLib::default(); - assembler.link_static_library(standards_lib)?; + assembler.link_package(Arc::new(standards_lib.into()), Linkage::Static)?; - let agglayer_lib = assembler.assemble_library_from_dir(source_dir, "agglayer")?; + let agglayer_lib = + assemble_library_from_dir(assembler, "agglayer", source_dir, MasmPath::new("agglayer"))?; - let output_file = target_dir.join("agglayer").with_extension(Library::LIBRARY_EXTENSION); + let output_file = target_dir.join("agglayer").with_extension(Library::EXTENSION); agglayer_lib.write_to_file(output_file).into_diagnostic()?; - Ok(Arc::unwrap_or_clone(agglayer_lib)) + Ok(agglayer_lib) } // COMPILE EXECUTABLE MODULES @@ -139,11 +184,26 @@ fn compile_note_scripts( // Add the miden-standards library to the assembler so note scripts can use it let standards_lib = miden_standards::StandardsLib::default(); - assembler.link_static_library(standards_lib)?; + assembler.link_package(Arc::new(standards_lib.into()), Linkage::Static)?; for note_file_path in shared::get_masm_files(source_dir).unwrap() { + let note_file_stem = note_file_path + .file_stem() + .expect("file stem should exist") + .to_str() + .ok_or_else(|| Report::msg("failed to convert file stem to &str"))?; + let note_module_path = + miden_assembly::PathBuf::new(&format!("agglayer::note_scripts::{note_file_stem}")) + .into_diagnostic()?; + let root = ModuleSource::File { + file_path: note_file_path.clone(), + module_path: note_module_path, + kind: ast::ModuleKind::Library, + }; + // compile the note script library from the provided MASM file - let note_library = assembler.clone().assemble_library([note_file_path.clone()])?; + let note_library = + assembler.clone().assemble_library("note-script", root, None::)?; let note_file_name = note_file_path .file_name() @@ -151,7 +211,7 @@ fn compile_note_scripts( .to_str() .ok_or_else(|| Report::msg("failed to convert file name to &str"))?; let mut masl_file_path = note_scripts_target_dir.join(note_file_name); - masl_file_path.set_extension(Library::LIBRARY_EXTENSION); + masl_file_path.set_extension(Library::EXTENSION); // write the note script library to the output dir note_library @@ -193,26 +253,164 @@ fn compile_account_components( .expect("file stem should be valid UTF-8") .to_owned(); - let component_source_code = fs::read_to_string(&masm_file_path) - .expect("reading the component's MASM source code should succeed"); - - let named_source = NamedSource::new(component_name.clone(), component_source_code); + let component_path = miden_assembly::PathBuf::new(&component_name).into_diagnostic()?; + let root = ModuleSource::File { + file_path: masm_file_path.clone(), + module_path: component_path, + kind: ast::ModuleKind::Library, + }; let component_library = assembler .clone() - .assemble_library([named_source]) + .assemble_library(component_name.as_str(), root, None::<&str>) .expect("library assembly should succeed"); let component_file_path = - target_dir.join(&component_name).with_extension(Library::LIBRARY_EXTENSION); + target_dir.join(&component_name).with_extension(Library::EXTENSION); component_library.write_to_file(&component_file_path).into_diagnostic()?; - component_libraries.push((component_name, Arc::unwrap_or_clone(component_library))); + component_libraries.push((component_name, *component_library)); } Ok(component_libraries) } +// HELPERS +// ================================================================================================ + +fn assemble_library_from_dir( + assembler: Assembler, + name: impl Into, + dir: impl AsRef, + namespace: &MasmPath, +) -> Result { + let mut modules = read_modules_from_dir(dir, namespace, ast::ModuleKind::Library)?; + let root = modules.remove(0); + assembler.assemble_library(name.into(), root, modules).map(|package| *package) +} + +fn read_modules_from_dir( + dir: impl AsRef, + namespace: &MasmPath, + kind: ast::ModuleKind, +) -> Result> { + let dir = dir.as_ref(); + let real_files = shared::get_masm_files(dir)?.into_iter().collect::>(); + let mut modules = synthetic_parent_modules(dir, namespace, &real_files, kind)?; + + let mut real_files = real_files; + real_files.sort(); + for file_path in real_files { + let module_path = module_path_from_file(dir, namespace, &file_path)?; + modules.push(ModuleSource::File { file_path, module_path, kind }); + } + + Ok(modules) +} + +fn synthetic_parent_modules( + root: &Path, + namespace: &MasmPath, + real_files: &[std::path::PathBuf], + kind: ast::ModuleKind, +) -> Result> { + let mut children_by_dir = BTreeMap::>::new(); + let mut dirs_with_real_mod = BTreeSet::::new(); + + for file_path in real_files { + let relative = file_path.strip_prefix(root).into_diagnostic()?; + let parent = relative.parent().unwrap_or(Path::new("")).to_path_buf(); + let stem = file_path + .file_stem() + .expect("masm file should have a stem") + .to_string_lossy() + .to_string(); + + if stem == "mod" { + dirs_with_real_mod.insert(parent.clone()); + } else { + children_by_dir.entry(parent).or_default().insert(stem); + } + + let mut ancestor = std::path::PathBuf::new(); + for component in relative.parent().unwrap_or(Path::new("")).components() { + let child = component.as_os_str().to_string_lossy().to_string(); + children_by_dir.entry(ancestor.clone()).or_default().insert(child.clone()); + ancestor.push(child); + } + } + + let mut modules = Vec::new(); + if let Some(children) = children_by_dir.remove(Path::new("")) + && !dirs_with_real_mod.contains(Path::new("")) + { + modules.push(ModuleSource::Inline { + source: synthetic_parent_source(children), + module_path: miden_assembly::PathBuf::new(&namespace.to_string()).into_diagnostic()?, + kind, + }); + } + + for (relative_dir, children) in children_by_dir { + if dirs_with_real_mod.contains(&relative_dir) { + continue; + } + let module_path = module_path_from_relative_dir(namespace, &relative_dir)?; + modules.push(ModuleSource::Inline { + source: synthetic_parent_source(children), + module_path, + kind, + }); + } + + Ok(modules) +} + +fn synthetic_parent_source(children: BTreeSet) -> String { + let mut contents = String::new(); + for child in children { + contents.push_str("pub mod "); + contents.push_str(&child); + contents.push('\n'); + } + contents +} + +fn module_path_from_relative_dir( + namespace: &MasmPath, + relative_dir: &Path, +) -> Result { + let mut parts = namespace.to_string(); + + for component in relative_dir { + parts.push_str("::"); + parts.push_str(component.to_string_lossy().as_ref()); + } + + miden_assembly::PathBuf::new(&parts).into_diagnostic() +} + +fn module_path_from_file( + root: &Path, + namespace: &MasmPath, + file_path: &Path, +) -> Result { + let relative = file_path.strip_prefix(root).into_diagnostic()?; + let mut parts = namespace.to_string(); + + for component in relative { + let component = component.to_string_lossy(); + let component = component.strip_suffix(".masm").unwrap_or(&component); + if component == "mod" { + continue; + } + parts.push_str("::"); + parts.push_str(component); + } + + miden_assembly::PathBuf::new(&parts).into_diagnostic() +} + // GENERATE AGGLAYER CONSTANTS // ================================================================================================ @@ -469,7 +667,7 @@ fn ensure_canonical_zeros(target_dir: &Path) -> Result<()> { // remove once CANONICAL_ZEROS advice map is available zero_constants.push_str( " -use ::agglayer::common::utils::mem_store_double_word +use {mem_store_double_word} from ::agglayer::common::utils #! Inputs: [zeros_ptr] @@ -514,7 +712,7 @@ mod shared { use fs_err as fs; use miden_assembly::Report; - use miden_assembly::diagnostics::{IntoDiagnostic, Result, WrapErr}; + use miden_assembly::diagnostics::{IntoDiagnostic, Result}; use regex::Regex; use walkdir::WalkDir; @@ -526,12 +724,9 @@ mod shared { let path = dir_path.as_ref(); if path.is_dir() { - let entries = fs::read_dir(path) - .into_diagnostic() - .wrap_err_with(|| format!("failed to read directory {}", path.display()))?; - for entry in entries { - let file = entry.into_diagnostic().wrap_err("failed to read directory entry")?; - let file_path = file.path(); + for entry in WalkDir::new(path) { + let entry = entry.into_diagnostic()?; + let file_path = entry.path().to_path_buf(); if is_masm_file(&file_path).into_diagnostic()? { files.push(file_path); } diff --git a/crates/miden-agglayer/src/b2agg_note.rs b/crates/miden-agglayer/src/b2agg_note.rs index fbd614ae7a..7d54b246c6 100644 --- a/crates/miden-agglayer/src/b2agg_note.rs +++ b/crates/miden-agglayer/src/b2agg_note.rs @@ -5,10 +5,9 @@ use alloc::vec::Vec; -use miden_assembly::Library; -use miden_assembly::serde::Deserializable; use miden_core::Felt; use miden_protocol::account::AccountId; +use miden_protocol::assembly::Library; use miden_protocol::crypto::rand::FeltRng; use miden_protocol::errors::NoteError; use miden_protocol::note::{ @@ -23,6 +22,7 @@ use miden_protocol::note::{ NoteType, PartialNoteMetadata, }; +use miden_protocol::utils::serde::Deserializable; use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint}; use miden_utils_sync::LazyLock; @@ -33,7 +33,7 @@ use crate::EthAddress; // Initialize the B2AGG note script only once static B2AGG_SCRIPT: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/b2agg.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/b2agg.masp")); let library = Library::read_from_bytes(bytes).expect("shipped B2AGG script library is well-formed"); NoteScript::from_library(&library).expect("shipped B2AGG script is well-formed") diff --git a/crates/miden-agglayer/src/claim_note.rs b/crates/miden-agglayer/src/claim_note.rs index 405c3969b8..7ad76c1b21 100644 --- a/crates/miden-agglayer/src/claim_note.rs +++ b/crates/miden-agglayer/src/claim_note.rs @@ -1,10 +1,9 @@ use alloc::vec; use alloc::vec::Vec; -use miden_assembly::Library; -use miden_assembly::serde::Deserializable; use miden_core::{Felt, Word}; use miden_protocol::account::AccountId; +use miden_protocol::assembly::Library; use miden_protocol::crypto::SequentialCommit; use miden_protocol::crypto::rand::FeltRng; use miden_protocol::errors::NoteError; @@ -20,6 +19,7 @@ use miden_protocol::note::{ NoteType, PartialNoteMetadata, }; +use miden_protocol::utils::serde::Deserializable; use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint}; use miden_utils_sync::LazyLock; @@ -31,7 +31,7 @@ use crate::{EthAddress, EthAmount, GlobalIndex, MetadataHash}; // Initialize the CLAIM note script only once static CLAIM_SCRIPT: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/claim.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/claim.masp")); let library = Library::read_from_bytes(bytes).expect("shipped CLAIM script library is well-formed"); NoteScript::from_library(&library).expect("shipped CLAIM script is well-formed") diff --git a/crates/miden-agglayer/src/config_note.rs b/crates/miden-agglayer/src/config_note.rs index c672a2aced..a3b35ebe04 100644 --- a/crates/miden-agglayer/src/config_note.rs +++ b/crates/miden-agglayer/src/config_note.rs @@ -9,10 +9,9 @@ use alloc::string::ToString; use alloc::vec; use alloc::vec::Vec; -use miden_assembly::Library; -use miden_assembly::serde::Deserializable; use miden_core::Felt; use miden_protocol::account::AccountId; +use miden_protocol::assembly::Library; use miden_protocol::crypto::rand::FeltRng; use miden_protocol::errors::NoteError; use miden_protocol::note::{ @@ -27,6 +26,7 @@ use miden_protocol::note::{ NoteType, PartialNoteMetadata, }; +use miden_protocol::utils::serde::Deserializable; use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint}; use miden_utils_sync::LazyLock; @@ -38,7 +38,7 @@ use crate::{EthAddress, MetadataHash}; // Initialize the CONFIG_AGG_BRIDGE note script only once static CONFIG_AGG_BRIDGE_SCRIPT: LazyLock = LazyLock::new(|| { let bytes = - include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/config_agg_bridge.masl")); + include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/config_agg_bridge.masp")); let library = Library::read_from_bytes(bytes) .expect("shipped CONFIG_AGG_BRIDGE script library is well-formed"); NoteScript::from_library(&library).expect("shipped CONFIG_AGG_BRIDGE script is well-formed") diff --git a/crates/miden-agglayer/src/lib.rs b/crates/miden-agglayer/src/lib.rs index 3fab13acc9..d3fa60e42c 100644 --- a/crates/miden-agglayer/src/lib.rs +++ b/crates/miden-agglayer/src/lib.rs @@ -2,11 +2,11 @@ extern crate alloc; -use miden_assembly::Library; -use miden_assembly::serde::Deserializable; use miden_core::{Felt, Word}; use miden_protocol::account::{Account, AccountBuilder, AccountComponent, AccountId, AccountType}; +use miden_protocol::assembly::Library; use miden_protocol::asset::TokenSymbol; +use miden_protocol::utils::serde::Deserializable; use miden_standards::account::access::{Authority, Ownable2Step}; use miden_standards::account::auth::AuthNetworkAccount; use miden_standards::account::policies::{ @@ -65,17 +65,17 @@ pub use utils::Keccak256Output; // ================================================================================================ static AGGLAYER_LIBRARY: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/agglayer.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/agglayer.masp")); Library::read_from_bytes(bytes).expect("shipped AggLayer library is well-formed") }); static BRIDGE_COMPONENT_LIBRARY: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/components/bridge.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/components/bridge.masp")); Library::read_from_bytes(bytes).expect("shipped bridge component library is well-formed") }); static FAUCET_COMPONENT_LIBRARY: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/components/faucet.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/components/faucet.masp")); Library::read_from_bytes(bytes).expect("shipped faucet component library is well-formed") }); diff --git a/crates/miden-agglayer/src/remove_ger_note.rs b/crates/miden-agglayer/src/remove_ger_note.rs index 828d159648..e361c430bf 100644 --- a/crates/miden-agglayer/src/remove_ger_note.rs +++ b/crates/miden-agglayer/src/remove_ger_note.rs @@ -4,12 +4,12 @@ //! which are used to remove a Global Exit Root from the bridge account and fold it into the //! running removed-GER keccak256 hash chain. -use miden_assembly::Library; -use miden_assembly::serde::Deserializable; use miden_protocol::account::AccountId; +use miden_protocol::assembly::Library; use miden_protocol::crypto::rand::FeltRng; use miden_protocol::errors::NoteError; use miden_protocol::note::{Note, NoteScript, NoteScriptRoot}; +use miden_protocol::utils::serde::Deserializable; use miden_utils_sync::LazyLock; use crate::ExitRoot; @@ -20,7 +20,7 @@ use crate::ger_note::create_ger_note; // Initialize the REMOVE_GER note script only once static REMOVE_GER_SCRIPT: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/remove_ger.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/remove_ger.masp")); let library = Library::read_from_bytes(bytes).expect("shipped REMOVE_GER script library is well-formed"); NoteScript::from_library(&library).expect("shipped REMOVE_GER script is well-formed") diff --git a/crates/miden-agglayer/src/update_ger_note.rs b/crates/miden-agglayer/src/update_ger_note.rs index ad5189862c..8b486bf83a 100644 --- a/crates/miden-agglayer/src/update_ger_note.rs +++ b/crates/miden-agglayer/src/update_ger_note.rs @@ -3,12 +3,12 @@ //! This module provides helpers for creating UPDATE_GER notes, //! which are used to update the Global Exit Root in the bridge account. -use miden_assembly::Library; -use miden_assembly::serde::Deserializable; use miden_protocol::account::AccountId; +use miden_protocol::assembly::Library; use miden_protocol::crypto::rand::FeltRng; use miden_protocol::errors::NoteError; use miden_protocol::note::{Note, NoteScript, NoteScriptRoot}; +use miden_protocol::utils::serde::Deserializable; use miden_utils_sync::LazyLock; use crate::ExitRoot; @@ -19,7 +19,7 @@ use crate::ger_note::create_ger_note; // Initialize the UPDATE_GER note script only once static UPDATE_GER_SCRIPT: LazyLock = LazyLock::new(|| { - let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/update_ger.masl")); + let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/update_ger.masp")); let library = Library::read_from_bytes(bytes).expect("shipped UPDATE_GER script library is well-formed"); NoteScript::from_library(&library).expect("shipped UPDATE_GER script is well-formed") diff --git a/crates/miden-protocol/Cargo.toml b/crates/miden-protocol/Cargo.toml index 695d757d69..98172e469d 100644 --- a/crates/miden-protocol/Cargo.toml +++ b/crates/miden-protocol/Cargo.toml @@ -31,7 +31,7 @@ std = [ "miden-processor/std", "miden-verifier/std", ] -testing = ["dep:rand_chacha", "dep:rand_xoshiro", "miden-core/testing", "miden-crypto/std"] +testing = ["dep:rand_chacha", "dep:rand_xoshiro", "miden-core/testing", "miden-crypto/std", "rand/thread_rng"] [dependencies] # Miden dependencies @@ -49,7 +49,7 @@ miden-verifier = { workspace = true } # External dependencies bech32 = { default-features = false, features = ["alloc"], version = "0.11" } rand = { workspace = true } -rand_xoshiro = { default-features = false, optional = true, version = "0.7" } +rand_xoshiro = { default-features = false, optional = true, version = "0.8" } semver = { features = ["serde"], version = "1.0" } serde = { features = ["derive"], optional = true, workspace = true } thiserror = { workspace = true } @@ -58,7 +58,7 @@ toml = { optional = true, version = "1.0" } rand_chacha = { optional = true, workspace = true } [target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { features = ["wasm_js"], version = "0.3" } +getrandom = { features = ["wasm_js"], version = "0.4" } [dev-dependencies] anyhow = { features = ["backtrace", "std"], workspace = true } @@ -70,12 +70,13 @@ rstest = { workspace = true } tempfile = { version = "3.19" } [build-dependencies] -fs-err = { workspace = true } -miden-assembly = { workspace = true } -miden-core = { workspace = true } -miden-core-lib = { workspace = true } -regex = { workspace = true } -walkdir = { workspace = true } +fs-err = { workspace = true } +miden-assembly = { workspace = true } +miden-assembly-syntax = { workspace = true } +miden-core = { workspace = true } +miden-core-lib = { workspace = true } +regex = { workspace = true } +walkdir = { workspace = true } [package.metadata.cargo-shear] ignored = ["getrandom"] diff --git a/crates/miden-protocol/asm/kernels/transaction/api.masm b/crates/miden-protocol/asm/kernels/transaction/api.masm index 0b6fb8ac10..0dbec41f1c 100644 --- a/crates/miden-protocol/asm/kernels/transaction/api.masm +++ b/crates/miden-protocol/asm/kernels/transaction/api.masm @@ -1,18 +1,30 @@ -use $kernel::asset -use $kernel::account -use $kernel::account_update -use $kernel::account_id -use $kernel::faucet -use $kernel::input_note -use $kernel::memory -use $kernel::output_note -use $kernel::tx - -use $kernel::memory::UPCOMING_FOREIGN_PROCEDURE_PTR -use $kernel::memory::UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR -use $kernel::memory::KERNEL_PROCEDURES_PTR +pub mod account +pub mod account_id +pub mod account_update +pub mod asset +pub mod asset_vault +pub mod callbacks +pub mod constants +pub mod epilogue +pub mod faucet +pub mod fungible_asset +pub mod input_note +pub mod link_map +pub mod memory +pub mod non_fungible_asset +pub mod note +pub mod output_note +pub mod prologue +pub mod tx +mod types +mod util use miden::core::word +use { + KERNEL_PROCEDURES_PTR, + UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR, + UPCOMING_FOREIGN_PROCEDURE_PTR, +} from $kernel::memory pub type AccountId = struct { prefix: felt, suffix: felt } @@ -1536,7 +1548,7 @@ pub proc tx_prepare_fpi(foreign_account_id: AccountId, foreign_proc_root: word, # => [foreign_proc_input_value_15, pad(15)] # store the 16th value of the foreign procedure inputs - mem_store.UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR + push.UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR mem_store # => [pad(16)] end @@ -1566,7 +1578,7 @@ pub proc tx_exec_foreign_proc # => [pad, foreign_procedure_inputs(15)] # load the 16th foreign procedure input value onto the stack - mem_load.UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR + push.UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR mem_load # => [foreign_proc_input_value_15, pad, foreign_procedure_inputs(15)] # drop the excess pad and move the 16th inputs value to its 15th position @@ -1590,7 +1602,7 @@ pub proc tx_exec_foreign_proc # => [foreign_proc_root_ptr, foreign_procedure_inputs(16)] # check that the foreign procedure root is not zero - padw mem_loadw_le.UPCOMING_FOREIGN_PROCEDURE_PTR + padw push.UPCOMING_FOREIGN_PROCEDURE_PTR mem_loadw_le # => [FOREIGN_PROC_ROOT, foreign_proc_root_ptr, foreign_procedure_inputs(16)] exec.word::eqz assertz.err=ERR_FOREIGN_ACCOUNT_PROCEDURE_ROOT_IS_ZERO diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/account.masm b/crates/miden-protocol/asm/kernels/transaction/lib/account.masm index 7bbf57d4fb..0a3d9ba010 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/account.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/account.masm @@ -2,18 +2,7 @@ use $kernel::account_update use $kernel::account_id use $kernel::asset_vault use $kernel::callbacks -use $kernel::callbacks::ON_BEFORE_ASSET_ADDED_TO_ACCOUNT_PROC_ROOT_SLOT -use $kernel::callbacks::ON_BEFORE_ASSET_ADDED_TO_NOTE_PROC_ROOT_SLOT -use $kernel::constants::ACCOUNT_PROCEDURE_DATA_LENGTH -use $kernel::constants::EMPTY_SMT_ROOT -use $kernel::constants::STORAGE_SLOT_TYPE_MAP -use $kernel::constants::STORAGE_SLOT_TYPE_VALUE use $kernel::memory -use $kernel::memory::ACCT_ID_SUFFIX_OFFSET -use $kernel::memory::ACCT_ID_PREFIX_OFFSET -use $kernel::memory::ACCOUNT_DATA_LENGTH -use $kernel::memory::MAX_FOREIGN_ACCOUNT_PTR -use $kernel::memory::NATIVE_ACCOUNT_DATA_PTR use miden::core::collections::smt use miden::core::collections::sorted_array use miden::core::crypto::hashes::poseidon2 @@ -88,9 +77,18 @@ const ACCOUNT_TREE_DEPTH=64 # The number of field elements it takes to store one account storage slot. const ACCOUNT_STORAGE_SLOT_DATA_LENGTH=8 +# The number of field elements in a serialized account procedure digest. +const ACCOUNT_PROCEDURE_DATA_LENGTH=4 + # The offset of the slot type in the storage slot. const ACCOUNT_SLOT_TYPE_OFFSET=1 +# The storage slot type for value slots. +const STORAGE_SLOT_TYPE_VALUE=0 + +# The storage slot type for map slots. +const STORAGE_SLOT_TYPE_MAP=1 + # The offset of the slot's ID suffix in the storage slot. const ACCOUNT_SLOT_ID_SUFFIX_OFFSET=2 @@ -100,6 +98,30 @@ const ACCOUNT_SLOT_ID_PREFIX_OFFSET=3 # The offset of the slot value in the storage slot. const ACCOUNT_SLOT_VALUE_OFFSET=4 +# The root of an empty SMT. +const EMPTY_SMT_ROOT=[3975378004049472045, 2532873049833957132, 2640800763532531478, 11158234471980764993] + +# The offset of the account ID suffix in account data. +const ACCT_ID_SUFFIX_OFFSET=2 + +# The offset of the account ID prefix in account data. +const ACCT_ID_PREFIX_OFFSET=3 + +# The number of field elements in account data. +const ACCOUNT_DATA_LENGTH=8192 + +# The pointer at which native account data starts. +const NATIVE_ACCOUNT_DATA_PTR=8192 + +# The maximum pointer at which foreign account data may start. +const MAX_FOREIGN_ACCOUNT_PTR=524288 + +# The digest of the `on_before_asset_added_to_account` callback. +const ON_BEFORE_ASSET_ADDED_TO_ACCOUNT_PROC_ROOT_SLOT=word("miden::protocol::faucet::callback::on_before_asset_added_to_account") + +# The digest of the `on_before_asset_added_to_note` callback. +const ON_BEFORE_ASSET_ADDED_TO_NOTE_PROC_ROOT_SLOT=word("miden::protocol::faucet::callback::on_before_asset_added_to_note") + # EVENTS # ================================================================================================= @@ -172,23 +194,23 @@ end # ID AND NONCE # ------------------------------------------------------------------------------------------------- -#! Returns the id of the active account. -#! -#! Inputs: [] -#! Outputs: [act_acct_id_prefix, act_acct_id_suffix] -#! -#! Where: -#! - act_acct_id_{prefix,suffix} are the prefix and suffix felts of the ID of the active account. -pub use memory::get_account_id->get_id - -#! Returns the nonce of the active account. -#! -#! Inputs: [] -#! Outputs: [nonce] -#! -#! Where: -#! - nonce is the account nonce. -pub use memory::get_account_nonce->get_nonce +# Returns the id of the active account. +# +# Inputs: [] +# Outputs: [act_acct_id_prefix, act_acct_id_suffix] +# +# Where: +# - act_acct_id_{prefix,suffix} are the prefix and suffix felts of the ID of the active account. +pub use {get_account_id as get_id} from $kernel::memory + +# Returns the nonce of the active account. +# +# Inputs: [] +# Outputs: [nonce] +# +# Where: +# - nonce is the account nonce. +pub use {get_account_nonce as get_nonce} from $kernel::memory #! Increments the native account's nonce by one and returns the new nonce. #! @@ -292,14 +314,14 @@ end ### CODE COMMITMENT ###################################################### -#! Gets the code commitment of the active account. -#! -#! Inputs: [] -#! Outputs: [CODE_COMMITMENT] -#! -#! Where: -#! - CODE_COMMITMENT is the commitment of the account code. -pub use memory::get_account_code_commitment->get_code_commitment +# Gets the code commitment of the active account. +# +# Inputs: [] +# Outputs: [CODE_COMMITMENT] +# +# Where: +# - CODE_COMMITMENT is the commitment of the account code. +pub use {get_account_code_commitment as get_code_commitment} from $kernel::memory ### STORAGE COMMITMENT ################################################### diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/account_update.masm b/crates/miden-protocol/asm/kernels/transaction/lib/account_update.masm index cbbd58019c..e1c980b59f 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/account_update.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/account_update.masm @@ -1,11 +1,7 @@ use $kernel::account use $kernel::asset -use $kernel::asset::COMPOSITION_NONE -use $kernel::constants::STORAGE_SLOT_TYPE_VALUE -use $kernel::asset::ASSET_SIZE use $kernel::link_map use $kernel::memory -use $kernel::memory::ACCOUNT_UPDATE_ASSET_PTR use miden::core::crypto::hashes::poseidon2 use miden::core::word @@ -39,6 +35,18 @@ const DOMAIN_VALUE = 5 # The domain of a map storage slot in the delta commitment. const DOMAIN_MAP = 6 +#! The number of field elements in an asset. +const ASSET_SIZE = 8 + +#! The asset composition for assets which cannot be merged or split. +const COMPOSITION_NONE = 0 + +#! The storage slot type for value slots. +const STORAGE_SLOT_TYPE_VALUE = 0 + +#! The pointer at which the account update asset map starts. +const ACCOUNT_UPDATE_ASSET_PTR = 532480 + #! The default delta operation indicating no change. const DELTA_OP_NONE = 0 diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/asset.masm b/crates/miden-protocol/asm/kernels/transaction/lib/asset.masm index 403b68b19e..42819e53b7 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/asset.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/asset.masm @@ -1,7 +1,7 @@ use $kernel::account_id use $kernel::fungible_asset use $kernel::non_fungible_asset -use $kernel::util::asset->util_asset +use $kernel::util::asset as util_asset # ERRORS # ================================================================================================= @@ -17,21 +17,23 @@ const ERR_VAULT_LT_COMPOSITION_NONE="assets with composition none cannot be comp # CONSTANT ACCESSORS # ================================================================================================= -pub use $kernel::util::asset::FUNGIBLE_ASSET_MAX_AMOUNT -pub use $kernel::util::asset::ASSET_SIZE -pub use $kernel::util::asset::ASSET_VALUE_MEMORY_OFFSET -pub use $kernel::util::asset::COMPOSITION_NONE -pub use $kernel::util::asset::COMPOSITION_FUNGIBLE -pub use $kernel::util::asset::COMPOSITION_CUSTOM -pub use $kernel::util::asset::key_to_faucet_id -pub use $kernel::util::asset::key_into_faucet_id -pub use $kernel::util::asset::key_to_asset_id -pub use $kernel::util::asset::key_into_asset_id -pub use $kernel::util::asset::key_to_callbacks_enabled -pub use $kernel::util::asset::key_to_composition -pub use $kernel::util::asset::store -pub use $kernel::util::asset::load -pub use $kernel::util::asset::validate_metadata +pub use { + FUNGIBLE_ASSET_MAX_AMOUNT, + ASSET_SIZE, + ASSET_VALUE_MEMORY_OFFSET, + COMPOSITION_NONE, + COMPOSITION_FUNGIBLE, + COMPOSITION_CUSTOM, + key_to_faucet_id, + key_into_faucet_id, + key_to_asset_id, + key_into_asset_id, + key_to_callbacks_enabled, + key_to_composition, + store, + load, + validate_metadata, +} from $kernel::util::asset # PROCEDURES # ================================================================================================= diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/constants.masm b/crates/miden-protocol/asm/kernels/transaction/lib/constants.masm index 5293b915ee..1b86b3032e 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/constants.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/constants.masm @@ -1,7 +1,7 @@ # CONSTANTS # ================================================================================================= -pub use $kernel::util::constants::WORD_NUM_ELEMENTS +pub use {WORD_NUM_ELEMENTS} from $kernel::util::constants # The maximum number of storage items associated with a single note. pub const MAX_NOTE_STORAGE_ITEMS = 1024 diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/epilogue.masm b/crates/miden-protocol/asm/kernels/transaction/lib/epilogue.masm index b4df666bd0..f239a0bfbc 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/epilogue.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/epilogue.masm @@ -1,12 +1,8 @@ use $kernel::account use $kernel::account_update use $kernel::asset -use $kernel::asset::ASSET_SIZE use $kernel::asset_vault -use $kernel::constants::NOTE_MEM_SIZE use $kernel::memory -use $kernel::memory::OUTPUT_NOTE_SECTION_OFFSET -use $kernel::memory::OUTPUT_VAULT_ROOT_PTR use $kernel::note use miden::core::crypto::hashes::poseidon2 @@ -35,6 +31,18 @@ const EPILOGUE_AUTH_PROC_START_EVENT=event("miden::protocol::epilogue::auth_proc # Event emitted to signal that an execution of the authentication procedure has ended. const EPILOGUE_AUTH_PROC_END_EVENT=event("miden::protocol::epilogue::auth_proc_end") +# The number of field elements in an asset. +const ASSET_SIZE=8 + +# The size of the memory segment allocated to each note. +const NOTE_MEM_SIZE=1024 + +# The pointer at which the output vault root starts. +const OUTPUT_VAULT_ROOT_PTR=8 + +# The offset of the output note section. +const OUTPUT_NOTE_SECTION_OFFSET=16777216 + # OUTPUT NOTES PROCEDURES # ================================================================================================= diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/faucet.masm b/crates/miden-protocol/asm/kernels/transaction/lib/faucet.masm index b0117c0d24..b75c35fae4 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/faucet.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/faucet.masm @@ -3,7 +3,9 @@ use $kernel::asset use $kernel::asset_vault use $kernel::fungible_asset use $kernel::non_fungible_asset -use $kernel::memory::INPUT_VAULT_ROOT_PTR + +# The pointer at which the input vault root starts. +const INPUT_VAULT_ROOT_PTR=4 # FUNGIBLE ASSETS # ================================================================================================== diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/fungible_asset.masm b/crates/miden-protocol/asm/kernels/transaction/lib/fungible_asset.masm index 5532dc3c06..499d77072f 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/fungible_asset.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/fungible_asset.masm @@ -1,16 +1,18 @@ # Contains procedures for the built-in fungible asset. use $kernel::account_id -use $kernel::util::asset::FUNGIBLE_ASSET_MAX_AMOUNT use $kernel::asset # RE-EXPORTS # ================================================================================================= -pub use $kernel::util::asset::create_fungible_key->create_key -pub use $kernel::util::asset::create_fungible_asset_unchecked->create_unchecked -pub use $kernel::util::asset::fungible_to_amount->to_amount -pub use $kernel::util::asset::fungible_value_into_amount->value_into_amount +pub use { + create_fungible_key as create_key, + create_fungible_asset_unchecked as create_unchecked, + FUNGIBLE_ASSET_MAX_AMOUNT, + fungible_to_amount as to_amount, + fungible_value_into_amount as value_into_amount +} from $kernel::util::asset # ERRORS # ================================================================================================= diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/link_map.masm b/crates/miden-protocol/asm/kernels/transaction/lib/link_map.masm index 39876016c3..30c6d5ee9b 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/link_map.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/link_map.masm @@ -1,8 +1,10 @@ use miden::core::word -use $kernel::memory -use $kernel::memory::LINK_MAP_ENTRY_SIZE -use $kernel::memory::LINK_MAP_REGION_END_PTR -use $kernel::memory::LINK_MAP_REGION_START_PTR +pub use { + LINK_MAP_ENTRY_SIZE, + LINK_MAP_REGION_END_PTR, + LINK_MAP_REGION_START_PTR, + link_map_malloc, +} from $kernel::memory # A link map is a map data structure based on a sorted linked list. # @@ -438,7 +440,7 @@ end #! Panics if: #! - the KEY is not less than the key in the head of the map, unless the map is empty. proc insert_at_head - exec.memory::link_map_malloc + exec.link_map_malloc # => [entry_ptr, map_ptr, KEY, VALUE0, VALUE1] dup movdn.14 @@ -535,7 +537,7 @@ proc insert_after_entry movup.4 # => [map_ptr, KEY, VALUE0, VALUE1, prev_entry_ptr] - exec.memory::link_map_malloc + exec.link_map_malloc # => [entry_ptr, map_ptr, KEY, VALUE0, VALUE1, prev_entry_ptr] dup movdn.14 diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/memory.masm b/crates/miden-protocol/asm/kernels/transaction/lib/memory.masm index 8369638ebc..d96aed124c 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/memory.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/memory.masm @@ -1,8 +1,10 @@ -use $kernel::constants::ACCOUNT_PROCEDURE_DATA_LENGTH -use $kernel::constants::MAX_ASSETS_PER_NOTE -use $kernel::constants::NOTE_MEM_SIZE -use $kernel::constants::WORD_NUM_ELEMENTS use miden::core::mem +use { + ACCOUNT_PROCEDURE_DATA_LENGTH, + MAX_ASSETS_PER_NOTE, + NOTE_MEM_SIZE, + WORD_NUM_ELEMENTS, +} from $kernel::constants pub type AccountId = struct { prefix: felt, suffix: felt } diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/note.masm b/crates/miden-protocol/asm/kernels/transaction/lib/note.masm index 448f3a66ae..aedb283f9c 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/note.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/note.masm @@ -1,16 +1,17 @@ use miden::core::crypto::hashes::poseidon2 -use $kernel::asset::ASSET_SIZE -use $kernel::constants::NOTE_MEM_SIZE -use $kernel::constants::WORD_NUM_ELEMENTS +use {ASSET_SIZE} from $kernel::asset +use {NOTE_MEM_SIZE, WORD_NUM_ELEMENTS} from $kernel::constants use $kernel::memory -pub use $kernel::util::note::NOTE_TYPE_PUBLIC -pub use $kernel::util::note::NOTE_TYPE_PRIVATE -pub use $kernel::util::note::MAX_ATTACHMENT_SCHEME -pub use $kernel::util::note::MAX_ATTACHMENT_WORDS -pub use $kernel::util::note::MAX_ATTACHMENT_TOTAL_WORDS -pub use $kernel::util::note::ATTACHMENT_SCHEME_NONE +pub use { + ATTACHMENT_SCHEME_NONE, + MAX_ATTACHMENT_SCHEME, + MAX_ATTACHMENT_TOTAL_WORDS, + MAX_ATTACHMENT_WORDS, + NOTE_TYPE_PRIVATE, + NOTE_TYPE_PUBLIC, +} from $kernel::util::note # ERRORS # ================================================================================================= diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/output_note.masm b/crates/miden-protocol/asm/kernels/transaction/lib/output_note.masm index 3b65ae9516..d59fccd615 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/output_note.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/output_note.masm @@ -1,18 +1,18 @@ use $kernel::account use $kernel::asset +use {ASSET_SIZE, ASSET_VALUE_MEMORY_OFFSET} from $kernel::asset use $kernel::callbacks use $kernel::fungible_asset use $kernel::memory use $kernel::note -use $kernel::note::NOTE_TYPE_PUBLIC -use $kernel::note::MAX_ATTACHMENT_SCHEME -use $kernel::note::MAX_ATTACHMENT_WORDS -use $kernel::note::MAX_ATTACHMENT_TOTAL_WORDS -use $kernel::constants::MAX_OUTPUT_NOTES_PER_TX -use $kernel::constants::WORD_NUM_ELEMENTS -use $kernel::util::note::NOTE_METADATA_VERSION_1 -use $kernel::asset::ASSET_SIZE -use $kernel::asset::ASSET_VALUE_MEMORY_OFFSET +use {MAX_OUTPUT_NOTES_PER_TX, WORD_NUM_ELEMENTS} from $kernel::constants +use { + MAX_ATTACHMENT_SCHEME, + MAX_ATTACHMENT_TOTAL_WORDS, + MAX_ATTACHMENT_WORDS, + NOTE_METADATA_VERSION_1, + NOTE_TYPE_PUBLIC, +} from $kernel::util::note use miden::core::word use miden::core::mem diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/prologue.masm b/crates/miden-protocol/asm/kernels/transaction/lib/prologue.masm index f4bc84c615..9fd451cfa4 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/prologue.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/prologue.masm @@ -6,18 +6,22 @@ use miden::core::word use $kernel::account use $kernel::account_id use $kernel::asset_vault -use $kernel::asset::ASSET_SIZE use $kernel::asset -use $kernel::constants::EMPTY_SMT_ROOT -use $kernel::constants::MAX_ASSETS_PER_NOTE -use $kernel::constants::MAX_INPUT_NOTES_PER_TX -use $kernel::constants::MAX_NOTE_STORAGE_ITEMS -use $kernel::constants::NOTE_TREE_DEPTH +use {ASSET_SIZE} from $kernel::asset +use { + EMPTY_SMT_ROOT, + MAX_ASSETS_PER_NOTE, + MAX_INPUT_NOTES_PER_TX, + MAX_NOTE_STORAGE_ITEMS, + NOTE_TREE_DEPTH, +} from $kernel::constants use $kernel::memory -use $kernel::memory::BLOCK_DATA_SECTION_OFFSET -use $kernel::memory::INPUT_VAULT_ROOT_PTR -use $kernel::memory::KERNEL_PROCEDURES_PTR -use $kernel::memory::PARTIAL_BLOCKCHAIN_PTR +use { + BLOCK_DATA_SECTION_OFFSET, + INPUT_VAULT_ROOT_PTR, + KERNEL_PROCEDURES_PTR, + PARTIAL_BLOCKCHAIN_PTR, +} from $kernel::memory # CONSTS # ================================================================================================= diff --git a/crates/miden-protocol/asm/kernels/transaction/lib/tx.masm b/crates/miden-protocol/asm/kernels/transaction/lib/tx.masm index fe49d70823..8a697b8657 100644 --- a/crates/miden-protocol/asm/kernels/transaction/lib/tx.masm +++ b/crates/miden-protocol/asm/kernels/transaction/lib/tx.masm @@ -1,6 +1,5 @@ use $kernel::account use $kernel::memory -use $kernel::note # CONSTANTS # ================================================================================================= @@ -19,81 +18,81 @@ const ERR_TX_INVALID_EXPIRATION_DELTA="transaction expiration block delta must b # PROCEDURES # ================================================================================================= -#! Returns the block commitment of the transaction reference block. -#! -#! Inputs: [] -#! Outputs: [BLOCK_COMMITMENT] -#! -#! Where: -#! - BLOCK_COMMITMENT is the commitment of the transaction reference block. -pub use memory::get_block_commitment - -#! Returns the block number of the transaction reference block. -#! -#! Inputs: [] -#! Outputs: [num] -#! -#! Where: -#! - num is the transaction reference block number. -pub use memory::get_blk_num->get_block_number - -#! Returns the block timestamp of the reference block for this transaction. -#! -#! Inputs: [] -#! Outputs: [timestamp] -#! -#! Where: -#! - timestamp is the timestamp of the reference block for this transaction. -pub use memory::get_blk_timestamp->get_block_timestamp - -#! Returns the input notes commitment hash. -#! -#! See `transaction::api::get_input_notes_commitment` for details. -#! -#! Inputs: [] -#! Outputs: [INPUT_NOTES_COMMITMENT] -#! -#! Where: -#! - INPUT_NOTES_COMMITMENT is the input notes commitment hash. -pub use memory::get_input_notes_commitment - -#! Returns the output notes commitment hash. This is computed as a sequential hash of -#! (note_details_commitment, note_metadata_commitment) tuples over all output notes. -#! -#! Inputs: [] -#! Outputs: [OUTPUT_NOTES_COMMITMENT] -#! -#! Where: -#! - OUTPUT_NOTES_COMMITMENT is the output notes commitment. -pub use note::compute_output_notes_commitment->get_output_notes_commitment - -#! Returns the total number of input notes consumed by this transaction. -#! -#! Inputs: [] -#! Outputs: [num_input_notes] -#! -#! Where: -#! - num_input_notes is the total number of input notes consumed by this transaction. -pub use memory::get_num_input_notes - -#! Returns the current number of output notes created in this transaction. -#! -#! Inputs: [] -#! Outputs: [num_output_notes] -#! -#! Where: -#! - num_output_notes is the number of output notes created in this transaction so far. -pub use memory::get_num_output_notes - -#! Returns the transaction script root. -#! -#! Inputs: [] -#! Outputs: [TX_SCRIPT_ROOT] -#! -#! Where: -#! - TX_SCRIPT_ROOT is the transaction script root, or the empty word if no transaction script was -#! executed. -pub use memory::get_tx_script_root +# Returns the block commitment of the transaction reference block. +# +# Inputs: [] +# Outputs: [BLOCK_COMMITMENT] +# +# Where: +# - BLOCK_COMMITMENT is the commitment of the transaction reference block. +pub use {get_block_commitment} from $kernel::memory + +# Returns the block number of the transaction reference block. +# +# Inputs: [] +# Outputs: [num] +# +# Where: +# - num is the transaction reference block number. +pub use {get_blk_num as get_block_number} from $kernel::memory + +# Returns the block timestamp of the reference block for this transaction. +# +# Inputs: [] +# Outputs: [timestamp] +# +# Where: +# - timestamp is the timestamp of the reference block for this transaction. +pub use {get_blk_timestamp as get_block_timestamp} from $kernel::memory + +# Returns the input notes commitment hash. +# +# See `transaction::api::get_input_notes_commitment` for details. +# +# Inputs: [] +# Outputs: [INPUT_NOTES_COMMITMENT] +# +# Where: +# - INPUT_NOTES_COMMITMENT is the input notes commitment hash. +pub use {get_input_notes_commitment} from $kernel::memory + +# Returns the output notes commitment hash. This is computed as a sequential hash of +# (note_details_commitment, note_metadata_commitment) tuples over all output notes. +# +# Inputs: [] +# Outputs: [OUTPUT_NOTES_COMMITMENT] +# +# Where: +# - OUTPUT_NOTES_COMMITMENT is the output notes commitment. +pub use {compute_output_notes_commitment as get_output_notes_commitment} from $kernel::note + +# Returns the total number of input notes consumed by this transaction. +# +# Inputs: [] +# Outputs: [num_input_notes] +# +# Where: +# - num_input_notes is the total number of input notes consumed by this transaction. +pub use {get_num_input_notes} from $kernel::memory + +# Returns the current number of output notes created in this transaction. +# +# Inputs: [] +# Outputs: [num_output_notes] +# +# Where: +# - num_output_notes is the number of output notes created in this transaction so far. +pub use {get_num_output_notes} from $kernel::memory + +# Returns the transaction script root. +# +# Inputs: [] +# Outputs: [TX_SCRIPT_ROOT] +# +# Where: +# - TX_SCRIPT_ROOT is the transaction script root, or the empty word if no transaction script was +# executed. +pub use {get_tx_script_root} from $kernel::memory #! Updates the transaction expiration block delta. #! diff --git a/crates/miden-protocol/asm/kernels/transaction/main.masm b/crates/miden-protocol/asm/kernels/transaction/main.masm index c11a29f202..1edde6e3e9 100644 --- a/crates/miden-protocol/asm/kernels/transaction/main.masm +++ b/crates/miden-protocol/asm/kernels/transaction/main.masm @@ -2,10 +2,12 @@ use miden::core::word use $kernel::epilogue use $kernel::memory -use $kernel::memory::TX_SCRIPT_ROOT_PTR use $kernel::note use $kernel::prologue +# The pointer at which the transaction script root starts. +const TX_SCRIPT_ROOT_PTR=428 + # EVENTS # ================================================================================================= diff --git a/crates/miden-protocol/asm/kernels/transaction/tx_script_main.masm b/crates/miden-protocol/asm/kernels/transaction/tx_script_main.masm index 958427842c..ff00c5da57 100644 --- a/crates/miden-protocol/asm/kernels/transaction/tx_script_main.masm +++ b/crates/miden-protocol/asm/kernels/transaction/tx_script_main.masm @@ -1,8 +1,10 @@ use miden::core::word -use $kernel::memory::TX_SCRIPT_ROOT_PTR use $kernel::prologue +# The pointer at which the transaction script root starts. +const TX_SCRIPT_ROOT_PTR=428 + # ERRORS # ================================================================================================= diff --git a/crates/miden-protocol/asm/protocol/active_account.masm b/crates/miden-protocol/asm/protocol/active_account.masm index 6a5ecbcfbc..a64fcebb7c 100644 --- a/crates/miden-protocol/asm/protocol/active_account.masm +++ b/crates/miden-protocol/asm/protocol/active_account.masm @@ -1,25 +1,26 @@ use miden::protocol::asset -use miden::protocol::asset::COMPOSITION_FUNGIBLE -use miden::protocol::asset::COMPOSITION_NONE -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_ID_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_NONCE_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_INITIAL_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_COMPUTE_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_CODE_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_INITIAL_STORAGE_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_COMPUTE_STORAGE_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_INITIAL_VAULT_ROOT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_VAULT_ROOT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_ITEM_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_HAS_STORAGE_SLOT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_INITIAL_ITEM_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_MAP_ITEM_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_INITIAL_MAP_ITEM_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_INITIAL_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_NUM_PROCEDURES_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_PROCEDURE_ROOT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_HAS_PROCEDURE_OFFSET +use {COMPOSITION_FUNGIBLE, COMPOSITION_NONE} from miden::protocol::asset +use { + ACCOUNT_GET_ID_OFFSET, + ACCOUNT_GET_NONCE_OFFSET, + ACCOUNT_GET_INITIAL_COMMITMENT_OFFSET, + ACCOUNT_COMPUTE_COMMITMENT_OFFSET, + ACCOUNT_GET_CODE_COMMITMENT_OFFSET, + ACCOUNT_GET_INITIAL_STORAGE_COMMITMENT_OFFSET, + ACCOUNT_COMPUTE_STORAGE_COMMITMENT_OFFSET, + ACCOUNT_GET_INITIAL_VAULT_ROOT_OFFSET, + ACCOUNT_GET_VAULT_ROOT_OFFSET, + ACCOUNT_GET_ITEM_OFFSET, + ACCOUNT_HAS_STORAGE_SLOT_OFFSET, + ACCOUNT_GET_INITIAL_ITEM_OFFSET, + ACCOUNT_GET_MAP_ITEM_OFFSET, + ACCOUNT_GET_INITIAL_MAP_ITEM_OFFSET, + ACCOUNT_GET_ASSET_OFFSET, + ACCOUNT_GET_INITIAL_ASSET_OFFSET, + ACCOUNT_GET_NUM_PROCEDURES_OFFSET, + ACCOUNT_GET_PROCEDURE_ROOT_OFFSET, + ACCOUNT_HAS_PROCEDURE_OFFSET, +} from miden::protocol::kernel_proc_offsets use miden::core::word # ACTIVE ACCOUNT PROCEDURES @@ -699,4 +700,3 @@ pub proc has_procedure swapw.3 dropw dropw dropw movdn.3 drop drop drop # => [is_procedure_available] end - diff --git a/crates/miden-protocol/asm/protocol/active_note.masm b/crates/miden-protocol/asm/protocol/active_note.masm index fa272cbec4..7fb67f4e8c 100644 --- a/crates/miden-protocol/asm/protocol/active_note.masm +++ b/crates/miden-protocol/asm/protocol/active_note.masm @@ -1,16 +1,17 @@ use miden::core::crypto::hashes::poseidon2 use miden::core::mem -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_ASSETS_INFO_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_RECIPIENT_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_STORAGE_INFO_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_METADATA_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_SERIAL_NUMBER_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_SCRIPT_ROOT_OFFSET +use { + INPUT_NOTE_GET_ASSETS_INFO_OFFSET, + INPUT_NOTE_GET_METADATA_OFFSET, + INPUT_NOTE_GET_RECIPIENT_OFFSET, + INPUT_NOTE_GET_SCRIPT_ROOT_OFFSET, + INPUT_NOTE_GET_SERIAL_NUMBER_OFFSET, + INPUT_NOTE_GET_STORAGE_INFO_OFFSET, +} from miden::protocol::kernel_proc_offsets use miden::protocol::note use miden::protocol::input_note -use miden::protocol::util::note::NOTE_TYPE_PUBLIC -use miden::protocol::util::note::NOTE_TYPE_PRIVATE +use {NOTE_TYPE_PRIVATE, NOTE_TYPE_PUBLIC} from miden::protocol::util::note # ERRORS # ================================================================================================= diff --git a/crates/miden-protocol/asm/protocol/asset.masm b/crates/miden-protocol/asm/protocol/asset.masm index 3812f59956..53e7343b87 100644 --- a/crates/miden-protocol/asm/protocol/asset.masm +++ b/crates/miden-protocol/asm/protocol/asset.masm @@ -3,25 +3,27 @@ use miden::protocol::util::asset # RE-EXPORTS # ================================================================================================= -pub use miden::protocol::util::asset::FUNGIBLE_ASSET_MAX_AMOUNT -pub use miden::protocol::util::asset::ASSET_SIZE -pub use miden::protocol::util::asset::ASSET_VALUE_MEMORY_OFFSET -pub use miden::protocol::util::asset::key_to_faucet_id -pub use miden::protocol::util::asset::key_into_faucet_id -pub use miden::protocol::util::asset::key_to_asset_id -pub use miden::protocol::util::asset::key_into_asset_id -pub use miden::protocol::util::asset::non_fungible_value_into_asset_id -pub use miden::protocol::util::asset::key_to_callbacks_enabled -pub use miden::protocol::util::asset::key_to_composition -pub use miden::protocol::util::asset::COMPOSITION_NONE -pub use miden::protocol::util::asset::COMPOSITION_FUNGIBLE -pub use miden::protocol::util::asset::COMPOSITION_CUSTOM -pub use miden::protocol::util::asset::store -pub use miden::protocol::util::asset::load -pub use miden::protocol::util::asset::fungible_value_into_amount -pub use miden::protocol::util::asset::fungible_to_amount -pub use miden::protocol::util::asset::create_fungible_key -pub use miden::protocol::util::asset::create_non_fungible_asset_unchecked->create_non_fungible_asset +pub use { + ASSET_SIZE, + ASSET_VALUE_MEMORY_OFFSET, + COMPOSITION_CUSTOM, + COMPOSITION_FUNGIBLE, + COMPOSITION_NONE, + FUNGIBLE_ASSET_MAX_AMOUNT, + create_fungible_key, + create_non_fungible_asset_unchecked as create_non_fungible_asset, + fungible_to_amount, + fungible_value_into_amount, + key_into_asset_id, + key_into_faucet_id, + key_to_asset_id, + key_to_callbacks_enabled, + key_to_composition, + key_to_faucet_id, + load, + non_fungible_value_into_asset_id, + store, +} from miden::protocol::util::asset # ERRORS # ================================================================================================= diff --git a/crates/miden-protocol/asm/protocol/faucet.masm b/crates/miden-protocol/asm/protocol/faucet.masm index 84d04a7c40..78ff803e3a 100644 --- a/crates/miden-protocol/asm/protocol/faucet.masm +++ b/crates/miden-protocol/asm/protocol/faucet.masm @@ -1,8 +1,10 @@ use miden::protocol::asset use miden::protocol::active_account -use miden::protocol::kernel_proc_offsets::FAUCET_MINT_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::FAUCET_BURN_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::FAUCET_HAS_CALLBACKS_OFFSET +use { + FAUCET_BURN_ASSET_OFFSET, + FAUCET_HAS_CALLBACKS_OFFSET, + FAUCET_MINT_ASSET_OFFSET, +} from miden::protocol::kernel_proc_offsets #! Creates a fungible asset for the faucet the transaction is being executed against. #! diff --git a/crates/miden-protocol/asm/protocol/input_note.masm b/crates/miden-protocol/asm/protocol/input_note.masm index 984e480b94..7b50028a3b 100644 --- a/crates/miden-protocol/asm/protocol/input_note.masm +++ b/crates/miden-protocol/asm/protocol/input_note.masm @@ -1,10 +1,12 @@ -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_ASSETS_INFO_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_RECIPIENT_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_METADATA_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_STORAGE_INFO_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_SCRIPT_ROOT_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_SERIAL_NUMBER_OFFSET -use miden::protocol::kernel_proc_offsets::INPUT_NOTE_GET_ATTACHMENTS_COMMITMENT_OFFSET +use { + INPUT_NOTE_GET_ASSETS_INFO_OFFSET, + INPUT_NOTE_GET_ATTACHMENTS_COMMITMENT_OFFSET, + INPUT_NOTE_GET_METADATA_OFFSET, + INPUT_NOTE_GET_RECIPIENT_OFFSET, + INPUT_NOTE_GET_SCRIPT_ROOT_OFFSET, + INPUT_NOTE_GET_SERIAL_NUMBER_OFFSET, + INPUT_NOTE_GET_STORAGE_INFO_OFFSET, +} from miden::protocol::kernel_proc_offsets use miden::protocol::note # PROCEDURES diff --git a/crates/miden-protocol/asm/protocol/native_account.masm b/crates/miden-protocol/asm/protocol/native_account.masm index 78680135ef..866525e1dc 100644 --- a/crates/miden-protocol/asm/protocol/native_account.masm +++ b/crates/miden-protocol/asm/protocol/native_account.masm @@ -1,11 +1,11 @@ -use miden::protocol::kernel_proc_offsets::ACCOUNT_GET_ID_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_INCR_NONCE_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_COMPUTE_DELTA_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_SET_ITEM_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_SET_MAP_ITEM_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_ADD_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_REMOVE_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::ACCOUNT_WAS_PROCEDURE_CALLED_OFFSET +use {ACCOUNT_GET_ID_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_INCR_NONCE_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_COMPUTE_DELTA_COMMITMENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_SET_ITEM_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_SET_MAP_ITEM_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_ADD_ASSET_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_REMOVE_ASSET_OFFSET} from miden::protocol::kernel_proc_offsets +use {ACCOUNT_WAS_PROCEDURE_CALLED_OFFSET} from miden::protocol::kernel_proc_offsets # NATIVE ACCOUNT PROCEDURES # ================================================================================================= diff --git a/crates/miden-protocol/asm/protocol/note.masm b/crates/miden-protocol/asm/protocol/note.masm index a5df9127f7..3cd3f7d45f 100644 --- a/crates/miden-protocol/asm/protocol/note.masm +++ b/crates/miden-protocol/asm/protocol/note.masm @@ -1,16 +1,16 @@ use miden::protocol::account_id -use miden::protocol::util::constants::WORD_NUM_ELEMENTS +use {WORD_NUM_ELEMENTS} from miden::protocol::util::constants use miden::core::crypto::hashes::poseidon2 use miden::core::mem # Re-export the max inputs per note constant. -pub use miden::protocol::util::note::MAX_NOTE_STORAGE_ITEMS -pub use miden::protocol::util::note::NOTE_TYPE_PUBLIC -pub use miden::protocol::util::note::NOTE_TYPE_PRIVATE -pub use miden::protocol::util::note::MAX_ATTACHMENT_SCHEME -pub use miden::protocol::util::note::MAX_ATTACHMENT_WORDS -pub use miden::protocol::util::note::MAX_ATTACHMENT_TOTAL_WORDS -pub use miden::protocol::util::note::ATTACHMENT_SCHEME_NONE +pub use {MAX_NOTE_STORAGE_ITEMS} from miden::protocol::util::note +pub use {NOTE_TYPE_PUBLIC} from miden::protocol::util::note +pub use {NOTE_TYPE_PRIVATE} from miden::protocol::util::note +pub use {MAX_ATTACHMENT_SCHEME} from miden::protocol::util::note +pub use {MAX_ATTACHMENT_WORDS} from miden::protocol::util::note +pub use {MAX_ATTACHMENT_TOTAL_WORDS} from miden::protocol::util::note +pub use {ATTACHMENT_SCHEME_NONE} from miden::protocol::util::note # ERRORS # ================================================================================================= diff --git a/crates/miden-protocol/asm/protocol/output_note.masm b/crates/miden-protocol/asm/protocol/output_note.masm index ae202f7873..f6b0cc7085 100644 --- a/crates/miden-protocol/asm/protocol/output_note.masm +++ b/crates/miden-protocol/asm/protocol/output_note.masm @@ -1,11 +1,11 @@ -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_CREATE_OFFSET -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_GET_ASSETS_INFO_OFFSET -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_ADD_ASSET_OFFSET -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_ADD_ATTACHMENT_OFFSET -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_GET_RECIPIENT_OFFSET -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_GET_METADATA_OFFSET -use miden::protocol::kernel_proc_offsets::OUTPUT_NOTE_GET_ATTACHMENTS_COMMITMENT_OFFSET -use miden::protocol::util::constants::WORD_NUM_ELEMENTS +use {OUTPUT_NOTE_CREATE_OFFSET} from miden::protocol::kernel_proc_offsets +use {OUTPUT_NOTE_GET_ASSETS_INFO_OFFSET} from miden::protocol::kernel_proc_offsets +use {OUTPUT_NOTE_ADD_ASSET_OFFSET} from miden::protocol::kernel_proc_offsets +use {OUTPUT_NOTE_ADD_ATTACHMENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {OUTPUT_NOTE_GET_RECIPIENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {OUTPUT_NOTE_GET_METADATA_OFFSET} from miden::protocol::kernel_proc_offsets +use {OUTPUT_NOTE_GET_ATTACHMENTS_COMMITMENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {WORD_NUM_ELEMENTS} from miden::protocol::util::constants use miden::protocol::note use miden::core::crypto::hashes::poseidon2 diff --git a/crates/miden-protocol/asm/protocol/tx.masm b/crates/miden-protocol/asm/protocol/tx.masm index 06df0413df..294358bb91 100644 --- a/crates/miden-protocol/asm/protocol/tx.masm +++ b/crates/miden-protocol/asm/protocol/tx.masm @@ -1,15 +1,15 @@ -use miden::protocol::kernel_proc_offsets::TX_GET_BLOCK_NUMBER_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_BLOCK_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_BLOCK_TIMESTAMP_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_INPUT_NOTES_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_OUTPUT_NOTES_COMMITMENT_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_NUM_INPUT_NOTES_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_NUM_OUTPUT_NOTES_OFFSET -use miden::protocol::kernel_proc_offsets::TX_PREPARE_FPI_OFFSET -use miden::protocol::kernel_proc_offsets::TX_EXEC_FOREIGN_PROC_OFFSET -use miden::protocol::kernel_proc_offsets::TX_UPDATE_EXPIRATION_BLOCK_DELTA_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_EXPIRATION_DELTA_OFFSET -use miden::protocol::kernel_proc_offsets::TX_GET_TX_SCRIPT_ROOT_OFFSET +use {TX_GET_BLOCK_NUMBER_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_BLOCK_COMMITMENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_BLOCK_TIMESTAMP_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_INPUT_NOTES_COMMITMENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_OUTPUT_NOTES_COMMITMENT_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_NUM_INPUT_NOTES_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_NUM_OUTPUT_NOTES_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_PREPARE_FPI_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_EXEC_FOREIGN_PROC_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_UPDATE_EXPIRATION_BLOCK_DELTA_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_EXPIRATION_DELTA_OFFSET} from miden::protocol::kernel_proc_offsets +use {TX_GET_TX_SCRIPT_ROOT_OFFSET} from miden::protocol::kernel_proc_offsets #! Returns the block number of the transaction reference block. #! diff --git a/crates/miden-protocol/asm/shared_utils/util/mod.masm b/crates/miden-protocol/asm/shared_utils/util/mod.masm new file mode 100644 index 0000000000..61c71729ef --- /dev/null +++ b/crates/miden-protocol/asm/shared_utils/util/mod.masm @@ -0,0 +1,3 @@ +pub mod asset +pub mod constants +pub mod note diff --git a/crates/miden-protocol/benches/account_seed.rs b/crates/miden-protocol/benches/account_seed.rs index 1f67d1fad5..71970da65e 100644 --- a/crates/miden-protocol/benches/account_seed.rs +++ b/crates/miden-protocol/benches/account_seed.rs @@ -3,7 +3,7 @@ use std::time::Duration; use criterion::{Criterion, criterion_group, criterion_main}; use miden_protocol::Word; use miden_protocol::account::{AccountId, AccountIdVersion, AccountType}; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; /// Running this benchmark with --no-default-features will use the single-threaded account seed /// computation. diff --git a/crates/miden-protocol/build.rs b/crates/miden-protocol/build.rs index a252bb7527..370998aebc 100644 --- a/crates/miden-protocol/build.rs +++ b/crates/miden-protocol/build.rs @@ -1,11 +1,22 @@ use std::collections::{BTreeMap, BTreeSet}; use std::env; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::Arc; use fs_err as fs; use miden_assembly::diagnostics::{IntoDiagnostic, Result, WrapErr, miette}; -use miden_assembly::{Assembler, DefaultSourceManager, KernelLibrary, Library}; +use miden_assembly::package::{Package, PackageExport}; +use miden_assembly::{ + Assembler, + DefaultSourceManager, + Linkage, + ModuleParser, + Path as MasmPath, + Report, + SourceManager, + ast, +}; +use miden_assembly_syntax::Parse; use miden_core::events::EventId; use regex::Regex; use walkdir::WalkDir; @@ -48,6 +59,40 @@ const TX_KERNEL_ERROR_CATEGORIES: [&str; 14] = [ "OUTPUT_NOTE", ]; +enum ModuleSource { + File { + file_path: std::path::PathBuf, + module_path: miden_assembly::PathBuf, + kind: ast::ModuleKind, + }, + Inline { + source: String, + module_path: miden_assembly::PathBuf, + kind: ast::ModuleKind, + }, +} + +impl Parse for ModuleSource { + fn parse( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> std::result::Result, Report> { + match self { + ModuleSource::File { file_path, module_path, kind } => { + let mut parser = ModuleParser::new(Some(kind)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_file(Some(module_path.as_path()), file_path, source_manager) + }, + ModuleSource::Inline { source, module_path, kind } => { + let mut parser = ModuleParser::new(Some(kind)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_str(Some(module_path.as_path()), source, source_manager) + }, + } + } +} + // PRE-PROCESSING // ================================================================================================ @@ -71,6 +116,7 @@ fn main() -> Result<()> { // copy the shared modules to the kernel and protocol library folders copy_shared_modules(&source_dir)?; + mirror_kernel_library_modules(&source_dir.join(ASM_TX_KERNEL_DIR))?; // set target directory to {OUT_DIR}/assets let target_dir = Path::new(&build_dir).join(ASSETS_DIR); @@ -84,7 +130,7 @@ fn main() -> Result<()> { // compile protocol library let protocol_lib = compile_protocol_lib(&source_dir, &target_dir, assembler.clone())?; - assembler.link_dynamic_library(protocol_lib)?; + assembler.link_package(Arc::new(protocol_lib), Linkage::Dynamic)?; // compile batch kernel compile_batch_kernel(&source_dir, &target_dir.join("kernels"))?; @@ -106,7 +152,10 @@ fn compile_batch_kernel(source_dir: &Path, target_dir: &Path) -> Result<()> { let main_file_path = batch_kernel_dir.join("main.masm"); let assembler = build_assembler(None)?; - let batch_main = assembler.assemble_program(main_file_path)?; + let batch_main = assembler + .assemble_program("batch-kernel", main_file_path)? + .try_into_program() + .map_err(|err| Report::msg(format!("{err:#}")))?; let masb_file_path = target_dir.join("batch_kernel.masb"); batch_main.write_to_file(masb_file_path).into_diagnostic() @@ -137,33 +186,33 @@ fn compile_batch_kernel(source_dir: &Path, target_dir: &Path) -> Result<()> { /// tx_script_main.masm. /// - src/transaction/procedures/kernel_v0.rs -> contains the kernel procedures table. fn compile_tx_kernel(source_dir: &Path, target_dir: &Path, build_dir: &str) -> Result { - let shared_utils_path = std::path::Path::new(ASM_DIR).join(SHARED_UTILS_DIR); - let kernel_path = miden_assembly::Path::kernel_path(); - - let mut assembler = build_assembler(None)?; - // add the shared util modules to the kernel lib under the ::$kernel::util namespace - assembler.compile_and_statically_link_from_dir(&shared_utils_path, kernel_path)?; + let assembler = build_assembler(None)?; // assemble the kernel library and write it to the "tx_kernel.masl" file - let kernel_lib = assembler - .assemble_kernel_from_dir(source_dir.join("api.masm"), Some(source_dir.join("lib")))?; + let kernel_lib = assemble_kernel_from_dir( + assembler, + "tx-kernel", + source_dir.join("api.masm"), + source_dir.join("lib"), + )?; // generate kernel `procedures.rs` file - generate_kernel_proc_hash_file(kernel_lib.clone(), build_dir)?; + generate_kernel_proc_hash_file(&kernel_lib, build_dir)?; - let output_file = target_dir.join("tx_kernel").with_extension(Library::LIBRARY_EXTENSION); + let output_file = target_dir.join("tx_kernel.masl"); kernel_lib.write_to_file(output_file).into_diagnostic()?; let assembler = build_assembler(Some(kernel_lib))?; // assemble the kernel program and write it to the "tx_kernel.masb" file - let mut main_assembler = assembler.clone(); - // add the shared util modules to the kernel lib under the ::$kernel::util namespace - main_assembler.compile_and_statically_link_from_dir(&shared_utils_path, kernel_path)?; - main_assembler.compile_and_statically_link_from_dir(source_dir.join("lib"), kernel_path)?; + let main_assembler = assembler.clone(); let main_file_path = source_dir.join("main.masm"); - let kernel_main = main_assembler.clone().assemble_program(main_file_path)?; + let kernel_main = main_assembler + .clone() + .assemble_program("tx-kernel-main", main_file_path)? + .try_into_program() + .map_err(|err| Report::msg(format!("{err:#}")))?; let masb_file_path = target_dir.join("tx_kernel.masb"); kernel_main.write_to_file(masb_file_path).into_diagnostic()?; @@ -173,22 +222,20 @@ fn compile_tx_kernel(source_dir: &Path, target_dir: &Path, build_dir: &str) -> R #[cfg(any(feature = "testing", test))] { - let mut kernel_lib_assembler = assembler.clone(); + let kernel_lib_assembler = build_assembler(None)?; // Build kernel as a library and save it to file. // This is needed in test assemblers to access individual procedures which would otherwise // be hidden when using KernelLibrary (api.masm) - // add the shared util modules to the kernel lib under the ::$kernel::util namespace - kernel_lib_assembler - .compile_and_statically_link_from_dir(&shared_utils_path, kernel_path)?; - - let test_lib = kernel_lib_assembler - .assemble_library_from_dir(source_dir.join("lib"), kernel_path) - .unwrap(); + let test_lib = assemble_library_from_dir( + kernel_lib_assembler, + "tx-kernel-library", + source_dir.join("lib"), + MasmPath::kernel_path(), + )?; - let masb_file_path = - target_dir.join("kernel_library").with_extension(Library::LIBRARY_EXTENSION); - (*test_lib).write_to_file(masb_file_path).into_diagnostic()?; + let masb_file_path = target_dir.join("kernel_library.masl"); + test_lib.write_to_file(masb_file_path).into_diagnostic()?; } Ok(assembler) @@ -204,7 +251,10 @@ fn compile_tx_script_main( // assemble the transaction script executor program and write it to the "tx_script_main.masb" // file. let tx_script_main_file_path = source_dir.join("tx_script_main.masm"); - let tx_script_main = main_assembler.assemble_program(tx_script_main_file_path)?; + let tx_script_main = main_assembler + .assemble_program("tx-script-main", tx_script_main_file_path)? + .try_into_program() + .map_err(|err| Report::msg(format!("{err:#}")))?; let masb_file_path = target_dir.join("tx_script_main.masb"); tx_script_main.write_to_file(masb_file_path).into_diagnostic() @@ -213,27 +263,61 @@ fn compile_tx_script_main( /// Generates kernel `procedures.rs` file based on the kernel library. /// /// The file is written to `{build_dir}/procedures.rs` and included via `include!` in the source. -fn generate_kernel_proc_hash_file(kernel: KernelLibrary, build_dir: &str) -> Result<()> { - let (_, module_info, _) = kernel.into_parts(); - +fn generate_kernel_proc_hash_file(kernel: &Package, build_dir: &str) -> Result<()> { let to_exclude = BTreeSet::from_iter(["exec_kernel_proc"]); let offsets_filename = Path::new(ASM_DIR).join(ASM_PROTOCOL_DIR).join("kernel_proc_offsets.masm"); let offsets = parse_proc_offsets(&offsets_filename)?; - let generated_procs: BTreeMap = module_info - .procedures() - .filter(|(_, proc_info)| !to_exclude.contains::(proc_info.name.as_ref())) - .map(|(_, proc_info)| { - let name = proc_info.name.to_string(); + // Only `$kernel::api::` exports are dynamic kernel API procedures. Public support + // modules also appear in package exports as `$kernel::api::::`, but those are + // not invoked through `exec_kernel_proc` and therefore do not belong in `KERNEL_PROCEDURES`. + let kernel_api_exports: Vec<_> = kernel + .manifest + .exports() + .filter_map(|export| match export { + PackageExport::Procedure(proc_info) => Some(proc_info), + _ => None, + }) + .filter(|proc_info| proc_info.path.len() == 3) + .collect(); - let Some(&offset) = offsets.get(&name) else { - panic!("Offset constant for function `{name}` not found in `{offsets_filename:?}`"); - }; + for proc_info in kernel_api_exports.iter() { + let name = proc_info.path.last().unwrap(); + if to_exclude.contains::(name) { + continue; + } - (offset, format!(" // {name}\n word!(\"{}\"),", proc_info.digest)) + if !offsets.contains_key(name) { + return Err(miette::miette!( + "Offset constant for kernel procedure `{}` not found in `{offsets_filename:?}`", + proc_info.path, + )); + } + } + + let generated_procs: BTreeMap = offsets + .iter() + .map(|(name, &offset)| { + let mut matching_exports = + kernel_api_exports.iter().filter(|proc_info| proc_info.path.last().unwrap() == name); + let proc_info = matching_exports.next().ok_or_else(|| { + miette::miette!( + "Kernel procedure offset `{name}` in `{offsets_filename:?}` does not match any exported procedure" + ) + })?; + + if let Some(other_proc_info) = matching_exports.next() { + return Err(miette::miette!( + "Kernel procedure offset `{name}` in `{offsets_filename:?}` matches multiple exported procedures: `{}` and `{}`", + proc_info.path, + other_proc_info.path, + )); + } + + Ok((offset, format!(" // {name}\n word!(\"{}\"),", proc_info.digest))) }) - .collect(); + .collect::>()?; let proc_count = generated_procs.len(); let generated_procs: String = generated_procs.into_iter().enumerate().map(|(index, (offset, txt))| { @@ -289,34 +373,188 @@ fn parse_proc_offsets(filename: impl AsRef) -> Result Result { + assembler: Assembler, +) -> Result { let source_dir = source_dir.join(ASM_PROTOCOL_DIR); - let shared_path = Path::new(ASM_DIR).join(SHARED_UTILS_DIR); - - // add the shared modules to the protocol lib under the miden::protocol::util namespace - // note that this module is not publicly exported, it is only available for linking the library - // itself - assembler.compile_and_statically_link_from_dir(&shared_path, PROTOCOL_LIB_NAMESPACE)?; - let protocol_lib = assembler.assemble_library_from_dir(source_dir, PROTOCOL_LIB_NAMESPACE)?; + let protocol_lib = assemble_library_from_dir( + assembler, + "miden-protocol", + source_dir, + MasmPath::new(PROTOCOL_LIB_NAMESPACE), + )?; - let output_file = target_dir.join("protocol").with_extension(Library::LIBRARY_EXTENSION); + let output_file = target_dir.join("protocol.masl"); protocol_lib.write_to_file(output_file).into_diagnostic()?; - Ok(Arc::unwrap_or_clone(protocol_lib)) + Ok(protocol_lib) } // HELPER FUNCTIONS // ================================================================================================ /// Returns a new [Assembler] loaded with miden-core-lib and the specified kernel, if provided. -fn build_assembler(kernel: Option) -> Result { - kernel - .map(|kernel| Assembler::with_kernel(Arc::new(DefaultSourceManager::default()), kernel)) - .unwrap_or_default() - .with_warnings_as_errors(true) - .with_dynamic_library(miden_core_lib::CoreLibrary::default()) +fn build_assembler(kernel: Option) -> Result { + let source_manager = Arc::new(DefaultSourceManager::default()); + let mut assembler = if let Some(kernel) = kernel { + Assembler::with_kernel(source_manager, Arc::new(kernel))? + } else { + Assembler::new(source_manager) + } + .with_warnings_as_errors(true); + + assembler.link_package(miden_core_lib::CoreLibrary::default().package(), Linkage::Dynamic)?; + + Ok(assembler) +} + +fn assemble_library_from_dir( + assembler: Assembler, + name: impl Into, + dir: impl AsRef, + namespace: &MasmPath, +) -> Result { + let mut modules = read_modules_from_dir(dir, namespace, ast::ModuleKind::Library, true)?; + let root = modules.remove(0); + assembler.assemble_library(name.into(), root, modules).map(|package| *package) +} + +fn assemble_kernel_from_dir( + assembler: Assembler, + name: impl Into, + sys_module_path: impl AsRef, + _lib_dir: impl AsRef, +) -> Result { + assembler + .assemble_kernel_from_root(name.into(), sys_module_path) + .map(|package| *package) +} + +fn read_modules_from_dir( + dir: impl AsRef, + namespace: &MasmPath, + kind: ast::ModuleKind, + include_root: bool, +) -> Result> { + let dir = dir.as_ref(); + let real_files = shared::get_masm_files(dir)?.into_iter().collect::>(); + let mut modules = synthetic_parent_modules(dir, namespace, &real_files, kind, include_root)?; + + let mut real_files = real_files; + real_files.sort(); + for file_path in real_files { + let module_path = module_path_from_file(dir, namespace, &file_path)?; + modules.push(ModuleSource::File { file_path, module_path, kind }); + } + + Ok(modules) +} + +fn synthetic_parent_modules( + root: &Path, + namespace: &MasmPath, + real_files: &[std::path::PathBuf], + kind: ast::ModuleKind, + include_root: bool, +) -> Result> { + let mut children_by_dir = BTreeMap::>::new(); + let mut dirs_with_real_mod = BTreeSet::::new(); + + for file_path in real_files { + let relative = file_path.strip_prefix(root).into_diagnostic()?; + let parent = relative.parent().unwrap_or(Path::new("")).to_path_buf(); + let stem = file_path + .file_stem() + .expect("masm file should have a stem") + .to_string_lossy() + .to_string(); + + if stem == "mod" { + dirs_with_real_mod.insert(parent.clone()); + } else { + children_by_dir.entry(parent).or_default().insert(stem); + } + + let mut ancestor = std::path::PathBuf::new(); + for component in relative.parent().unwrap_or(Path::new("")).components() { + let child = component.as_os_str().to_string_lossy().to_string(); + children_by_dir.entry(ancestor.clone()).or_default().insert(child.clone()); + ancestor.push(child); + } + } + + let mut modules = Vec::new(); + if let Some(children) = children_by_dir.remove(Path::new("")) + && include_root + && !dirs_with_real_mod.contains(Path::new("")) + { + let module_path = miden_assembly::PathBuf::new(&namespace.to_string()).into_diagnostic()?; + modules.push(ModuleSource::Inline { + source: synthetic_parent_source(children), + module_path, + kind, + }); + } + + for (relative_dir, children) in children_by_dir { + if dirs_with_real_mod.contains(&relative_dir) { + continue; + } + + let module_path = module_path_from_relative_dir(namespace, &relative_dir)?; + modules.push(ModuleSource::Inline { + source: synthetic_parent_source(children), + module_path, + kind, + }); + } + + Ok(modules) +} + +fn synthetic_parent_source(children: BTreeSet) -> String { + let mut contents = String::new(); + for child in children { + contents.push_str("pub mod "); + contents.push_str(&child); + contents.push('\n'); + } + contents +} + +fn module_path_from_relative_dir( + namespace: &MasmPath, + relative_dir: &Path, +) -> Result { + let mut parts = namespace.to_string(); + + for component in relative_dir { + parts.push_str("::"); + parts.push_str(component.to_string_lossy().as_ref()); + } + + miden_assembly::PathBuf::new(&parts).into_diagnostic() +} + +fn module_path_from_file( + root: &Path, + namespace: &MasmPath, + file_path: &Path, +) -> Result { + let relative = file_path.strip_prefix(root).into_diagnostic()?; + let mut parts = namespace.to_string(); + + for component in relative { + let component = component.to_string_lossy(); + let component = component.strip_suffix(".masm").unwrap_or(&component); + if component == "mod" { + continue; + } + parts.push_str("::"); + parts.push_str(component); + } + + miden_assembly::PathBuf::new(&parts).into_diagnostic() } /// Copies the content of the build `shared_modules` folder to the `lib` and `protocol` build @@ -327,18 +565,40 @@ fn build_assembler(kernel: Option) -> Result { /// i.e. "use $kernel::account_id". fn copy_shared_modules>(source_dir: T) -> Result<()> { // source is expected to be an `OUT_DIR/asm` folder - let shared_modules_dir = source_dir.as_ref().join(SHARED_MODULES_DIR); + let source_dir = source_dir.as_ref(); + let shared_modules_dir = source_dir.join(SHARED_MODULES_DIR); + let kernel_lib_folder = source_dir.join(ASM_TX_KERNEL_DIR).join("lib"); + let protocol_lib_folder = source_dir.join(ASM_PROTOCOL_DIR); + + copy_masm_files( + &shared_modules_dir, + &[kernel_lib_folder.clone(), protocol_lib_folder.clone()], + )?; + + let shared_utils_dir = source_dir.join(SHARED_UTILS_DIR); + copy_masm_files(&shared_utils_dir, &[kernel_lib_folder, protocol_lib_folder])?; - for module_path in shared::get_masm_files(shared_modules_dir).unwrap() { - let module_name = module_path.file_name().unwrap(); + Ok(()) +} - // copy to kernel lib - let kernel_lib_folder = source_dir.as_ref().join(ASM_TX_KERNEL_DIR).join("lib"); - fs::copy(&module_path, kernel_lib_folder.join(module_name)).into_diagnostic()?; +fn mirror_kernel_library_modules(kernel_dir: &Path) -> Result<()> { + let lib_dir = kernel_dir.join("lib"); + copy_masm_files(&lib_dir, &[kernel_dir.to_path_buf()])?; - // copy to protocol lib - let protocol_lib_folder = source_dir.as_ref().join(ASM_PROTOCOL_DIR); - fs::copy(&module_path, protocol_lib_folder.join(module_name)).into_diagnostic()?; + Ok(()) +} + +fn copy_masm_files(source_dir: &Path, target_dirs: &[PathBuf]) -> Result<()> { + for module_path in shared::get_masm_files(source_dir).unwrap() { + let relative = module_path.strip_prefix(source_dir).into_diagnostic()?; + + for target_dir in target_dirs { + let target_path = target_dir.join(relative); + if let Some(parent) = target_path.parent() { + fs::create_dir_all(parent).into_diagnostic()?; + } + fs::copy(&module_path, target_path).into_diagnostic()?; + } } Ok(()) @@ -372,21 +632,12 @@ fn copy_shared_modules>(source_dir: T) -> Result<()> { /// The generated files are written to `build_dir` (i.e. `OUT_DIR`) and included via `include!` /// in the source. fn generate_error_constants(asm_source_dir: &Path, build_dir: &str) -> Result<()> { - // Shared utils errors - // For now these are duplicated in the tx kernel and protocol error module. - // ------------------------------------------ - - let shared_utils_dir = asm_source_dir.join(SHARED_UTILS_DIR); - let shared_utils_errors = shared::extract_all_masm_errors(&shared_utils_dir) - .context("failed to extract all masm errors")?; - // Transaction kernel errors // ------------------------------------------ let tx_kernel_dir = asm_source_dir.join(ASM_TX_KERNEL_DIR); - let mut errors = shared::extract_all_masm_errors(&tx_kernel_dir) + let errors = shared::extract_all_masm_errors(&tx_kernel_dir) .context("failed to extract all masm errors")?; - errors.extend_from_slice(&shared_utils_errors); validate_tx_kernel_category(&errors)?; shared::generate_error_file( @@ -402,9 +653,8 @@ fn generate_error_constants(asm_source_dir: &Path, build_dir: &str) -> Result<() // ------------------------------------------ let protocol_dir = asm_source_dir.join(ASM_PROTOCOL_DIR); - let mut errors = shared::extract_all_masm_errors(&protocol_dir) + let errors = shared::extract_all_masm_errors(&protocol_dir) .context("failed to extract all masm errors")?; - errors.extend(shared_utils_errors); shared::generate_error_file( shared::ErrorModule { diff --git a/crates/miden-protocol/src/account/account_id/account_type.rs b/crates/miden-protocol/src/account/account_id/account_type.rs index 1494621ff6..83054e374b 100644 --- a/crates/miden-protocol/src/account/account_id/account_type.rs +++ b/crates/miden-protocol/src/account/account_id/account_type.rs @@ -2,6 +2,9 @@ use alloc::string::String; use core::fmt; use core::str::FromStr; +#[cfg(any(feature = "testing", test))] +use rand::RngExt; + use crate::errors::AccountIdError; // ACCOUNT TYPE diff --git a/crates/miden-protocol/src/account/auth.rs b/crates/miden-protocol/src/account/auth.rs index 0665f2e16b..8dd6239132 100644 --- a/crates/miden-protocol/src/account/auth.rs +++ b/crates/miden-protocol/src/account/auth.rs @@ -127,7 +127,7 @@ impl AuthSecretKey { /// Generates an Falcon512Poseidon2 secrete key using the provided random number generator. pub fn new_falcon512_poseidon2_with_rng(rng: &mut R) -> Self { - Self::Falcon512Poseidon2(falcon512_poseidon2::SecretKey::with_rng(rng)) + Self::Falcon512Poseidon2(falcon512_poseidon2::SecretKey::with_rng::(rng)) } /// Generates an EcdsaK256Keccak secret key from the OS-provided randomness. @@ -138,7 +138,7 @@ impl AuthSecretKey { /// Generates an EcdsaK256Keccak secret key using the provided random number generator. pub fn new_ecdsa_k256_keccak_with_rng(rng: &mut R) -> Self { - Self::EcdsaK256Keccak(ecdsa_k256_keccak::SigningKey::with_rng(rng)) + Self::EcdsaK256Keccak(ecdsa_k256_keccak::SigningKey::with_rng::(rng)) } /// Generates a new secret key for the specified authentication scheme using the provided diff --git a/crates/miden-protocol/src/account/builder/mod.rs b/crates/miden-protocol/src/account/builder/mod.rs index 06e17ee067..d196755fbb 100644 --- a/crates/miden-protocol/src/account/builder/mod.rs +++ b/crates/miden-protocol/src/account/builder/mod.rs @@ -291,12 +291,14 @@ mod tests { use std::sync::{Arc, LazyLock}; use assert_matches::assert_matches; - use miden_assembly::{Assembler, Library}; + use miden_assembly::{DefaultSourceManager, ModuleParser, Path, ast}; use miden_core::mast::MastNodeExt; + use miden_mast_package::Package as Library; use super::*; use crate::account::component::AccountComponentMetadata; use crate::account::{AccountProcedureRoot, StorageSlot, StorageSlotName}; + use crate::assembly::Assembler; use crate::testing::noop_auth_component::NoopAuthComponent; const CUSTOM_CODE1: &str = " @@ -311,20 +313,23 @@ mod tests { "; static CUSTOM_LIBRARY1: LazyLock = LazyLock::new(|| { - Arc::unwrap_or_clone( - Assembler::default() - .assemble_library([CUSTOM_CODE1]) - .expect("code should be valid"), - ) + assemble_test_library("custom-library-1", "custom::component1", CUSTOM_CODE1) }); static CUSTOM_LIBRARY2: LazyLock = LazyLock::new(|| { - Arc::unwrap_or_clone( - Assembler::default() - .assemble_library([CUSTOM_CODE2]) - .expect("code should be valid"), - ) + assemble_test_library("custom-library-2", "custom::component2", CUSTOM_CODE2) }); + fn assemble_test_library(name: &str, path: &str, source: &str) -> Library { + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ast::ModuleKind::Library)) + .parse_str(Some(Path::new(path)), source, source_manager.clone()) + .expect("code should parse"); + + *Assembler::new(source_manager) + .assemble_library(name, root, None::<&str>) + .expect("code should be valid") + } + static CUSTOM_COMPONENT1_SLOT_NAME: LazyLock = LazyLock::new(|| { StorageSlotName::new("custom::component1::slot0") .expect("storage slot name should be valid") @@ -411,11 +416,11 @@ mod tests { // The merged code should have one procedure from each library. assert_eq!(account.code.procedure_roots().count(), 3); - let foo_root = CUSTOM_LIBRARY1.mast_forest() - [CUSTOM_LIBRARY1.get_export_node_id(CUSTOM_LIBRARY1.exports().next().unwrap().path())] + let foo_root = CUSTOM_LIBRARY1.mast_forest()[CUSTOM_LIBRARY1 + .get_export_node_id(CUSTOM_LIBRARY1.manifest.exports().next().unwrap().path())] .digest(); - let bar_root = CUSTOM_LIBRARY2.mast_forest() - [CUSTOM_LIBRARY2.get_export_node_id(CUSTOM_LIBRARY2.exports().next().unwrap().path())] + let bar_root = CUSTOM_LIBRARY2.mast_forest()[CUSTOM_LIBRARY2 + .get_export_node_id(CUSTOM_LIBRARY2.manifest.exports().next().unwrap().path())] .digest(); assert!(account.code().procedures().contains(&AccountProcedureRoot::from_raw(foo_root))); diff --git a/crates/miden-protocol/src/account/code/mod.rs b/crates/miden-protocol/src/account/code/mod.rs index 2e4b39af2b..00cbccf804 100644 --- a/crates/miden-protocol/src/account/code/mod.rs +++ b/crates/miden-protocol/src/account/code/mod.rs @@ -3,6 +3,9 @@ use alloc::vec::Vec; use miden_core::mast::MastForest; use miden_core::prettier::PrettyPrint; +use miden_mast_package::debug_info::PackageDebugInfo; +use miden_mast_package::{Package, PackageDebugInfoError}; +use miden_processor::LoadedMastForest; use super::{ AccountError, @@ -44,6 +47,7 @@ pub struct AccountCode { mast: Arc, procedures: Vec, commitment: Word, + package_debug_info: Option>, } impl AccountCode { @@ -74,6 +78,7 @@ impl AccountCode { commitment: build_procedure_commitment(&procedures), procedures, mast, + package_debug_info: None, } } @@ -105,9 +110,10 @@ impl AccountCode { pub(super) fn from_components_unchecked( components: &[AccountComponent], ) -> Result { - let (merged_mast_forest, _) = + let (merged_mast_forest, root_map) = MastForest::merge(components.iter().map(|component| component.mast_forest())) .map_err(AccountError::AccountComponentMastForestMergeError)?; + let package_debug_info = merge_component_debug_info(components, &root_map)?; let mut builder = AccountProcedureBuilder::new(); let mut components_iter = components.iter(); @@ -126,6 +132,7 @@ impl AccountCode { commitment: build_procedure_commitment(&procedures), procedures, mast: Arc::new(merged_mast_forest), + package_debug_info, }) } @@ -142,6 +149,11 @@ impl AccountCode { self.mast.clone() } + /// Returns the MAST forest and package-owned debug information backing this account code. + pub fn loaded_mast_forest(&self) -> LoadedMastForest { + loaded_mast_forest(self.mast.clone(), self.package_debug_info.clone()) + } + /// Returns a reference to the account procedure roots. pub fn procedures(&self) -> &[AccountProcedureRoot] { &self.procedures @@ -409,6 +421,54 @@ fn build_procedure_commitment(procedures: &[AccountProcedureRoot]) -> Word { Hasher::hash_elements(&elements) } +fn merge_component_debug_info( + components: &[AccountComponent], + root_map: &miden_core::mast::MastForestRootMap, +) -> Result>, AccountError> { + let component_debug_info = components + .iter() + .enumerate() + .filter_map(|(idx, component)| { + decode_package_debug_info(component.component_code().as_library()) + .map(|debug| (idx, debug)) + }) + .collect::>(); + + if component_debug_info.is_empty() { + return Ok(None); + } + + let debug_info = PackageDebugInfo::merge_source_debug( + component_debug_info.iter().map(|(idx, debug)| (*idx, debug.as_ref())), + root_map, + ) + .map_err(|err| { + AccountError::other_with_source("failed to merge account component debug info", err) + })?; + + Ok(Some(Arc::new(debug_info))) +} + +fn decode_package_debug_info(package: &Package) -> Option> { + match package.debug_info() { + Ok(debug_info) => debug_info.map(Arc::new), + Err(PackageDebugInfoError::UntrustedSections) => None, + Err(_) => None, + } +} + +fn loaded_mast_forest( + mast: Arc, + package_debug_info: Option>, +) -> LoadedMastForest { + match package_debug_info { + Some(package_debug_info) => { + LoadedMastForest::with_package_debug_info(mast, Ok(Some((*package_debug_info).clone()))) + }, + None => LoadedMastForest::new(mast), + } +} + /// Converts given procedures into field elements fn procedures_as_elements(procedures: &[AccountProcedureRoot]) -> Vec { procedures.iter().flat_map(AccountProcedureRoot::as_elements).copied().collect() @@ -419,11 +479,11 @@ fn procedures_as_elements(procedures: &[AccountProcedureRoot]) -> Vec { #[cfg(test)] mod tests { - use alloc::sync::Arc; use assert_matches::assert_matches; - use miden_assembly::Assembler; + use miden_assembly::{Assembler, DefaultSourceManager, ModuleParser, Path, ast}; + use miden_mast_package::Package as Library; use super::{AccountCode, Deserializable, Serializable}; use crate::account::AccountComponent; @@ -433,6 +493,17 @@ mod tests { use crate::testing::account_code::CODE; use crate::testing::noop_auth_component::NoopAuthComponent; + fn assemble_test_library(name: &str, path: &str, source: &str) -> Library { + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ast::ModuleKind::Library)) + .parse_str(Some(Path::new(path)), source, source_manager.clone()) + .unwrap(); + + *Assembler::new(source_manager) + .assemble_library(name, root, None::<&str>) + .unwrap() + } + #[test] fn test_serde_account_code() { let code = AccountCode::mock(); @@ -457,7 +528,8 @@ mod tests { #[test] fn test_account_code_no_auth_component() { - let library = Arc::unwrap_or_clone(Assembler::default().assemble_library([CODE]).unwrap()); + let library = + assemble_test_library("test-account-code-no-auth", "test::account_code", CODE); let metadata = AccountComponentMetadata::new("test::no_auth"); let component = AccountComponent::new(library, vec![], metadata).unwrap(); @@ -466,6 +538,18 @@ mod tests { assert_matches!(err, AccountError::AccountCodeNoAuthComponent); } + #[test] + fn test_account_code_preserves_component_debug_info() { + let library = + assemble_test_library("test-account-code-debug-info", "test::account_code", CODE); + let metadata = AccountComponentMetadata::new("test::debug_info"); + let component = AccountComponent::new(library, vec![], metadata).unwrap(); + + let code = AccountCode::from_components(&[NoopAuthComponent.into(), component]).unwrap(); + + assert!(code.loaded_mast_forest().package_debug_info().unwrap().is_some()); + } + #[test] fn test_account_code_multiple_auth_components() { let err = @@ -477,8 +561,6 @@ mod tests { #[test] fn test_account_component_multiple_auth_procedures() { - use miden_assembly::Assembler; - let code_with_multiple_auth = " @auth_script pub proc auth_basic @@ -491,8 +573,10 @@ mod tests { end "; - let library = Arc::unwrap_or_clone( - Assembler::default().assemble_library([code_with_multiple_auth]).unwrap(), + let library = assemble_test_library( + "test-account-code-multiple-auth", + "test::account_code_multiple_auth", + code_with_multiple_auth, ); let metadata = AccountComponentMetadata::new("test::multiple_auth"); let component = AccountComponent::new(library, vec![], metadata).unwrap(); diff --git a/crates/miden-protocol/src/account/code/procedure.rs b/crates/miden-protocol/src/account/code/procedure.rs index 2c27f9fd20..287a261f65 100644 --- a/crates/miden-protocol/src/account/code/procedure.rs +++ b/crates/miden-protocol/src/account/code/procedure.rs @@ -6,7 +6,6 @@ use miden_core::prettier::PrettyPrint; use miden_crypto_derive::WordWrapper; use miden_processor::mast::{MastNode, MastNodeExt, MastNodeId}; -use super::Felt; use crate::Word; use crate::utils::serde::{ ByteReader, diff --git a/crates/miden-protocol/src/account/component/code.rs b/crates/miden-protocol/src/account/component/code.rs index 97469eacf8..ac876a69ca 100644 --- a/crates/miden-protocol/src/account/component/code.rs +++ b/crates/miden-protocol/src/account/component/code.rs @@ -1,5 +1,4 @@ -use miden_assembly::Library; -use miden_assembly::library::ProcedureExport; +use miden_mast_package::{Package as Library, ProcedureExport}; use miden_processor::mast::{MastForest, MastNodeExt}; use crate::account::AccountProcedureRoot; @@ -32,9 +31,13 @@ impl AccountComponentCode { /// Returns an iterator over the [`AccountProcedureRoot`]s of this component's exported /// procedures. pub fn procedure_roots(&self) -> impl Iterator + '_ { - self.0.exports().filter_map(|export| { + self.0.manifest.exports().filter_map(|export| { export.as_procedure().map(|proc_export| { - let digest = self.0.mast_forest()[proc_export.node].digest(); + let digest = if let Some(node) = proc_export.node { + self.0.mast_forest()[node].digest() + } else { + proc_export.digest + }; AccountProcedureRoot::from_raw(digest) }) }) @@ -42,7 +45,7 @@ impl AccountComponentCode { /// Returns the procedure exports of this component. pub fn exports(&self) -> impl Iterator + '_ { - self.0.exports().filter_map(|export| export.as_procedure()) + self.0.manifest.exports().filter_map(|export| export.as_procedure()) } /// Returns the [`AccountProcedureRoot`] of the procedure with the specified path, or `None` @@ -51,7 +54,19 @@ impl AccountComponentCode { &self, proc_name: impl AsRef, ) -> Option { - self.0.get_procedure_root_by_path(proc_name).map(AccountProcedureRoot::from_raw) + let proc_name = proc_name.as_ref(); + let absolute_proc_name = proc_name.to_absolute().ok(); + self.0 + .manifest + .exports() + .filter_map(|export| export.as_procedure()) + .find(|export| { + export.path.as_ref() == proc_name + || absolute_proc_name.as_ref().is_some_and(|absolute_proc_name| { + export.path.as_ref() == absolute_proc_name.as_ref() + }) + }) + .map(|export| AccountProcedureRoot::from_raw(export.digest)) } /// Returns a new [AccountComponentCode] with the provided advice map entries merged into the @@ -97,18 +112,30 @@ mod tests { use alloc::string::ToString; use alloc::sync::Arc; + use miden_assembly::{DefaultSourceManager, ModuleParser, Path, ast}; use miden_core::{Felt, Word}; + use miden_mast_package::Package as Library; use super::*; use crate::assembly::Assembler; + fn assemble_test_library(name: &str, path: &str, source: &str) -> Library { + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ast::ModuleKind::Library)) + .parse_str(Some(Path::new(path)), source, source_manager.clone()) + .unwrap(); + + *Assembler::new(source_manager) + .assemble_library(name, root, None::<&str>) + .unwrap() + } + #[test] fn test_account_component_code_with_advice_map() { - let assembler = Assembler::default(); - let library = Arc::unwrap_or_clone( - assembler - .assemble_library(["pub proc test nop end"]) - .expect("failed to assemble library"), + let library = assemble_test_library( + "test-component-code-advice-map", + "test::component_code_advice_map", + "pub proc test nop end", ); let component_code = AccountComponentCode::from(library); @@ -135,11 +162,10 @@ mod tests { #[test] fn test_get_procedure_root_by_path() { - let assembler = Assembler::default(); - let library = Arc::unwrap_or_clone( - assembler - .assemble_library(["pub proc test_proc nop end"]) - .expect("failed to assemble library"), + let library = assemble_test_library( + "test-component-code-procedure-root", + "test::component_code_procedure_root", + "pub proc test_proc nop end", ); let component_code = AccountComponentCode::from(library); @@ -161,6 +187,13 @@ mod tests { .expect("test_proc should be present"); assert_eq!(root, expected); + let relative_proc_path = + proc_path.strip_prefix("::").expect("test procedure path should be absolute"); + let root = component_code + .get_procedure_root_by_path(relative_proc_path) + .expect("relative test_proc path should be present"); + assert_eq!(root, expected); + assert!(component_code.get_procedure_root_by_path("bogus::missing").is_none()); } } diff --git a/crates/miden-protocol/src/account/component/mod.rs b/crates/miden-protocol/src/account/component/mod.rs index f6d17591e8..95eae30ccf 100644 --- a/crates/miden-protocol/src/account/component/mod.rs +++ b/crates/miden-protocol/src/account/component/mod.rs @@ -23,7 +23,7 @@ const AUTH_SCRIPT_ATTRIBUTE: &str = "auth_script"; // ACCOUNT COMPONENT // ================================================================================================ -/// An [`AccountComponent`] defines a [`Library`](miden_assembly::Library) of code and the initial +/// An [`AccountComponent`] defines a [`Library`](crate::assembly::Library) of code and the initial /// value and types of the [`StorageSlot`]s it accesses. /// /// One or more components can be used to built [`AccountCode`](crate::account::AccountCode) and @@ -80,7 +80,7 @@ impl AccountComponent { /// /// # Arguments /// - /// * `package` - The package containing the [`Library`](miden_assembly::Library) and account + /// * `package` - The package containing the [`Library`](crate::assembly::Library) and account /// component metadata /// * `init_storage_data` - The initialization data for storage slots /// @@ -97,7 +97,7 @@ impl AccountComponent { init_storage_data: &InitStorageData, ) -> Result { let metadata = AccountComponentMetadata::try_from(package)?; - let library = package.mast.as_ref().clone(); + let library = package.clone(); let component_code = AccountComponentCode::from(library); Self::from_library(&component_code, &metadata, init_storage_data) @@ -179,13 +179,17 @@ impl AccountComponent { /// attribute. pub fn procedures(&self) -> impl Iterator + '_ { let library = self.code.as_library(); - library.exports().filter_map(|export| { + library.manifest.exports().filter_map(|export| { export.as_procedure().map(|proc_export| { - let digest = library - .mast_forest() - .get_node_by_id(proc_export.node) - .expect("export node not in the forest") - .digest(); + let digest = if let Some(node) = proc_export.node { + library + .mast_forest() + .get_node_by_id(node) + .expect("export node not in the forest") + .digest() + } else { + proc_export.digest + }; let is_auth = proc_export.attributes.has(AUTH_SCRIPT_ATTRIBUTE); (AccountProcedureRoot::from_raw(digest), is_auth) }) @@ -219,18 +223,30 @@ mod tests { use alloc::string::ToString; use alloc::sync::Arc; - use miden_assembly::Assembler; - use miden_mast_package::{Package, PackageManifest, Section, SectionId, TargetType}; + use miden_assembly::{Assembler, DefaultSourceManager, ModuleParser, Path, ast}; + use miden_mast_package::{Package as Library, Section, SectionId}; use semver::Version; use super::*; use crate::testing::account_code::CODE; use crate::utils::serde::Serializable; + fn assemble_test_library(name: &str, path: &str, source: &str) -> Library { + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ast::ModuleKind::Library)) + .parse_str(Some(Path::new(path)), source, source_manager.clone()) + .unwrap(); + + *Assembler::new(source_manager) + .assemble_library(name, root, None::<&str>) + .unwrap() + } + #[test] fn test_extract_metadata_from_package() { // Create a simple library for testing - let library = Assembler::default().assemble_library([CODE]).unwrap(); + let library = + assemble_test_library("test-extract-metadata", "test::extract_metadata", CODE); // Test with metadata let metadata = AccountComponentMetadata::new("test_component") @@ -238,33 +254,17 @@ mod tests { .with_version(Version::new(1, 0, 0)); let metadata_bytes = metadata.to_bytes(); - let package_with_metadata = Package { - name: "test_package".into(), - mast: library.clone(), - manifest: PackageManifest::new(core::iter::empty()).unwrap(), - kind: TargetType::AccountComponent, - sections: vec![Section::new( - SectionId::ACCOUNT_COMPONENT_METADATA, - metadata_bytes.clone(), - )], - version: Version::new(0, 0, 0), - description: None, - }; + let mut package_with_metadata = library.clone(); + package_with_metadata + .sections + .push(Section::new(SectionId::ACCOUNT_COMPONENT_METADATA, metadata_bytes.clone())); let extracted_metadata = AccountComponentMetadata::try_from(&package_with_metadata).unwrap(); assert_eq!(extracted_metadata.name(), "test_component"); // Test without metadata - should fail - let package_without_metadata = Package { - name: "test_package_no_metadata".into(), - mast: library, - manifest: PackageManifest::new(core::iter::empty()).unwrap(), - kind: TargetType::AccountComponent, - sections: vec![], // No metadata section - version: Version::new(0, 0, 0), - description: None, - }; + let package_without_metadata = library; let result = AccountComponentMetadata::try_from(&package_without_metadata); assert!(result.is_err()); @@ -275,8 +275,9 @@ mod tests { #[test] fn test_from_library_with_init_data() { // Create a simple library for testing - let library = Assembler::default().assemble_library([CODE]).unwrap(); - let component_code = AccountComponentCode::from(Arc::unwrap_or_clone(library.clone())); + let library = + assemble_test_library("test-from-library-init-data", "test::from_library", CODE); + let component_code = AccountComponentCode::from(library.clone()); // Create metadata for the component let metadata = AccountComponentMetadata::new("test_component") @@ -293,15 +294,7 @@ mod tests { assert_eq!(component.storage_size(), 0); // Test without metadata - should fail - let package_without_metadata = Package { - name: "test_package_no_metadata".into(), - mast: library, - kind: TargetType::AccountComponent, - manifest: PackageManifest::new(core::iter::empty()).unwrap(), - sections: vec![], // No metadata section - version: Version::new(0, 0, 0), - description: None, - }; + let package_without_metadata = library; let result = AccountComponent::from_package(&package_without_metadata, &init_data); assert!(result.is_err()); diff --git a/crates/miden-protocol/src/account/storage/map/key.rs b/crates/miden-protocol/src/account/storage/map/key.rs index 5838311fc5..a44afa6690 100644 --- a/crates/miden-protocol/src/account/storage/map/key.rs +++ b/crates/miden-protocol/src/account/storage/map/key.rs @@ -10,7 +10,7 @@ use crate::utils::serde::{ DeserializationError, Serializable, }; -use crate::{Felt, Hasher, Word}; +use crate::{Hasher, Word}; // STORAGE MAP KEY // ================================================================================================ diff --git a/crates/miden-protocol/src/account/storage/partial.rs b/crates/miden-protocol/src/account/storage/partial.rs index 7d5ef2d18d..d3e9a243ca 100644 --- a/crates/miden-protocol/src/account/storage/partial.rs +++ b/crates/miden-protocol/src/account/storage/partial.rs @@ -124,7 +124,7 @@ impl PartialStorage { /// Returns an iterator over inner nodes of all storage map proofs contained in this /// partial storage. pub fn inner_nodes(&self) -> impl Iterator { - self.maps.iter().flat_map(|(_, map)| map.inner_nodes()) + self.maps.values().flat_map(|map| map.inner_nodes()) } /// Iterator over every [`PartialStorageMap`] in this partial storage. diff --git a/crates/miden-protocol/src/batch/note_tree.rs b/crates/miden-protocol/src/batch/note_tree.rs index dd1d9a6f88..2c157e10fa 100644 --- a/crates/miden-protocol/src/batch/note_tree.rs +++ b/crates/miden-protocol/src/batch/note_tree.rs @@ -76,7 +76,7 @@ impl Serializable for BatchNoteTree { impl Deserializable for BatchNoteTree { fn read_from(source: &mut R) -> Result { let leaves = Vec::read_from(source)?; - let smt = SimpleSmt::with_leaves(leaves.into_iter()).map_err(|err| { + let smt = SimpleSmt::with_leaves(leaves).map_err(|err| { DeserializationError::UnknownError(format!( "failed to deserialize BatchNoteTree: {err}" )) diff --git a/crates/miden-protocol/src/block/smt_backend.rs b/crates/miden-protocol/src/block/smt_backend.rs index a906261f44..3700ab01fc 100644 --- a/crates/miden-protocol/src/block/smt_backend.rs +++ b/crates/miden-protocol/src/block/smt_backend.rs @@ -169,13 +169,21 @@ where } fn leaves(&self) -> Box, SmtLeaf)> + '_> { - Box::new(LargeSmt::leaves(self).expect("Only IO can error out here")) + Box::new( + LargeSmt::leaves(self) + .expect("Only IO can error out here") + .map(|leaf| leaf.expect("Only IO can error out here")), + ) } fn entries(&self) -> Box + '_> { // SAFETY: We expect here as only I/O errors can occur. Storage failures are considered // unrecoverable at this layer. See issue #2010 for future error handling improvements. - Box::new(LargeSmt::entries(self).expect("Storage I/O error accessing entries")) + Box::new( + LargeSmt::entries(self) + .expect("Storage I/O error accessing entries") + .map(|entry| entry.expect("Storage I/O error accessing entries")), + ) } fn open(&self, key: &Word) -> SmtProof { diff --git a/crates/miden-protocol/src/lib.rs b/crates/miden-protocol/src/lib.rs index 93dedc2ae3..4dcf8ecd26 100644 --- a/crates/miden-protocol/src/lib.rs +++ b/crates/miden-protocol/src/lib.rs @@ -37,14 +37,11 @@ pub use protocol::ProtocolLib; pub mod assembly { pub use miden_assembly::ast::{Module, ModuleKind, ProcedureName, QualifiedProcedureName}; pub use miden_assembly::debuginfo::SourceManagerSync; - pub use miden_assembly::library::LibraryExport; pub use miden_assembly::{ Assembler, DefaultSourceManager, - KernelLibrary, - Library, - Parse, - ParseOptions, + Linkage, + ModuleParser, Path, SourceFile, SourceId, @@ -54,6 +51,13 @@ pub mod assembly { diagnostics, mast, }; + pub use miden_assembly_syntax::Parse; + pub use miden_mast_package::{ + Package as KernelLibrary, + Package as Library, + PackageExport as LibraryExport, + ProcedureExport, + }; } pub mod crypto { @@ -67,8 +71,10 @@ pub mod vm { pub use miden_core::advice::{AdviceInputs, AdviceMap}; pub use miden_core::events::{EventId, EventName, SystemEvent}; pub use miden_core::program::{Program, ProgramInfo}; + pub use miden_mast_package::debug_info::PackageDebugInfo; pub use miden_mast_package::{ Package, + PackageDebugInfoError, PackageExport, PackageManifest, ProcedureExport, diff --git a/crates/miden-protocol/src/note/note_details_commitment.rs b/crates/miden-protocol/src/note/note_details_commitment.rs index 0b1326cdc8..f1c3fd7ac6 100644 --- a/crates/miden-protocol/src/note/note_details_commitment.rs +++ b/crates/miden-protocol/src/note/note_details_commitment.rs @@ -2,7 +2,7 @@ use alloc::string::String; use miden_crypto_derive::WordWrapper; -use super::{Felt, Hasher, Word}; +use super::{Hasher, Word}; use crate::note::{NoteAssets, NoteRecipient}; use crate::utils::serde::{ ByteReader, diff --git a/crates/miden-protocol/src/note/note_id.rs b/crates/miden-protocol/src/note/note_id.rs index 1a50e613ea..c95da1f3b2 100644 --- a/crates/miden-protocol/src/note/note_id.rs +++ b/crates/miden-protocol/src/note/note_id.rs @@ -3,7 +3,7 @@ use core::fmt::Display; use miden_crypto_derive::WordWrapper; -use super::{Felt, NoteDetailsCommitment, NoteMetadata}; +use super::{NoteDetailsCommitment, NoteMetadata}; use crate::utils::serde::{ ByteReader, ByteWriter, diff --git a/crates/miden-protocol/src/note/script.rs b/crates/miden-protocol/src/note/script.rs index e6b08fcc0a..b259882a77 100644 --- a/crates/miden-protocol/src/note/script.rs +++ b/crates/miden-protocol/src/note/script.rs @@ -4,12 +4,14 @@ use alloc::vec::Vec; use core::fmt::Display; use core::num::TryFromIntError; -use miden_core::mast::MastNodeExt; +use miden_core::mast::{MastNode, MastNodeExt}; use miden_crypto_derive::WordWrapper; -use miden_mast_package::Package; +use miden_mast_package::debug_info::PackageDebugInfo; +use miden_mast_package::{Package, PackageDebugInfoError}; +use miden_processor::LoadedMastForest; use super::Felt; -use crate::assembly::mast::{ExternalNodeBuilder, MastForest, MastForestContributor, MastNodeId}; +use crate::assembly::mast::{ExternalNodeBuilder, MastForest, MastNodeId}; use crate::assembly::{Library, Path}; use crate::errors::NoteError; use crate::utils::serde::{ @@ -68,10 +70,11 @@ impl Deserializable for NoteScriptRoot { /// /// A note's script represents a program which must be executed for a note to be consumed. As such /// it defines the rules and side effects of consuming a given note. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] pub struct NoteScript { mast: Arc, entrypoint: MastNodeId, + package_debug_info: Option>, } impl NoteScript { @@ -87,6 +90,7 @@ impl NoteScript { Self { entrypoint: code.entrypoint(), mast: code.mast_forest().clone(), + package_debug_info: None, } } @@ -104,7 +108,11 @@ impl NoteScript { /// Panics if the specified entrypoint is not in the provided MAST forest. pub fn from_parts(mast: Arc, entrypoint: MastNodeId) -> Self { assert!(mast.get_node_by_id(entrypoint).is_some()); - Self { mast, entrypoint } + Self { + mast, + entrypoint, + package_debug_info: None, + } } /// Returns a new [NoteScript] instantiated from the provided library. @@ -119,14 +127,16 @@ impl NoteScript { pub fn from_library(library: &Library) -> Result { let mut entrypoint = None; - for export in library.exports() { + for export in library.manifest.exports() { if let Some(proc_export) = export.as_procedure() { // Check for @note_script attribute if proc_export.attributes.has(NOTE_SCRIPT_ATTRIBUTE) { if entrypoint.is_some() { return Err(NoteError::NoteScriptMultipleProceduresWithAttribute); } - entrypoint = Some(proc_export.node); + entrypoint = Some( + proc_export.node.ok_or(NoteError::NoteScriptNoProcedureWithAttribute)?, + ); } } } @@ -136,6 +146,7 @@ impl NoteScript { Ok(Self { mast: library.mast_forest().clone(), entrypoint, + package_debug_info: decode_package_debug_info(library), }) } @@ -159,6 +170,7 @@ impl NoteScript { pub fn from_library_reference(library: &Library, path: &Path) -> Result { // Find the export matching the path let export = library + .manifest .exports() .find(|e| e.path().as_ref() == path) .ok_or_else(|| NoteError::NoteScriptProcedureNotFound(path.to_string().into()))?; @@ -173,12 +185,16 @@ impl NoteScript { } // Get the digest of the procedure from the library - let digest = library.mast_forest()[proc_export.node].digest(); + let digest = proc_export.digest; // Create a minimal MastForest with just an external node referencing the digest let (mast, entrypoint) = create_external_node_forest(digest); - Ok(Self { mast: Arc::new(mast), entrypoint }) + Ok(Self { + mast: Arc::new(mast), + entrypoint, + package_debug_info: decode_package_debug_info(library), + }) } /// Creates an [`NoteScript`] from a [`Package`]. @@ -191,7 +207,7 @@ impl NoteScript { /// - The package contains a library which contains multiple procedures with the `@note_script` /// attribute. pub fn from_package(package: &Package) -> Result { - Ok(NoteScript::from_library(&package.mast))? + Ok(NoteScript::from_library(package))? } // PUBLIC ACCESSORS @@ -207,19 +223,32 @@ impl NoteScript { self.mast.clone() } + /// Returns the MAST forest and package-owned debug information backing this note script. + pub fn loaded_mast_forest(&self) -> LoadedMastForest { + loaded_mast_forest(self.mast.clone(), self.package_debug_info.clone()) + } + /// Returns an entrypoint node ID of the current script. pub fn entrypoint(&self) -> MastNodeId { self.entrypoint } - /// Clears all debug info from this script's [`MastForest`]: decorators, error codes, and - /// procedure names. + /// Compacts this script's [`MastForest`], removing duplicate and unreachable nodes while + /// preserving the script root. /// - /// See [`MastForest::clear_debug_info`] for more details. + /// Note script minification used to clear debug metadata from the forest. As of + /// `miden-core` v0.24, debug metadata is no longer stored in [`MastForest`], so minification + /// compacts the forest instead. pub fn clear_debug_info(&mut self) { - let mut mast = self.mast.clone(); - Arc::make_mut(&mut mast).clear_debug_info(); - self.mast = mast; + let root = self.root(); + let (mast, root_map) = (*self.mast).clone().compact(); + self.entrypoint = root_map + .map_root(0, &self.entrypoint) + .expect("entrypoint should be preserved when compacting a note script MAST forest"); + self.mast = Arc::new(mast); + self.package_debug_info = None; + + debug_assert_eq!(self.root(), root); } /// Returns a new [NoteScript] with the provided advice map entries merged into the @@ -232,15 +261,23 @@ impl NoteScript { return self; } - let mut mast = (*self.mast).clone(); - mast.advice_map_mut().extend(advice_map); + let mast = (*self.mast).clone().with_advice_map(advice_map); Self { mast: Arc::new(mast), entrypoint: self.entrypoint, + package_debug_info: self.package_debug_info, } } } +impl PartialEq for NoteScript { + fn eq(&self, other: &Self) -> bool { + self.mast == other.mast && self.entrypoint == other.entrypoint + } +} + +impl Eq for NoteScript {} + // CONVERSIONS INTO NOTE SCRIPT // ================================================================================================ @@ -312,7 +349,7 @@ impl TryFrom<&[Felt]> for NoteScript { })?; data.extend(element.to_le_bytes()) } - data.shrink_to(len as usize); + data.truncate(len as usize); // TODO: Use UntrustedMastForest and check where else we deserialize mast forests. let mast = MastForest::read_from_bytes(&data)?; @@ -385,28 +422,66 @@ impl Display for NoteScript { /// libraries. The external reference will be resolved at runtime, assuming the source library /// is loaded into the VM's MastForestStore. fn create_external_node_forest(digest: Word) -> (MastForest, MastNodeId) { - let mut mast = MastForest::new(); - let node_id = ExternalNodeBuilder::new(digest) - .add_to_forest(&mut mast) + let mut nodes: miden_core::utils::IndexVec = + miden_core::utils::IndexVec::new(); + let node_id = nodes + .push(ExternalNodeBuilder::new(digest).build().into()) .expect("adding external node to empty forest should not fail"); - mast.make_root(node_id); + let mast = MastForest::from_raw_parts(nodes, vec![node_id], AdviceMap::default()) + .expect("single external node forest should be well-formed"); (mast, node_id) } +fn decode_package_debug_info(package: &Package) -> Option> { + match package.debug_info() { + Ok(debug_info) => debug_info.map(Arc::new), + Err(PackageDebugInfoError::UntrustedSections) => None, + Err(_) => None, + } +} + +fn loaded_mast_forest( + mast: Arc, + package_debug_info: Option>, +) -> LoadedMastForest { + match package_debug_info { + Some(package_debug_info) => { + LoadedMastForest::with_package_debug_info(mast, Ok(Some((*package_debug_info).clone()))) + }, + None => LoadedMastForest::new(mast), + } +} + // TESTS // ================================================================================================ #[cfg(test)] mod tests { + use alloc::sync::Arc; + + use miden_assembly::{DefaultSourceManager, ModuleParser, Path, ast}; + use miden_mast_package::Package as Library; + use super::{Felt, NoteScript, Vec}; use crate::assembly::Assembler; use crate::testing::note::DEFAULT_NOTE_SCRIPT; + fn assemble_test_library(name: &str, path: &str, source: &str) -> Library { + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ast::ModuleKind::Library)) + .parse_str(Some(Path::new(path)), source, source_manager.clone()) + .unwrap(); + + *Assembler::new(source_manager) + .assemble_library(name, root, None::<&str>) + .unwrap() + } + #[test] fn test_note_script_to_from_felt() { - let assembler = Assembler::default(); let script_src = DEFAULT_NOTE_SCRIPT; - let library = assembler.assemble_library([script_src]).unwrap(); + let library = + assemble_test_library("test-note-script-roundtrip", "test::note_roundtrip", script_src); let note_script = NoteScript::from_library(&library).unwrap(); let encoded: Vec = (¬e_script).into(); @@ -415,14 +490,29 @@ mod tests { assert_eq!(note_script, decoded); } + #[test] + fn test_note_script_preserves_package_debug_info() { + let library = assemble_test_library( + "test-note-script-debug-info", + "test::note_debug_info", + DEFAULT_NOTE_SCRIPT, + ); + let note_script = NoteScript::from_library(&library).unwrap(); + + assert!(note_script.loaded_mast_forest().package_debug_info().unwrap().is_some()); + } + #[test] fn test_note_script_with_advice_map() { use miden_core::advice::AdviceMap; use crate::Word; - let assembler = Assembler::default(); - let library = assembler.assemble_library([DEFAULT_NOTE_SCRIPT]).unwrap(); + let library = assemble_test_library( + "test-note-script-with-advice-map", + "test::note_with_advice_map", + DEFAULT_NOTE_SCRIPT, + ); let script = NoteScript::from_library(&library).unwrap(); assert!(script.mast().advice_map().is_empty()); diff --git a/crates/miden-protocol/src/testing/account_code.rs b/crates/miden-protocol/src/testing/account_code.rs index c463d78b3c..70ff2bcdfc 100644 --- a/crates/miden-protocol/src/testing/account_code.rs +++ b/crates/miden-protocol/src/testing/account_code.rs @@ -3,10 +3,9 @@ use alloc::sync::Arc; -use miden_assembly::Assembler; - use crate::account::component::AccountComponentMetadata; use crate::account::{AccountCode, AccountComponent}; +use crate::assembly::{Assembler, DefaultSourceManager, ModuleKind, ModuleParser, Path}; use crate::testing::noop_auth_component::NoopAuthComponent; pub const CODE: &str = " @@ -22,11 +21,17 @@ pub const CODE: &str = " impl AccountCode { /// Creates a mock [AccountCode] with default assembler and mock code pub fn mock() -> AccountCode { - let library = Arc::unwrap_or_clone( - Assembler::default() - .assemble_library([CODE]) - .expect("mock account component should assemble"), - ); + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str( + Some(Path::new("miden::testing::mock_account")), + CODE, + source_manager.clone(), + ) + .expect("mock account component should parse"); + let library = *Assembler::new(source_manager) + .assemble_library("miden-testing-mock-account", root, None::<&str>) + .expect("mock account component should assemble"); let metadata = AccountComponentMetadata::new("miden::testing::mock"); let component = AccountComponent::new(library, vec![], metadata).unwrap(); diff --git a/crates/miden-protocol/src/testing/account_id.rs b/crates/miden-protocol/src/testing/account_id.rs index a26833d587..146a3a4cad 100644 --- a/crates/miden-protocol/src/testing/account_id.rs +++ b/crates/miden-protocol/src/testing/account_id.rs @@ -1,4 +1,4 @@ -use rand_xoshiro::rand_core::SeedableRng; +use rand::{RngExt, SeedableRng}; use crate::account::{AccountId, AccountIdV1, AccountIdVersion, AccountType}; diff --git a/crates/miden-protocol/src/testing/add_component.rs b/crates/miden-protocol/src/testing/add_component.rs index 1cffe9182c..abd3cb98b7 100644 --- a/crates/miden-protocol/src/testing/add_component.rs +++ b/crates/miden-protocol/src/testing/add_component.rs @@ -2,7 +2,7 @@ use alloc::sync::Arc; use crate::account::AccountComponent; use crate::account::component::AccountComponentMetadata; -use crate::assembly::{Assembler, Library}; +use crate::assembly::{Assembler, DefaultSourceManager, Library, ModuleKind, ModuleParser, Path}; use crate::utils::sync::LazyLock; // ADD COMPONENT @@ -15,11 +15,14 @@ const ADD_CODE: &str = " "; static ADD_LIBRARY: LazyLock = LazyLock::new(|| { - Arc::unwrap_or_clone( - Assembler::default() - .assemble_library([ADD_CODE]) - .expect("add code should be valid"), - ) + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str(Some(Path::new("miden::testing::add")), ADD_CODE, source_manager.clone()) + .expect("add code should parse"); + + *Assembler::new(source_manager) + .assemble_library("miden-testing-add", root, None::<&str>) + .expect("add code should be valid") }); /// Creates a mock authentication [`AccountComponent`] for testing purposes. diff --git a/crates/miden-protocol/src/testing/noop_auth_component.rs b/crates/miden-protocol/src/testing/noop_auth_component.rs index 069ff94076..9184254dd2 100644 --- a/crates/miden-protocol/src/testing/noop_auth_component.rs +++ b/crates/miden-protocol/src/testing/noop_auth_component.rs @@ -2,7 +2,7 @@ use alloc::sync::Arc; use crate::account::AccountComponent; use crate::account::component::AccountComponentMetadata; -use crate::assembly::{Assembler, Library}; +use crate::assembly::{Assembler, DefaultSourceManager, Library, ModuleKind, ModuleParser, Path}; use crate::utils::sync::LazyLock; // NOOP AUTH COMPONENT @@ -16,11 +16,18 @@ const NOOP_AUTH_CODE: &str = " "; static NOOP_AUTH_LIBRARY: LazyLock = LazyLock::new(|| { - Arc::unwrap_or_clone( - Assembler::default() - .assemble_library([NOOP_AUTH_CODE]) - .expect("noop auth code should be valid"), - ) + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str( + Some(Path::new("miden::testing::noop_auth")), + NOOP_AUTH_CODE, + source_manager.clone(), + ) + .expect("noop auth code should parse"); + + *Assembler::new(source_manager) + .assemble_library("miden-testing-noop-auth", root, None::<&str>) + .expect("noop auth code should be valid") }); /// Creates a mock authentication [`AccountComponent`] for testing purposes. diff --git a/crates/miden-protocol/src/testing/note.rs b/crates/miden-protocol/src/testing/note.rs index 6dbceba7c2..8c947e5016 100644 --- a/crates/miden-protocol/src/testing/note.rs +++ b/crates/miden-protocol/src/testing/note.rs @@ -1,7 +1,8 @@ +use alloc::sync::Arc; use alloc::vec::Vec; use crate::Word; -use crate::assembly::Assembler; +use crate::assembly::{Assembler, DefaultSourceManager, ModuleKind, ModuleParser, Path}; use crate::asset::FungibleAsset; use crate::note::{ Note, @@ -42,8 +43,17 @@ impl Note { impl NoteScript { pub fn mock() -> Self { - let assembler = Assembler::default(); - let library = assembler.assemble_library([DEFAULT_NOTE_SCRIPT]).unwrap(); + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str( + Some(Path::new("miden::testing::note")), + DEFAULT_NOTE_SCRIPT, + source_manager.clone(), + ) + .expect("mock note script should parse"); + let library = Assembler::new(source_manager) + .assemble_library("miden-testing-note", root, None::<&str>) + .unwrap(); Self::from_library(&library).unwrap() } } diff --git a/crates/miden-protocol/src/testing/random_secret_key.rs b/crates/miden-protocol/src/testing/random_secret_key.rs index c984ce94e7..e58f3f3e88 100644 --- a/crates/miden-protocol/src/testing/random_secret_key.rs +++ b/crates/miden-protocol/src/testing/random_secret_key.rs @@ -9,6 +9,6 @@ use crate::crypto::dsa::ecdsa_k256_keccak::SigningKey; pub fn random_secret_key() -> SigningKey { use rand::SeedableRng; use rand_chacha::ChaCha20Rng; - let mut rng = ChaCha20Rng::from_os_rng(); - SigningKey::with_rng(&mut rng) + let mut rng = ChaCha20Rng::from_rng(&mut rand::rng()); + SigningKey::with_rng::(&mut rng) } diff --git a/crates/miden-protocol/src/transaction/kernel/mod.rs b/crates/miden-protocol/src/transaction/kernel/mod.rs index 046433a69c..1006af7499 100644 --- a/crates/miden-protocol/src/transaction/kernel/mod.rs +++ b/crates/miden-protocol/src/transaction/kernel/mod.rs @@ -7,7 +7,7 @@ use crate::account::{AccountHeader, AccountId}; #[cfg(any(feature = "testing", test))] use crate::assembly::Library; use crate::assembly::debuginfo::SourceManagerSync; -use crate::assembly::{Assembler, DefaultSourceManager, KernelLibrary}; +use crate::assembly::{Assembler, DefaultSourceManager, KernelLibrary, Linkage}; use crate::block::BlockNumber; use crate::crypto::SequentialCommit; use crate::errors::TransactionOutputError; @@ -103,7 +103,7 @@ impl TransactionKernel { pub fn program_info() -> ProgramInfo { // TODO: make static let program_hash = Self::main().hash(); - let kernel = Self::kernel().kernel().clone(); + let kernel = Self::kernel().to_kernel().expect("failed to convert package to kernel"); ProgramInfo::new(program_hash, kernel) } @@ -141,11 +141,15 @@ impl TransactionKernel { #[cfg(all(any(feature = "testing", test), feature = "std"))] source_manager_ext::load_masm_source_files(&source_manager); - Assembler::with_kernel(source_manager, Self::kernel()) - .with_dynamic_library(CoreLibrary::default()) - .expect("failed to load std-lib") - .with_dynamic_library(ProtocolLib::default()) - .expect("failed to load miden-lib") + let mut assembler = Assembler::with_kernel(source_manager, Arc::new(Self::kernel())) + .expect("failed to load transaction kernel"); + assembler + .link_package(CoreLibrary::default().package(), Linkage::Dynamic) + .expect("failed to load std-lib"); + assembler + .link_package(Arc::new(ProtocolLib::default().into()), Linkage::Dynamic) + .expect("failed to load miden-lib"); + assembler } // STACK INPUTS / OUTPUTS diff --git a/crates/miden-protocol/src/transaction/outputs/tests.rs b/crates/miden-protocol/src/transaction/outputs/tests.rs index f2ce0d055f..712c41a2ad 100644 --- a/crates/miden-protocol/src/transaction/outputs/tests.rs +++ b/crates/miden-protocol/src/transaction/outputs/tests.rs @@ -4,7 +4,12 @@ use assert_matches::assert_matches; use super::{PublicOutputNote, RawOutputNote, RawOutputNotes}; use crate::account::AccountId; -use crate::assembly::mast::{ExternalNodeBuilder, MastForest, MastForestContributor}; +use crate::assembly::mast::{ + ExternalNodeBuilder, + JoinNodeBuilder, + MastForest, + MastForestContributor, +}; use crate::asset::FungibleAsset; use crate::constants::NOTE_MAX_SIZE; use crate::errors::{OutputNoteError, TransactionOutputError}; @@ -77,25 +82,40 @@ fn output_note_size_hint_matches_serialized_length() -> anyhow::Result<()> { Ok(()) } -// Construct a public note whose serialized size exceeds NOTE_MAX_SIZE by building -// a MastForest with many external nodes. External nodes carry no debug info, so -// `minify_script()` (called inside `PublicOutputNote::new()`) cannot shrink them. +// Construct a public note whose serialized size exceeds NOTE_MAX_SIZE by building a MastForest with +// many reachable external nodes. External nodes carry no debug info, so `minify_script()` (called +// inside `PublicOutputNote::new()`) cannot shrink them below the limit. #[test] fn oversized_public_note_triggers_size_limit_error() -> anyhow::Result<()> { let sender_id = ACCOUNT_ID_SENDER.try_into().unwrap(); - // Build a large MastForest by adding many external nodes. Each node stores a - // 32-byte digest; 7000 nodes comfortably exceed the 256 KiB limit. + // Build a large reachable MastForest by joining many external nodes. Each external node stores + // a 32-byte digest, and each join node keeps the previous nodes reachable after compaction. The + // joins are balanced to keep recursive traversals shallow. let mut mast = MastForest::new(); - let mut root_id = None; + let mut roots = alloc::vec::Vec::new(); for i in 0..7_000_u16 { let digest = Word::new([Felt::from(i + 1), Felt::ZERO, Felt::ZERO, Felt::ZERO]); - let id = ExternalNodeBuilder::new(digest) + let external_id = ExternalNodeBuilder::new(digest) .add_to_forest(&mut mast) .expect("adding external node should not fail"); - root_id = Some(id); + roots.push(external_id); + } + while roots.len() > 1 { + let mut next_roots = alloc::vec::Vec::with_capacity(roots.len().div_ceil(2)); + for chunk in roots.chunks(2) { + let root_id = match chunk { + [left, right] => JoinNodeBuilder::new([*left, *right]) + .add_to_forest(&mut mast) + .expect("adding join node should not fail"), + [root] => *root, + _ => unreachable!("chunks of two have one or two elements"), + }; + next_roots.push(root_id); + } + roots = next_roots; } - let root_id = root_id.unwrap(); + let root_id = roots.pop().expect("at least one root should exist"); mast.make_root(root_id); let script = NoteScript::from_parts(Arc::new(mast), root_id); @@ -121,6 +141,13 @@ fn oversized_public_note_triggers_size_limit_error() -> anyhow::Result<()> { computed_note_size > NOTE_MAX_SIZE as usize, "Expected note size ({computed_note_size}) to exceed NOTE_MAX_SIZE ({NOTE_MAX_SIZE})" ); + let mut minified_note = oversized_note.clone(); + minified_note.minify_script(); + let minified_note_size = minified_note.get_size_hint(); + assert!( + minified_note_size > NOTE_MAX_SIZE as usize, + "Expected minified note size ({minified_note_size}) to exceed NOTE_MAX_SIZE ({NOTE_MAX_SIZE})" + ); // Creating a PublicOutputNote should fail with size limit error let result = PublicOutputNote::new(oversized_note.clone()); diff --git a/crates/miden-protocol/src/transaction/transaction_id.rs b/crates/miden-protocol/src/transaction/transaction_id.rs index 30c07664ae..4eb53a1932 100644 --- a/crates/miden-protocol/src/transaction/transaction_id.rs +++ b/crates/miden-protocol/src/transaction/transaction_id.rs @@ -3,7 +3,7 @@ use core::fmt::{Debug, Display}; use miden_crypto_derive::WordWrapper; -use super::{Felt, Hasher, ProvenTransaction, WORD_SIZE, Word, ZERO}; +use super::{Hasher, ProvenTransaction, WORD_SIZE, Word, ZERO}; use crate::utils::serde::{ ByteReader, ByteWriter, diff --git a/crates/miden-protocol/src/transaction/tx_args.rs b/crates/miden-protocol/src/transaction/tx_args.rs index 0ffc8eeec5..e46b2f3367 100644 --- a/crates/miden-protocol/src/transaction/tx_args.rs +++ b/crates/miden-protocol/src/transaction/tx_args.rs @@ -7,7 +7,9 @@ use core::fmt::Display; use miden_core::mast::MastNodeExt; use miden_crypto::merkle::InnerNodeInfo; use miden_crypto_derive::WordWrapper; -use miden_mast_package::Package; +use miden_mast_package::debug_info::PackageDebugInfo; +use miden_mast_package::{Package, PackageDebugInfoError}; +use miden_processor::LoadedMastForest; use super::{Felt, Hasher, Word}; use crate::account::auth::{PublicKeyCommitment, Signature}; @@ -325,10 +327,11 @@ impl Deserializable for TransactionScriptRoot { /// /// The [TransactionScript] object is composed of an executable program defined by a [MastForest] /// and an associated entrypoint. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug)] pub struct TransactionScript { mast: Arc, entrypoint: MastNodeId, + package_debug_info: Option>, } impl TransactionScript { @@ -347,7 +350,11 @@ impl TransactionScript { pub fn from_parts(mast: Arc, entrypoint: MastNodeId) -> Self { assert!(mast.get_node_by_id(entrypoint).is_some()); - Self { mast, entrypoint } + Self { + mast, + entrypoint, + package_debug_info: None, + } } /// Creates a [TransactionScript] from a [`Package`]. @@ -361,7 +368,11 @@ impl TransactionScript { let program = package.try_into_program().map_err(TransactionScriptError::PackageNotProgram)?; - Ok(TransactionScript::new(program)) + Ok(Self { + mast: program.mast_forest().clone(), + entrypoint: program.entrypoint(), + package_debug_info: decode_package_debug_info(package), + }) } // PUBLIC ACCESSORS @@ -372,6 +383,11 @@ impl TransactionScript { self.mast.clone() } + /// Returns the MAST forest and package-owned debug information backing this transaction script. + pub fn loaded_mast_forest(&self) -> LoadedMastForest { + loaded_mast_forest(self.mast.clone(), self.package_debug_info.clone()) + } + /// Returns the commitment of this transaction script (i.e., the script's MAST root). pub fn root(&self) -> TransactionScriptRoot { TransactionScriptRoot::from_raw(self.mast[self.entrypoint].digest()) @@ -387,15 +403,43 @@ impl TransactionScript { return self; } - let mut mast = (*self.mast).clone(); - mast.advice_map_mut().extend(advice_map); + let mast = (*self.mast).clone().with_advice_map(advice_map); Self { mast: Arc::new(mast), entrypoint: self.entrypoint, + package_debug_info: self.package_debug_info, } } } +impl PartialEq for TransactionScript { + fn eq(&self, other: &Self) -> bool { + self.mast == other.mast && self.entrypoint == other.entrypoint + } +} + +impl Eq for TransactionScript {} + +fn decode_package_debug_info(package: &Package) -> Option> { + match package.debug_info() { + Ok(debug_info) => debug_info.map(Arc::new), + Err(PackageDebugInfoError::UntrustedSections) => None, + Err(_) => None, + } +} + +fn loaded_mast_forest( + mast: Arc, + package_debug_info: Option>, +) -> LoadedMastForest { + match package_debug_info { + Some(package_debug_info) => { + LoadedMastForest::with_package_debug_info(mast, Ok(Some((*package_debug_info).clone()))) + }, + None => LoadedMastForest::new(mast), + } +} + // SERIALIZATION // ================================================================================================ @@ -431,6 +475,19 @@ mod tests { assert_eq!(tx_args, decoded); } + #[test] + fn test_transaction_script_preserves_package_debug_info() { + use super::TransactionScript; + use crate::assembly::Assembler; + + let assembler = Assembler::default(); + let package = + assembler.assemble_program("test-transaction-script", "begin nop end").unwrap(); + let script = TransactionScript::from_package(&package).unwrap(); + + assert!(script.loaded_mast_forest().package_debug_info().unwrap().is_some()); + } + #[test] fn test_transaction_script_with_advice_map() { use miden_core::{Felt, Word}; @@ -439,7 +496,11 @@ mod tests { use crate::assembly::Assembler; let assembler = Assembler::default(); - let program = assembler.assemble_program("begin nop end").unwrap(); + let program = assembler + .assemble_program("test-transaction-script", "begin nop end") + .unwrap() + .try_into_program() + .unwrap(); let script = TransactionScript::new(program); assert!(script.mast().advice_map().is_empty()); diff --git a/crates/miden-standards/Cargo.toml b/crates/miden-standards/Cargo.toml index 5888abf0df..60e2ba2e46 100644 --- a/crates/miden-standards/Cargo.toml +++ b/crates/miden-standards/Cargo.toml @@ -29,12 +29,13 @@ rand = { optional = true, workspace = true } thiserror = { workspace = true } [build-dependencies] -fs-err = { workspace = true } -miden-assembly = { workspace = true } -miden-core-lib = { workspace = true } -miden-protocol = { workspace = true } -regex = { workspace = true } -walkdir = { workspace = true } +fs-err = { workspace = true } +miden-assembly = { workspace = true } +miden-assembly-syntax = { workspace = true } +miden-core-lib = { workspace = true } +miden-protocol = { workspace = true } +regex = { workspace = true } +walkdir = { workspace = true } [dev-dependencies] anyhow = { workspace = true } diff --git a/crates/miden-standards/asm/account_components/access/authority.masm b/crates/miden-standards/asm/account_components/access/authority.masm index f660bb559b..1beee9d893 100644 --- a/crates/miden-standards/asm/account_components/access/authority.masm +++ b/crates/miden-standards/asm/account_components/access/authority.masm @@ -8,10 +8,10 @@ # emergency switch (`freeze` / `unfreeze`) as `call` entrypoints. use miden::protocol::active_account -use miden::standards::access::authority::AUTHORITY_SLOT +use {AUTHORITY_SLOT} from miden::standards::access::authority -pub use ::miden::standards::access::authority::freeze -pub use ::miden::standards::access::authority::unfreeze +pub use {freeze} from ::miden::standards::access::authority +pub use {unfreeze} from ::miden::standards::access::authority #! Returns the authority discriminator stored on the account. #! diff --git a/crates/miden-standards/asm/account_components/access/ownable2step.masm b/crates/miden-standards/asm/account_components/access/ownable2step.masm index 0f7b7dd2bd..21ad004dc4 100644 --- a/crates/miden-standards/asm/account_components/access/ownable2step.masm +++ b/crates/miden-standards/asm/account_components/access/ownable2step.masm @@ -2,8 +2,8 @@ # # See the `Ownable2Step` Rust type's documentation for more details. -pub use ::miden::standards::access::ownable2step::get_owner -pub use ::miden::standards::access::ownable2step::get_nominated_owner -pub use ::miden::standards::access::ownable2step::transfer_ownership -pub use ::miden::standards::access::ownable2step::accept_ownership -pub use ::miden::standards::access::ownable2step::renounce_ownership +pub use {get_owner} from ::miden::standards::access::ownable2step +pub use {get_nominated_owner} from ::miden::standards::access::ownable2step +pub use {transfer_ownership} from ::miden::standards::access::ownable2step +pub use {accept_ownership} from ::miden::standards::access::ownable2step +pub use {renounce_ownership} from ::miden::standards::access::ownable2step diff --git a/crates/miden-standards/asm/account_components/access/pausable/manager.masm b/crates/miden-standards/asm/account_components/access/pausable/manager.masm index ed3d462b92..06dd89a980 100644 --- a/crates/miden-standards/asm/account_components/access/pausable/manager.masm +++ b/crates/miden-standards/asm/account_components/access/pausable/manager.masm @@ -8,5 +8,5 @@ # `Authority::AuthControlled` directly by `create_user_fungible_faucet`). # - `Pausable` — provides the `is_paused` storage slot. -pub use ::miden::standards::access::pausable::manager::pause -pub use ::miden::standards::access::pausable::manager::unpause +pub use {pause} from ::miden::standards::access::pausable::manager +pub use {unpause} from ::miden::standards::access::pausable::manager diff --git a/crates/miden-standards/asm/account_components/access/pausable/mod.masm b/crates/miden-standards/asm/account_components/access/pausable/mod.masm index 6ac2a10597..8e2ac147f0 100644 --- a/crates/miden-standards/asm/account_components/access/pausable/mod.masm +++ b/crates/miden-standards/asm/account_components/access/pausable/mod.masm @@ -3,4 +3,4 @@ # [`TokenPolicyManager`] and the metadata setter procedures themselves, both of which use the # `assert_not_paused` exec helper from `miden::standards::access::pausable` directly. -pub use ::miden::standards::access::pausable::is_paused +pub use {is_paused} from ::miden::standards::access::pausable diff --git a/crates/miden-standards/asm/account_components/access/rbac.masm b/crates/miden-standards/asm/account_components/access/rbac.masm index 1478b4f575..af75c0b43a 100644 --- a/crates/miden-standards/asm/account_components/access/rbac.masm +++ b/crates/miden-standards/asm/account_components/access/rbac.masm @@ -2,10 +2,10 @@ # # See the `RoleBasedAccessControl` Rust type's documentation for more details. -pub use ::miden::standards::access::rbac::has_role -pub use ::miden::standards::access::rbac::get_role_admin -pub use ::miden::standards::access::rbac::get_role_member_count -pub use ::miden::standards::access::rbac::set_role_admin -pub use ::miden::standards::access::rbac::grant_role -pub use ::miden::standards::access::rbac::revoke_role -pub use ::miden::standards::access::rbac::renounce_role +pub use {has_role} from ::miden::standards::access::rbac +pub use {get_role_admin} from ::miden::standards::access::rbac +pub use {get_role_member_count} from ::miden::standards::access::rbac +pub use {set_role_admin} from ::miden::standards::access::rbac +pub use {grant_role} from ::miden::standards::access::rbac +pub use {revoke_role} from ::miden::standards::access::rbac +pub use {renounce_role} from ::miden::standards::access::rbac diff --git a/crates/miden-standards/asm/account_components/auth/guarded_multisig.masm b/crates/miden-standards/asm/account_components/auth/guarded_multisig.masm index 29ffded0e5..fd7c125609 100644 --- a/crates/miden-standards/asm/account_components/auth/guarded_multisig.masm +++ b/crates/miden-standards/asm/account_components/auth/guarded_multisig.masm @@ -5,13 +5,13 @@ use miden::standards::auth::multisig use miden::standards::auth::guardian -pub use multisig::update_signers_and_threshold -pub use multisig::get_threshold_and_num_approvers -pub use multisig::set_procedure_threshold -pub use multisig::get_signer_at -pub use multisig::is_signer +pub use {update_signers_and_threshold} from miden::standards::auth::multisig +pub use {get_threshold_and_num_approvers} from miden::standards::auth::multisig +pub use {set_procedure_threshold} from miden::standards::auth::multisig +pub use {get_signer_at} from miden::standards::auth::multisig +pub use {is_signer} from miden::standards::auth::multisig -pub use guardian::update_guardian_public_key +pub use {update_guardian_public_key} from miden::standards::auth::guardian #! Authenticate a transaction with multi-signature support and optional guardian verification. #! diff --git a/crates/miden-standards/asm/account_components/auth/multisig.masm b/crates/miden-standards/asm/account_components/auth/multisig.masm index 5e698bc886..00c14866a1 100644 --- a/crates/miden-standards/asm/account_components/auth/multisig.masm +++ b/crates/miden-standards/asm/account_components/auth/multisig.masm @@ -4,11 +4,11 @@ use miden::standards::auth::multisig -pub use multisig::update_signers_and_threshold -pub use multisig::get_threshold_and_num_approvers -pub use multisig::set_procedure_threshold -pub use multisig::get_signer_at -pub use multisig::is_signer +pub use {update_signers_and_threshold} from miden::standards::auth::multisig +pub use {get_threshold_and_num_approvers} from miden::standards::auth::multisig +pub use {set_procedure_threshold} from miden::standards::auth::multisig +pub use {get_signer_at} from miden::standards::auth::multisig +pub use {is_signer} from miden::standards::auth::multisig #! Authenticate a transaction with multi-signature support. #! diff --git a/crates/miden-standards/asm/account_components/auth/multisig_smart.masm b/crates/miden-standards/asm/account_components/auth/multisig_smart.masm index af05afa295..bcfce77a96 100644 --- a/crates/miden-standards/asm/account_components/auth/multisig_smart.masm +++ b/crates/miden-standards/asm/account_components/auth/multisig_smart.masm @@ -5,11 +5,11 @@ use miden::standards::auth::multisig use miden::standards::auth::multisig_smart -pub use multisig::get_threshold_and_num_approvers -pub use multisig::get_signer_at -pub use multisig::is_signer -pub use multisig_smart::set_procedure_policy -pub use multisig_smart::update_signers_and_threshold +pub use {get_threshold_and_num_approvers} from miden::standards::auth::multisig +pub use {get_signer_at} from miden::standards::auth::multisig +pub use {is_signer} from miden::standards::auth::multisig +pub use {set_procedure_policy} from miden::standards::auth::multisig_smart +pub use {update_signers_and_threshold} from miden::standards::auth::multisig_smart #! Authenticate a transaction using multisig smart-policy rules. #! diff --git a/crates/miden-standards/asm/account_components/faucets/fungible_faucet.masm b/crates/miden-standards/asm/account_components/faucets/fungible_faucet.masm index 0b370ce547..f5ca0ef500 100644 --- a/crates/miden-standards/asm/account_components/faucets/fungible_faucet.masm +++ b/crates/miden-standards/asm/account_components/faucets/fungible_faucet.masm @@ -5,24 +5,24 @@ # (name, description, logo URI, external link, mutability config) into a single component. # Fungible token minting and burning -pub use ::miden::standards::faucets::fungible::mint_and_send -pub use ::miden::standards::faucets::fungible::receive_and_burn +pub use {mint_and_send} from ::miden::standards::faucets::fungible +pub use {receive_and_burn} from ::miden::standards::faucets::fungible # Fungible token configuration -pub use ::miden::standards::faucets::fungible::get_decimals -pub use ::miden::standards::faucets::fungible::get_token_symbol -pub use ::miden::standards::faucets::fungible::get_token_supply -pub use ::miden::standards::faucets::fungible::get_max_supply -pub use ::miden::standards::faucets::fungible::set_max_supply -pub use ::miden::standards::faucets::fungible::is_max_supply_mutable -pub use ::miden::standards::faucets::fungible::get_token_config +pub use {get_decimals} from ::miden::standards::faucets::fungible +pub use {get_token_symbol} from ::miden::standards::faucets::fungible +pub use {get_token_supply} from ::miden::standards::faucets::fungible +pub use {get_max_supply} from ::miden::standards::faucets::fungible +pub use {set_max_supply} from ::miden::standards::faucets::fungible +pub use {is_max_supply_mutable} from ::miden::standards::faucets::fungible +pub use {get_token_config} from ::miden::standards::faucets::fungible # Token metadata: mandatory name + optional description, logo, external link. -pub use ::miden::standards::faucets::get_name -pub use ::miden::standards::faucets::get_mutability_config -pub use ::miden::standards::faucets::is_description_mutable -pub use ::miden::standards::faucets::is_logo_uri_mutable -pub use ::miden::standards::faucets::is_external_link_mutable -pub use ::miden::standards::faucets::set_description -pub use ::miden::standards::faucets::set_logo_uri -pub use ::miden::standards::faucets::set_external_link +pub use {get_name} from ::miden::standards::faucets +pub use {get_mutability_config} from ::miden::standards::faucets +pub use {is_description_mutable} from ::miden::standards::faucets +pub use {is_logo_uri_mutable} from ::miden::standards::faucets +pub use {is_external_link_mutable} from ::miden::standards::faucets +pub use {set_description} from ::miden::standards::faucets +pub use {set_logo_uri} from ::miden::standards::faucets +pub use {set_external_link} from ::miden::standards::faucets diff --git a/crates/miden-standards/asm/account_components/faucets/non_fungible_faucet.masm b/crates/miden-standards/asm/account_components/faucets/non_fungible_faucet.masm index 7e7dd61beb..292300db89 100644 --- a/crates/miden-standards/asm/account_components/faucets/non_fungible_faucet.masm +++ b/crates/miden-standards/asm/account_components/faucets/non_fungible_faucet.masm @@ -6,21 +6,27 @@ # into a single component. # Non-fungible token minting and burning -pub use ::miden::standards::faucets::non_fungible::mint_and_send -pub use ::miden::standards::faucets::non_fungible::receive_and_burn +pub use { + mint_and_send, + receive_and_burn, +} from ::miden::standards::faucets::non_fungible # Non-fungible token symbol and asset status -pub use ::miden::standards::faucets::non_fungible::get_symbol -pub use ::miden::standards::faucets::non_fungible::get_asset_status +pub use { + get_asset_status, + get_symbol, +} from ::miden::standards::faucets::non_fungible # Token metadata: mandatory name + optional description, logo, contract URI. # The shared `external_link` field is surfaced under the NFT-specific name `contract_uri` # (the OpenSea-style collection metadata pointer); it reuses the shared external_link storage. -pub use ::miden::standards::faucets::get_name -pub use ::miden::standards::faucets::get_mutability_config -pub use ::miden::standards::faucets::is_description_mutable -pub use ::miden::standards::faucets::is_logo_uri_mutable -pub use ::miden::standards::faucets::is_external_link_mutable->is_contract_uri_mutable -pub use ::miden::standards::faucets::set_description -pub use ::miden::standards::faucets::set_logo_uri -pub use ::miden::standards::faucets::set_external_link->set_contract_uri +pub use { + get_mutability_config, + get_name, + is_description_mutable, + is_external_link_mutable as is_contract_uri_mutable, + is_logo_uri_mutable, + set_description, + set_external_link as set_contract_uri, + set_logo_uri, +} from ::miden::standards::faucets diff --git a/crates/miden-standards/asm/account_components/faucets/policies/burn/allow_all.masm b/crates/miden-standards/asm/account_components/faucets/policies/burn/allow_all.masm index 8915ff99d7..935f66c36b 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/burn/allow_all.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/burn/allow_all.masm @@ -3,4 +3,4 @@ # Exposes the `check_policy` procedure so its MAST root can be registered as the active # (or allowed) policy on a `BurnPolicyManager`. Storage-free. -pub use ::miden::standards::faucets::policies::burn::allow_all::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::burn::allow_all diff --git a/crates/miden-standards/asm/account_components/faucets/policies/burn/min_burn_amount.masm b/crates/miden-standards/asm/account_components/faucets/policies/burn/min_burn_amount.masm index 55e3ff6e96..aa993cc79e 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/burn/min_burn_amount.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/burn/min_burn_amount.masm @@ -4,6 +4,6 @@ # a `TokenPolicyManager`, plus the owner-gated `set_min_burn_amount` / `get_min_burn_amount` # accessors for the configurable minimum burn amount stored in this component's storage slot. -pub use ::miden::standards::faucets::policies::burn::min_burn_amount::check_policy -pub use ::miden::standards::faucets::policies::burn::min_burn_amount::set_min_burn_amount -pub use ::miden::standards::faucets::policies::burn::min_burn_amount::get_min_burn_amount +pub use {check_policy} from ::miden::standards::faucets::policies::burn::min_burn_amount +pub use {set_min_burn_amount} from ::miden::standards::faucets::policies::burn::min_burn_amount +pub use {get_min_burn_amount} from ::miden::standards::faucets::policies::burn::min_burn_amount diff --git a/crates/miden-standards/asm/account_components/faucets/policies/burn/owner_controlled/owner_only.masm b/crates/miden-standards/asm/account_components/faucets/policies/burn/owner_controlled/owner_only.masm index 96f67e0f90..769bf57dc9 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/burn/owner_controlled/owner_only.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/burn/owner_controlled/owner_only.masm @@ -3,4 +3,4 @@ # Exposes the `check_policy` procedure so its MAST root can be registered as the active # (or allowed) policy on a `BurnPolicyManager`. Storage-free. -pub use ::miden::standards::faucets::policies::burn::owner_controlled::owner_only::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::burn::owner_controlled::owner_only diff --git a/crates/miden-standards/asm/account_components/faucets/policies/mint/allow_all.masm b/crates/miden-standards/asm/account_components/faucets/policies/mint/allow_all.masm index cdee675edb..3bbbdf9a25 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/mint/allow_all.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/mint/allow_all.masm @@ -3,4 +3,4 @@ # Exposes the `check_policy` procedure so its MAST root can be registered as the active # (or allowed) policy on a `MintPolicyManager`. Storage-free. -pub use ::miden::standards::faucets::policies::mint::allow_all::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::mint::allow_all diff --git a/crates/miden-standards/asm/account_components/faucets/policies/mint/owner_controlled/owner_only.masm b/crates/miden-standards/asm/account_components/faucets/policies/mint/owner_controlled/owner_only.masm index e09e0ab9ad..0ef6de8e3d 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/mint/owner_controlled/owner_only.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/mint/owner_controlled/owner_only.masm @@ -3,4 +3,4 @@ # Exposes the `check_policy` procedure so its MAST root can be registered as the active # (or allowed) policy on a `MintPolicyManager`. Storage-free. -pub use ::miden::standards::faucets::policies::mint::owner_controlled::owner_only::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::mint::owner_controlled::owner_only diff --git a/crates/miden-standards/asm/account_components/faucets/policies/policy_manager.masm b/crates/miden-standards/asm/account_components/faucets/policies/policy_manager.masm index 470abbd73c..ab5532eac1 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/policy_manager.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/policy_manager.masm @@ -8,13 +8,13 @@ # to the whole circulating supply. Pair with policy components whose procedure roots are # registered in the relevant allowed-policies map. -pub use ::miden::standards::faucets::policies::policy_manager::set_mint_policy -pub use ::miden::standards::faucets::policies::policy_manager::get_mint_policy -pub use ::miden::standards::faucets::policies::policy_manager::set_burn_policy -pub use ::miden::standards::faucets::policies::policy_manager::get_burn_policy -pub use ::miden::standards::faucets::policies::policy_manager::set_send_policy -pub use ::miden::standards::faucets::policies::policy_manager::get_send_policy -pub use ::miden::standards::faucets::policies::policy_manager::set_receive_policy -pub use ::miden::standards::faucets::policies::policy_manager::get_receive_policy -pub use ::miden::standards::faucets::policies::policy_manager::invoke_send_policy -pub use ::miden::standards::faucets::policies::policy_manager::invoke_receive_policy +pub use {set_mint_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {get_mint_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {set_burn_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {get_burn_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {set_send_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {get_send_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {set_receive_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {get_receive_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {invoke_send_policy} from ::miden::standards::faucets::policies::policy_manager +pub use {invoke_receive_policy} from ::miden::standards::faucets::policies::policy_manager diff --git a/crates/miden-standards/asm/account_components/faucets/policies/transfer/allow_all.masm b/crates/miden-standards/asm/account_components/faucets/policies/transfer/allow_all.masm index 5b4d3f893b..7e91abc05f 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/transfer/allow_all.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/transfer/allow_all.masm @@ -3,4 +3,4 @@ # Exposes the `check_policy` procedure so its MAST root can be registered as the active # (or allowed) transfer policy on a `TokenPolicyManager`. Storage-free. -pub use ::miden::standards::faucets::policies::transfer::allow_all::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::transfer::allow_all diff --git a/crates/miden-standards/asm/account_components/faucets/policies/transfer/allowlist/owner_controlled.masm b/crates/miden-standards/asm/account_components/faucets/policies/transfer/allowlist/owner_controlled.masm index 1475b1505d..63f9396004 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/transfer/allowlist/owner_controlled.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/transfer/allowlist/owner_controlled.masm @@ -8,5 +8,5 @@ # component that installs the `allowed_accounts` storage slot — typically the basic allowlist # transfer policy component. -pub use ::miden::standards::faucets::policies::transfer::allowlist::owner_controlled::allow_account -pub use ::miden::standards::faucets::policies::transfer::allowlist::owner_controlled::disallow_account +pub use {allow_account} from ::miden::standards::faucets::policies::transfer::allowlist::owner_controlled +pub use {disallow_account} from ::miden::standards::faucets::policies::transfer::allowlist::owner_controlled diff --git a/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_allowlist.masm b/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_allowlist.masm index d0ef3fb20c..a89aded7a6 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_allowlist.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_allowlist.masm @@ -5,4 +5,4 @@ # storage map (defined by the sibling `allowlist` primitive); admin updates go through a # companion auth-gated component (see `allowlist/owner_controlled.masm`). -pub use ::miden::standards::faucets::policies::transfer::basic_allowlist::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::transfer::basic_allowlist diff --git a/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_blocklist.masm b/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_blocklist.masm index 36c4ddaaaa..4c6890163a 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_blocklist.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/transfer/basic_blocklist.masm @@ -5,4 +5,4 @@ # storage map (defined by the sibling `blocklist` primitive); admin updates go through a # companion auth-gated component (see `blocklist/owner_controlled.masm`). -pub use ::miden::standards::faucets::policies::transfer::basic_blocklist::check_policy +pub use {check_policy} from ::miden::standards::faucets::policies::transfer::basic_blocklist diff --git a/crates/miden-standards/asm/account_components/faucets/policies/transfer/blocklist/owner_controlled.masm b/crates/miden-standards/asm/account_components/faucets/policies/transfer/blocklist/owner_controlled.masm index 42a4d42893..e11c2063bd 100644 --- a/crates/miden-standards/asm/account_components/faucets/policies/transfer/blocklist/owner_controlled.masm +++ b/crates/miden-standards/asm/account_components/faucets/policies/transfer/blocklist/owner_controlled.masm @@ -8,5 +8,5 @@ # component that installs the `blocked_accounts` storage slot — typically the basic blocklist # transfer policy component. -pub use ::miden::standards::faucets::policies::transfer::blocklist::owner_controlled::block_account -pub use ::miden::standards::faucets::policies::transfer::blocklist::owner_controlled::unblock_account +pub use {block_account} from ::miden::standards::faucets::policies::transfer::blocklist::owner_controlled +pub use {unblock_account} from ::miden::standards::faucets::policies::transfer::blocklist::owner_controlled diff --git a/crates/miden-standards/asm/account_components/metadata/code_inspection.masm b/crates/miden-standards/asm/account_components/metadata/code_inspection.masm index 850c9f4852..fb9f33b6ae 100644 --- a/crates/miden-standards/asm/account_components/metadata/code_inspection.masm +++ b/crates/miden-standards/asm/account_components/metadata/code_inspection.masm @@ -4,7 +4,9 @@ # read-only introspection over the account's own code so that external callers can verify what the # account can do. It carries no storage of its own. -pub use ::miden::standards::metadata::code_inspection::has_procedure -pub use ::miden::standards::metadata::code_inspection::get_code_commitment -pub use ::miden::standards::metadata::code_inspection::get_num_procedures -pub use ::miden::standards::metadata::code_inspection::get_procedure_root +pub use { + get_code_commitment, + get_num_procedures, + get_procedure_root, + has_procedure, +} from ::miden::standards::metadata::code_inspection diff --git a/crates/miden-standards/asm/account_components/metadata/schema_commitment.masm b/crates/miden-standards/asm/account_components/metadata/schema_commitment.masm index cc9b85230a..03331fcf77 100644 --- a/crates/miden-standards/asm/account_components/metadata/schema_commitment.masm +++ b/crates/miden-standards/asm/account_components/metadata/schema_commitment.masm @@ -2,4 +2,4 @@ # # See the `AccountSchemaCommitment` Rust type's documentation for more details. -pub use ::miden::standards::metadata::storage_schema::get_schema_commitment +pub use {get_schema_commitment} from ::miden::standards::metadata::storage_schema diff --git a/crates/miden-standards/asm/account_components/wallets/basic_wallet.masm b/crates/miden-standards/asm/account_components/wallets/basic_wallet.masm index e6b613900e..02f7629e5c 100644 --- a/crates/miden-standards/asm/account_components/wallets/basic_wallet.masm +++ b/crates/miden-standards/asm/account_components/wallets/basic_wallet.masm @@ -2,5 +2,5 @@ # # See the `BasicWallet` Rust type's documentation for more details. -pub use ::miden::standards::wallets::basic::receive_asset -pub use ::miden::standards::wallets::basic::move_asset_to_note +pub use {receive_asset} from ::miden::standards::wallets::basic +pub use {move_asset_to_note} from ::miden::standards::wallets::basic diff --git a/crates/miden-standards/asm/standards/access/pausable/mod.masm b/crates/miden-standards/asm/standards/access/pausable/mod.masm index c1a1e91ae9..922c49201c 100644 --- a/crates/miden-standards/asm/standards/access/pausable/mod.masm +++ b/crates/miden-standards/asm/standards/access/pausable/mod.masm @@ -12,6 +12,8 @@ use miden::core::word use miden::protocol::active_account use miden::protocol::native_account +pub mod manager + # CONSTANTS # ================================================================================================ diff --git a/crates/miden-standards/asm/standards/auth/guardian.masm b/crates/miden-standards/asm/standards/auth/guardian.masm index 3f4ba0bc41..6254318c37 100644 --- a/crates/miden-standards/asm/standards/auth/guardian.masm +++ b/crates/miden-standards/asm/standards/auth/guardian.masm @@ -4,7 +4,7 @@ # # A state guardian can help coordinate state availability for private accounts. -use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT +use {AUTH_UNAUTHORIZED_EVENT} from miden::protocol::auth use miden::protocol::native_account use miden::standards::auth::tx_policy use miden::standards::auth::signature diff --git a/crates/miden-standards/asm/standards/auth/mod.masm b/crates/miden-standards/asm/standards/auth/mod.masm index 9d6503aad1..3279a98119 100644 --- a/crates/miden-standards/asm/standards/auth/mod.masm +++ b/crates/miden-standards/asm/standards/auth/mod.masm @@ -2,6 +2,14 @@ use miden::protocol::native_account use miden::protocol::tx use miden::core::crypto::hashes::poseidon2 +pub mod guardian +pub mod multisig +pub mod multisig_smart +pub mod note_script_allowlist +pub mod signature +pub mod tx_policy +pub mod tx_script_allowlist + #! Creates the transaction summary and returns it in the order in which it will be hashed. #! #! Inputs: [SALT] diff --git a/crates/miden-standards/asm/standards/auth/multisig.masm b/crates/miden-standards/asm/standards/auth/multisig.masm index 26b9f67abf..7bafa5397f 100644 --- a/crates/miden-standards/asm/standards/auth/multisig.masm +++ b/crates/miden-standards/asm/standards/auth/multisig.masm @@ -3,7 +3,7 @@ # See the `AuthMultisig` Rust type's documentation for more details. use miden::protocol::active_account -use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT +use {AUTH_UNAUTHORIZED_EVENT} from miden::protocol::auth use miden::protocol::native_account use miden::standards::auth use miden::standards::auth::signature diff --git a/crates/miden-standards/asm/standards/auth/multisig_smart/mod.masm b/crates/miden-standards/asm/standards/auth/multisig_smart/mod.masm index 33aa44eeb6..0db052959b 100644 --- a/crates/miden-standards/asm/standards/auth/multisig_smart/mod.masm +++ b/crates/miden-standards/asm/standards/auth/multisig_smart/mod.masm @@ -1,11 +1,11 @@ use miden::protocol::active_account use miden::protocol::native_account -use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT +use {AUTH_UNAUTHORIZED_EVENT} from miden::protocol::auth use miden::standards::auth use miden::standards::auth::multisig -use miden::standards::auth::multisig::APPROVER_PUBLIC_KEYS_SLOT -use miden::standards::auth::multisig::APPROVER_SCHEME_ID_SLOT -use miden::standards::auth::multisig::THRESHOLD_CONFIG_SLOT +use {APPROVER_PUBLIC_KEYS_SLOT} from miden::standards::auth::multisig +use {APPROVER_SCHEME_ID_SLOT} from miden::standards::auth::multisig +use {THRESHOLD_CONFIG_SLOT} from miden::standards::auth::multisig use miden::standards::auth::signature use miden::standards::auth::tx_policy diff --git a/crates/miden-standards/asm/standards/auth/signature.masm b/crates/miden-standards/asm/standards/auth/signature.masm index 50b24da609..f6bd82636f 100644 --- a/crates/miden-standards/asm/standards/auth/signature.masm +++ b/crates/miden-standards/asm/standards/auth/signature.masm @@ -2,7 +2,7 @@ use miden::core::crypto::dsa::falcon512_poseidon2 use miden::core::crypto::hashes::poseidon2 use miden::core::crypto::dsa::ecdsa_k256_keccak use miden::protocol::active_account -use miden::protocol::auth::AUTH_REQUEST_EVENT +use {AUTH_REQUEST_EVENT} from miden::protocol::auth use miden::protocol::native_account use miden::protocol::tx use miden::standards::auth diff --git a/crates/miden-standards/asm/standards/data_structures/double_word_array.masm b/crates/miden-standards/asm/standards/data_structures/double_word_array.masm index a2cf4f23cc..0ed2d29fe7 100644 --- a/crates/miden-standards/asm/standards/data_structures/double_word_array.masm +++ b/crates/miden-standards/asm/standards/data_structures/double_word_array.masm @@ -17,7 +17,7 @@ const SLOT_ID_PREFIX_LOC=0 const SLOT_ID_SUFFIX_LOC=1 const INDEX_LOC=2 -type DoubleWord = struct { +pub type DoubleWord = struct { a: felt, b: felt, c: felt, diff --git a/crates/miden-standards/asm/standards/faucets/fungible.masm b/crates/miden-standards/asm/standards/faucets/fungible.masm index a10fc65552..e119feada6 100644 --- a/crates/miden-standards/asm/standards/faucets/fungible.masm +++ b/crates/miden-standards/asm/standards/faucets/fungible.masm @@ -13,7 +13,7 @@ use miden::protocol::faucet use miden::protocol::native_account use miden::protocol::output_note use miden::protocol::asset -use miden::protocol::asset::FUNGIBLE_ASSET_MAX_AMOUNT +use {FUNGIBLE_ASSET_MAX_AMOUNT} from miden::protocol::asset use miden::standards::access::authority use miden::standards::faucets::policies::policy_manager use miden::standards::faucets diff --git a/crates/miden-standards/asm/standards/faucets/mod.masm b/crates/miden-standards/asm/standards/faucets/mod.masm index de18582a42..24939a3ecd 100644 --- a/crates/miden-standards/asm/standards/faucets/mod.masm +++ b/crates/miden-standards/asm/standards/faucets/mod.masm @@ -13,6 +13,10 @@ use miden::protocol::native_account use miden::standards::access::authority use miden::standards::access::pausable +pub mod fungible +pub mod non_fungible +pub mod policies + # ================================================================================================= # CONSTANTS — slot names # ================================================================================================= diff --git a/crates/miden-standards/asm/standards/faucets/policies/transfer/allowlist/mod.masm b/crates/miden-standards/asm/standards/faucets/policies/transfer/allowlist/mod.masm index 5e5e453ee9..36a4b4b4db 100644 --- a/crates/miden-standards/asm/standards/faucets/policies/transfer/allowlist/mod.masm +++ b/crates/miden-standards/asm/standards/faucets/policies/transfer/allowlist/mod.masm @@ -17,6 +17,8 @@ use miden::core::word use miden::protocol::active_account use miden::protocol::native_account +pub mod owner_controlled + # CONSTANTS # ================================================================================================ diff --git a/crates/miden-standards/asm/standards/faucets/policies/transfer/blocklist/mod.masm b/crates/miden-standards/asm/standards/faucets/policies/transfer/blocklist/mod.masm index 4bbd71b7af..38c487299f 100644 --- a/crates/miden-standards/asm/standards/faucets/policies/transfer/blocklist/mod.masm +++ b/crates/miden-standards/asm/standards/faucets/policies/transfer/blocklist/mod.masm @@ -15,6 +15,8 @@ use miden::core::word use miden::protocol::active_account use miden::protocol::native_account +pub mod owner_controlled + # CONSTANTS # ================================================================================================ diff --git a/crates/miden-standards/asm/standards/notes/burn.masm b/crates/miden-standards/asm/standards/notes/burn.masm index 4f1dc38400..2c783c4006 100644 --- a/crates/miden-standards/asm/standards/notes/burn.masm +++ b/crates/miden-standards/asm/standards/notes/burn.masm @@ -1,4 +1,4 @@ -use miden::standards::faucets::fungible->faucet +use miden::standards::faucets::fungible as faucet #! BURN script: burns the asset from the note by calling the faucet's `receive_and_burn` #! procedure. This note is intended to be executed against a fungible faucet account. diff --git a/crates/miden-standards/asm/standards/notes/burn_nft.masm b/crates/miden-standards/asm/standards/notes/burn_nft.masm index 3fde52f275..47707878fd 100644 --- a/crates/miden-standards/asm/standards/notes/burn_nft.masm +++ b/crates/miden-standards/asm/standards/notes/burn_nft.masm @@ -1,4 +1,4 @@ -use miden::standards::faucets::non_fungible->faucet +use miden::standards::faucets::non_fungible as faucet #! BURN script (non-fungible): burns the NFT carried by the note by calling the faucet's #! `receive_and_burn` procedure. Intended to be executed against a non-fungible faucet account. diff --git a/crates/miden-standards/asm/standards/notes/mint.masm b/crates/miden-standards/asm/standards/notes/mint.masm index 0745fcc794..bc3f205d56 100644 --- a/crates/miden-standards/asm/standards/notes/mint.masm +++ b/crates/miden-standards/asm/standards/notes/mint.masm @@ -1,6 +1,6 @@ use miden::protocol::active_note use miden::protocol::note -use miden::standards::faucets::fungible->faucet +use miden::standards::faucets::fungible as faucet # CONSTANTS # ================================================================================================= @@ -8,8 +8,8 @@ use miden::standards::faucets::fungible->faucet const MINT_NOTE_NUM_STORAGE_ITEMS_PRIVATE=13 const MINT_NOTE_MIN_NUM_STORAGE_ITEMS_PUBLIC=20 -use miden::protocol::note::NOTE_TYPE_PUBLIC -use miden::protocol::note::NOTE_TYPE_PRIVATE +use {NOTE_TYPE_PUBLIC} from miden::protocol::note +use {NOTE_TYPE_PRIVATE} from miden::protocol::note # Memory addresses of MINT note storage (private mode, 13 items total) const STORAGE_PTR = 0 diff --git a/crates/miden-standards/asm/standards/notes/mint_nft.masm b/crates/miden-standards/asm/standards/notes/mint_nft.masm index c8796f49c6..f030e19a47 100644 --- a/crates/miden-standards/asm/standards/notes/mint_nft.masm +++ b/crates/miden-standards/asm/standards/notes/mint_nft.masm @@ -1,6 +1,6 @@ use miden::protocol::active_note use miden::protocol::note -use miden::standards::faucets::non_fungible->faucet +use miden::standards::faucets::non_fungible as faucet # CONSTANTS # ================================================================================================= @@ -8,8 +8,8 @@ use miden::standards::faucets::non_fungible->faucet const MINT_NOTE_NUM_STORAGE_ITEMS_PRIVATE=9 const MINT_NOTE_MIN_NUM_STORAGE_ITEMS_PUBLIC=16 -use miden::protocol::note::NOTE_TYPE_PUBLIC -use miden::protocol::note::NOTE_TYPE_PRIVATE +use {NOTE_TYPE_PUBLIC} from miden::protocol::note +use {NOTE_TYPE_PRIVATE} from miden::protocol::note # Memory addresses of MINT note storage (private mode, 9 items total) const STORAGE_PTR = 0 diff --git a/crates/miden-standards/asm/standards/notes/p2id.masm b/crates/miden-standards/asm/standards/notes/p2id.masm index 9be2fa9d81..2187a6ccba 100644 --- a/crates/miden-standards/asm/standards/notes/p2id.masm +++ b/crates/miden-standards/asm/standards/notes/p2id.masm @@ -3,7 +3,7 @@ use miden::protocol::account_id use miden::protocol::active_note use miden::protocol::note use miden::protocol::output_note -use miden::standards::wallets::basic->basic_wallet +use miden::standards::wallets::basic as basic_wallet # ERRORS # ================================================================================================= diff --git a/crates/miden-standards/asm/standards/notes/p2ide.masm b/crates/miden-standards/asm/standards/notes/p2ide.masm index f9404571ce..7ddcdf7195 100644 --- a/crates/miden-standards/asm/standards/notes/p2ide.masm +++ b/crates/miden-standards/asm/standards/notes/p2ide.masm @@ -2,7 +2,7 @@ use miden::protocol::active_account use miden::protocol::account_id use miden::protocol::active_note use miden::protocol::tx -use miden::standards::wallets::basic->basic_wallet +use miden::standards::wallets::basic as basic_wallet # ERRORS # ================================================================================================= diff --git a/crates/miden-standards/asm/standards/notes/pswap.masm b/crates/miden-standards/asm/standards/notes/pswap.masm index f900fc2e33..0e950a93c2 100644 --- a/crates/miden-standards/asm/standards/notes/pswap.masm +++ b/crates/miden-standards/asm/standards/notes/pswap.masm @@ -6,10 +6,10 @@ use miden::protocol::active_note use miden::protocol::asset use miden::protocol::note use miden::protocol::output_note -use miden::protocol::asset::FUNGIBLE_ASSET_MAX_AMOUNT +use {FUNGIBLE_ASSET_MAX_AMOUNT} from miden::protocol::asset use miden::standards::note_tag use miden::standards::notes::p2id -use miden::standards::wallets::basic->wallet +use miden::standards::wallets::basic as wallet # CONSTANTS # ================================================================================================= diff --git a/crates/miden-standards/asm/standards/notes/swap.masm b/crates/miden-standards/asm/standards/notes/swap.masm index b837552f17..5134db3411 100644 --- a/crates/miden-standards/asm/standards/notes/swap.masm +++ b/crates/miden-standards/asm/standards/notes/swap.masm @@ -1,9 +1,9 @@ use miden::protocol::active_note use miden::protocol::asset use miden::protocol::output_note -use miden::protocol::note::NOTE_TYPE_PRIVATE +use {NOTE_TYPE_PRIVATE} from miden::protocol::note use miden::standards::notes::p2id -use miden::standards::wallets::basic->wallet +use miden::standards::wallets::basic as wallet # CONSTANTS # ================================================================================================= diff --git a/crates/miden-standards/asm/standards/wallets/basic.masm b/crates/miden-standards/asm/standards/wallets/basic.masm index 1fba824af8..c49eba92db 100644 --- a/crates/miden-standards/asm/standards/wallets/basic.masm +++ b/crates/miden-standards/asm/standards/wallets/basic.masm @@ -1,5 +1,5 @@ -use miden::protocol::asset::ASSET_VALUE_MEMORY_OFFSET -use miden::protocol::asset::ASSET_SIZE +use {ASSET_VALUE_MEMORY_OFFSET} from miden::protocol::asset +use {ASSET_SIZE} from miden::protocol::asset use miden::protocol::native_account use miden::protocol::output_note use miden::protocol::active_note diff --git a/crates/miden-standards/build.rs b/crates/miden-standards/build.rs index b5ce96b2db..843f86dd9d 100644 --- a/crates/miden-standards/build.rs +++ b/crates/miden-standards/build.rs @@ -1,11 +1,23 @@ +use std::collections::{BTreeMap, BTreeSet}; use std::env; use std::path::Path; use std::sync::Arc; use fs_err as fs; -use miden_assembly::diagnostics::{IntoDiagnostic, NamedSource, Result, WrapErr}; -use miden_assembly::{Assembler, Library}; +use miden_assembly::diagnostics::{IntoDiagnostic, Result, WrapErr}; +use miden_assembly::{ + Assembler, + Linkage, + ModuleParser, + Path as MasmPath, + Report, + SourceManager, + ast, +}; +use miden_assembly_syntax::Parse; +use miden_protocol::assembly::Library; use miden_protocol::transaction::TransactionKernel; +use miden_protocol::vm::Package; // CONSTANTS // ================================================================================================ @@ -21,13 +33,31 @@ const ACCOUNT_COMPONENTS_LIB_NAMESPACE: &str = "miden::standards::components"; const STANDARDS_ERRORS_RS_FILE: &str = "standards_errors.rs"; const STANDARDS_ERRORS_ARRAY_NAME: &str = "STANDARDS_ERRORS"; +struct ModuleSource { + file_path: std::path::PathBuf, + module_path: miden_assembly::PathBuf, + kind: ast::ModuleKind, +} + +impl Parse for ModuleSource { + fn parse( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> std::result::Result, Report> { + let mut parser = ModuleParser::new(Some(self.kind)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_file(Some(self.module_path.as_path()), self.file_path, source_manager) + } +} + // PRE-PROCESSING // ================================================================================================ /// Read and parse the contents from `./asm`. /// - Compiles the contents of asm/standards directory into a Miden library file (.masl) under /// standards namespace. Note scripts are included in this library. -/// - Compiles the contents of asm/account_components directory into individual .masl files. +/// - Compiles the contents of asm/account_components directory into individual .masp files. fn main() -> Result<()> { // re-build when the MASM code changes println!("cargo::rerun-if-changed={ASM_DIR}/"); @@ -46,7 +76,7 @@ fn main() -> Result<()> { // compile standards library (includes note scripts) let standards_lib = compile_standards_lib(&source_dir, &target_dir, assembler.clone())?; - assembler.link_static_library(standards_lib)?; + assembler.link_package(Arc::new(standards_lib), Linkage::Static)?; // compile account components compile_account_components( @@ -73,18 +103,29 @@ fn compile_standards_lib( ) -> Result { let source_dir = source_dir.join(ASM_STANDARDS_DIR); - let standards_lib = assembler.assemble_library_from_dir(source_dir, STANDARDS_LIB_NAMESPACE)?; + let namespace = MasmPath::new(STANDARDS_LIB_NAMESPACE); + let synthetic_dir = target_dir.join("synthetic").join("standards"); + let mut modules = read_modules_with_synthetic_parents( + &source_dir, + namespace, + &synthetic_dir, + ast::ModuleKind::Library, + )?; + let root = modules.remove(0); + let standards_lib = assembler + .assemble_library("miden-standards", root, modules) + .map(|package| *package)?; - let output_file = target_dir.join("standards").with_extension(Library::LIBRARY_EXTENSION); + let output_file = target_dir.join("standards").with_extension("masl"); standards_lib.write_to_file(output_file).into_diagnostic()?; - Ok(Arc::unwrap_or_clone(standards_lib)) + Ok(standards_lib) } // COMPILE ACCOUNT COMPONENTS // ================================================================================================ -/// Compiles the account components in `source_dir` into MASL libraries and stores the compiled +/// Compiles the account components in `source_dir` into MASP packages and stores the compiled /// files in `target_dir`, preserving the subdirectory structure. fn compile_account_components( source_dir: &Path, @@ -103,9 +144,6 @@ fn compile_account_components( .expect("file stem should be valid UTF-8") .to_owned(); - let component_source_code = fs::read_to_string(&masm_file_path) - .expect("reading the component's MASM source code should succeed"); - // Build full library path from directory structure: // e.g. faucets/fungible_faucet.masm -> // miden::standards::components::faucets::fungible_faucet @@ -118,11 +156,16 @@ fn compile_account_components( library_path.push_str("::"); library_path.push_str(part); } - let named_source = NamedSource::new(library_path, component_source_code); + let library_path = miden_assembly::PathBuf::new(&library_path).into_diagnostic()?; + let root = ModuleSource { + file_path: masm_file_path.clone(), + module_path: library_path, + kind: ast::ModuleKind::Library, + }; let component_library = assembler .clone() - .assemble_library([named_source]) + .assemble_library(component_name.as_str(), root, None::) .expect("library assembly should succeed"); // Preserve the subdirectory structure: compute relative path from source_dir @@ -137,13 +180,154 @@ fn compile_account_components( } let component_file_path = - output_dir.join(component_name).with_extension(Library::LIBRARY_EXTENSION); + output_dir.join(component_name).with_extension(Package::EXTENSION); component_library.write_to_file(component_file_path).into_diagnostic()?; } Ok(()) } +// HELPERS +// ================================================================================================ + +fn read_modules_with_synthetic_parents( + root: &Path, + namespace: &MasmPath, + synthetic_dir: &Path, + kind: ast::ModuleKind, +) -> Result> { + let real_files = shared::get_masm_files(root)?.into_iter().collect::>(); + let synthetic_files = write_synthetic_parent_modules(root, synthetic_dir, &real_files)?; + + let mut modules = Vec::with_capacity(real_files.len() + synthetic_files.len()); + + let root_synthetic = synthetic_files + .iter() + .find(|(relative_dir, _)| relative_dir.as_os_str().is_empty()) + .map(|(_, file_path)| file_path) + .expect("root synthetic module should always be generated"); + modules.push(ModuleSource { + file_path: root_synthetic.clone(), + module_path: miden_assembly::PathBuf::new(&namespace.to_string()).into_diagnostic()?, + kind, + }); + + let mut support_synthetic = synthetic_files + .into_iter() + .filter(|(relative_dir, _)| !relative_dir.as_os_str().is_empty()) + .collect::>(); + support_synthetic.sort_by(|a, b| a.0.cmp(&b.0)); + for (relative_dir, file_path) in support_synthetic { + let module_path = module_path_from_relative_dir(namespace, &relative_dir)?; + modules.push(ModuleSource { file_path, module_path, kind }); + } + + let mut real_files = real_files; + real_files.sort(); + for file_path in real_files { + let module_path = module_path_from_file(root, namespace, &file_path)?; + modules.push(ModuleSource { file_path, module_path, kind }); + } + + Ok(modules) +} + +fn write_synthetic_parent_modules( + root: &Path, + synthetic_dir: &Path, + real_files: &[std::path::PathBuf], +) -> Result> { + let mut children_by_dir = BTreeMap::>::new(); + let mut dirs_with_real_mod = BTreeSet::::new(); + + for file_path in real_files { + let relative = file_path.strip_prefix(root).into_diagnostic()?; + let parent = relative.parent().unwrap_or(Path::new("")).to_path_buf(); + let stem = file_path + .file_stem() + .expect("masm file should have a stem") + .to_string_lossy() + .to_string(); + + if stem == "mod" { + dirs_with_real_mod.insert(parent.clone()); + } else { + children_by_dir.entry(parent).or_default().insert(stem); + } + + let mut ancestor = std::path::PathBuf::new(); + for component in relative.parent().unwrap_or(Path::new("")).components() { + let child = component.as_os_str().to_string_lossy().to_string(); + children_by_dir.entry(ancestor.clone()).or_default().insert(child.clone()); + ancestor.push(child); + } + } + + fs::create_dir_all(synthetic_dir).into_diagnostic()?; + + let mut synthetic_files = Vec::new(); + for (relative_dir, children) in children_by_dir { + if dirs_with_real_mod.contains(&relative_dir) { + continue; + } + + let mut contents = String::new(); + for child in children { + contents.push_str("pub mod "); + contents.push_str(&child); + contents.push('\n'); + } + + let file_path = synthetic_dir.join(if relative_dir.as_os_str().is_empty() { + std::path::PathBuf::from("mod.masm") + } else { + relative_dir.join("mod.masm") + }); + if let Some(parent) = file_path.parent() { + fs::create_dir_all(parent).into_diagnostic()?; + } + fs::write(&file_path, contents).into_diagnostic()?; + synthetic_files.push((relative_dir, file_path)); + } + + Ok(synthetic_files) +} + +fn module_path_from_relative_dir( + namespace: &MasmPath, + relative_dir: &Path, +) -> Result { + let mut parts = namespace.to_string(); + + for component in relative_dir { + parts.push_str("::"); + parts.push_str(&component.to_string_lossy()); + } + + miden_assembly::PathBuf::new(&parts).into_diagnostic() +} + +fn module_path_from_file( + root: &Path, + namespace: &MasmPath, + file_path: &Path, +) -> Result { + let relative = file_path.strip_prefix(root).into_diagnostic()?; + let mut parts = namespace.to_string(); + + for component in relative { + let component = component.to_string_lossy(); + let component = component.strip_suffix(".masm").unwrap_or(&component); + if component == "mod" { + continue; + } + parts.push_str("::"); + parts.push_str(component); + } + + miden_assembly::PathBuf::new(&parts).into_diagnostic() +} + // ERROR CONSTANTS FILE GENERATION // ================================================================================================ diff --git a/crates/miden-standards/src/account/access/authority.rs b/crates/miden-standards/src/account/access/authority.rs index 8e497e527a..6589286ec8 100644 --- a/crates/miden-standards/src/account/access/authority.rs +++ b/crates/miden-standards/src/account/access/authority.rs @@ -31,7 +31,7 @@ use crate::procedure_root; // CONSTANTS // ================================================================================================ -account_component_code!(AUTHORITY_CODE, "access/authority.masl"); +account_component_code!(AUTHORITY_CODE, "access/authority.masp"); procedure_root!( AUTHORITY_FREEZE, diff --git a/crates/miden-standards/src/account/access/ownable2step.rs b/crates/miden-standards/src/account/access/ownable2step.rs index 1e6c1f2f28..e5342b9885 100644 --- a/crates/miden-standards/src/account/access/ownable2step.rs +++ b/crates/miden-standards/src/account/access/ownable2step.rs @@ -19,7 +19,7 @@ use miden_protocol::{Felt, Word}; use crate::account::account_component_code; -account_component_code!(OWNABLE2STEP_CODE, "access/ownable2step.masl"); +account_component_code!(OWNABLE2STEP_CODE, "access/ownable2step.masp"); static OWNER_CONFIG_SLOT_NAME: LazyLock = LazyLock::new(|| { StorageSlotName::new("miden::standards::access::ownable2step::owner_config") diff --git a/crates/miden-standards/src/account/access/pausable/manager.rs b/crates/miden-standards/src/account/access/pausable/manager.rs index 8ce5eca461..de947ed80c 100644 --- a/crates/miden-standards/src/account/access/pausable/manager.rs +++ b/crates/miden-standards/src/account/access/pausable/manager.rs @@ -7,7 +7,7 @@ use crate::procedure_root; // PAUSABLE MANAGER COMPONENT // ================================================================================================ -account_component_code!(PAUSABLE_MANAGER_CODE, "access/pausable/manager.masl"); +account_component_code!(PAUSABLE_MANAGER_CODE, "access/pausable/manager.masp"); procedure_root!( PAUSABLE_MANAGER_PAUSE, diff --git a/crates/miden-standards/src/account/access/pausable/mod.rs b/crates/miden-standards/src/account/access/pausable/mod.rs index eea1b42c55..d4b102cfcb 100644 --- a/crates/miden-standards/src/account/access/pausable/mod.rs +++ b/crates/miden-standards/src/account/access/pausable/mod.rs @@ -22,7 +22,7 @@ pub use manager::PausableManager; // IS_PAUSED STORAGE // ================================================================================================ -account_component_code!(PAUSABLE_CODE, "access/pausable/mod.masl"); +account_component_code!(PAUSABLE_CODE, "access/pausable/mod.masp"); static IS_PAUSED_SLOT_NAME: LazyLock = LazyLock::new(|| { StorageSlotName::new("miden::standards::access::pausable::is_paused") diff --git a/crates/miden-standards/src/account/access/rbac.rs b/crates/miden-standards/src/account/access/rbac.rs index 7a53bd9fa1..5625982524 100644 --- a/crates/miden-standards/src/account/access/rbac.rs +++ b/crates/miden-standards/src/account/access/rbac.rs @@ -18,7 +18,7 @@ use miden_protocol::utils::sync::LazyLock; use crate::account::account_component_code; -account_component_code!(RBAC_CODE, "access/rbac.masl"); +account_component_code!(RBAC_CODE, "access/rbac.masp"); static ROLE_CONFIG_SLOT_NAME: LazyLock = LazyLock::new(|| { StorageSlotName::new("miden::standards::access::rbac::role_config") diff --git a/crates/miden-standards/src/account/auth/guarded_multisig.rs b/crates/miden-standards/src/account/auth/guarded_multisig.rs index 0b3ee75360..9765b020f1 100644 --- a/crates/miden-standards/src/account/auth/guarded_multisig.rs +++ b/crates/miden-standards/src/account/auth/guarded_multisig.rs @@ -25,7 +25,7 @@ use super::multisig::{AuthMultisig, AuthMultisigConfig}; use super::{Approver, ApproverSet}; use crate::account::account_component_code; -account_component_code!(GUARDED_MULTISIG_CODE, "auth/guarded_multisig.masl"); +account_component_code!(GUARDED_MULTISIG_CODE, "auth/guarded_multisig.masp"); // CONSTANTS // ================================================================================================ diff --git a/crates/miden-standards/src/account/auth/multisig.rs b/crates/miden-standards/src/account/auth/multisig.rs index 6699d858a3..6729fb540b 100644 --- a/crates/miden-standards/src/account/auth/multisig.rs +++ b/crates/miden-standards/src/account/auth/multisig.rs @@ -24,7 +24,7 @@ use miden_protocol::utils::sync::LazyLock; use super::{Approver, ApproverSet}; use crate::account::account_component_code; -account_component_code!(MULTISIG_CODE, "auth/multisig.masl"); +account_component_code!(MULTISIG_CODE, "auth/multisig.masp"); // CONSTANTS // ================================================================================================ diff --git a/crates/miden-standards/src/account/auth/multisig_smart/component.rs b/crates/miden-standards/src/account/auth/multisig_smart/component.rs index 89e5afe5b7..4a189cef94 100644 --- a/crates/miden-standards/src/account/auth/multisig_smart/component.rs +++ b/crates/miden-standards/src/account/auth/multisig_smart/component.rs @@ -31,7 +31,7 @@ use super::ProcedurePolicy; use crate::account::account_component_code; use crate::account::auth::{Approver, ApproverSet, AuthMultisig}; -account_component_code!(MULTISIG_SMART_CODE, "auth/multisig_smart.masl"); +account_component_code!(MULTISIG_SMART_CODE, "auth/multisig_smart.masp"); // CONSTANTS // ================================================================================================ diff --git a/crates/miden-standards/src/account/auth/network_account/auth_network_account.rs b/crates/miden-standards/src/account/auth/network_account/auth_network_account.rs index 56322f66cc..03d28bf651 100644 --- a/crates/miden-standards/src/account/auth/network_account/auth_network_account.rs +++ b/crates/miden-standards/src/account/auth/network_account/auth_network_account.rs @@ -18,7 +18,7 @@ use super::{ }; use crate::account::account_component_code; -account_component_code!(NETWORK_ACCOUNT_AUTH_CODE, "auth/network_account.masl"); +account_component_code!(NETWORK_ACCOUNT_AUTH_CODE, "auth/network_account.masp"); // AUTH NETWORK ACCOUNT // ================================================================================================ diff --git a/crates/miden-standards/src/account/auth/no_auth.rs b/crates/miden-standards/src/account/auth/no_auth.rs index d3bc0568af..678cd5587b 100644 --- a/crates/miden-standards/src/account/auth/no_auth.rs +++ b/crates/miden-standards/src/account/auth/no_auth.rs @@ -3,7 +3,7 @@ use miden_protocol::account::{AccountComponent, AccountComponentName}; use crate::account::account_component_code; -account_component_code!(NO_AUTH_CODE, "auth/no_auth.masl"); +account_component_code!(NO_AUTH_CODE, "auth/no_auth.masp"); /// An [`AccountComponent`] implementing a no-authentication scheme. /// diff --git a/crates/miden-standards/src/account/auth/singlesig.rs b/crates/miden-standards/src/account/auth/singlesig.rs index 61359f2c28..13651f92f9 100644 --- a/crates/miden-standards/src/account/auth/singlesig.rs +++ b/crates/miden-standards/src/account/auth/singlesig.rs @@ -19,7 +19,7 @@ use miden_protocol::utils::sync::LazyLock; use super::Approver; use crate::account::account_component_code; -account_component_code!(SINGLESIG_CODE, "auth/singlesig.masl"); +account_component_code!(SINGLESIG_CODE, "auth/singlesig.masp"); // CONSTANTS // ================================================================================================ diff --git a/crates/miden-standards/src/account/auth/singlesig_acl.rs b/crates/miden-standards/src/account/auth/singlesig_acl.rs index 776166ab85..4449092705 100644 --- a/crates/miden-standards/src/account/auth/singlesig_acl.rs +++ b/crates/miden-standards/src/account/auth/singlesig_acl.rs @@ -25,7 +25,7 @@ use miden_protocol::utils::sync::LazyLock; use super::Approver; use crate::account::account_component_code; -account_component_code!(SINGLESIG_ACL_CODE, "auth/singlesig_acl.masl"); +account_component_code!(SINGLESIG_ACL_CODE, "auth/singlesig_acl.masp"); // CONSTANTS // ================================================================================================ diff --git a/crates/miden-standards/src/account/faucets/fungible/mod.rs b/crates/miden-standards/src/account/faucets/fungible/mod.rs index 66353b11a8..3d98dca1fe 100644 --- a/crates/miden-standards/src/account/faucets/fungible/mod.rs +++ b/crates/miden-standards/src/account/faucets/fungible/mod.rs @@ -65,7 +65,7 @@ const TOKEN_SYMBOL_TYPE: &str = "miden::standards::faucets::fungible::token_symb // FUNGIBLE FAUCET ACCOUNT COMPONENT // ================================================================================================ -account_component_code!(FUNGIBLE_FAUCET_CODE, "faucets/fungible_faucet.masl"); +account_component_code!(FUNGIBLE_FAUCET_CODE, "faucets/fungible_faucet.masp"); // Initialize the procedure root of the `mint_and_send` procedure of the Fungible Faucet only once. procedure_root!( diff --git a/crates/miden-standards/src/account/faucets/non_fungible/mod.rs b/crates/miden-standards/src/account/faucets/non_fungible/mod.rs index 44e440d2fc..cb85754637 100644 --- a/crates/miden-standards/src/account/faucets/non_fungible/mod.rs +++ b/crates/miden-standards/src/account/faucets/non_fungible/mod.rs @@ -64,7 +64,7 @@ pub(crate) static ASSET_STATUS_SLOT: LazyLock = LazyLock::new(| // NON-FUNGIBLE FAUCET ACCOUNT COMPONENT // ================================================================================================ -account_component_code!(NON_FUNGIBLE_FAUCET_CODE, "faucets/non_fungible_faucet.masl"); +account_component_code!(NON_FUNGIBLE_FAUCET_CODE, "faucets/non_fungible_faucet.masp"); procedure_root!( NON_FUNGIBLE_FAUCET_MINT_AND_SEND, diff --git a/crates/miden-standards/src/account/metadata/code_inspection.rs b/crates/miden-standards/src/account/metadata/code_inspection.rs index 941a3cb278..aac4301c67 100644 --- a/crates/miden-standards/src/account/metadata/code_inspection.rs +++ b/crates/miden-standards/src/account/metadata/code_inspection.rs @@ -7,7 +7,7 @@ use crate::procedure_root; // CODE INSPECTION // ================================================================================================ -account_component_code!(CODE_INSPECTION_CODE, "metadata/code_inspection.masl"); +account_component_code!(CODE_INSPECTION_CODE, "metadata/code_inspection.masp"); // Initialize the procedure root of the `has_procedure` procedure only once. procedure_root!( diff --git a/crates/miden-standards/src/account/metadata/schema_commitment.rs b/crates/miden-standards/src/account/metadata/schema_commitment.rs index 633c4caa4a..78c43ac8ca 100644 --- a/crates/miden-standards/src/account/metadata/schema_commitment.rs +++ b/crates/miden-standards/src/account/metadata/schema_commitment.rs @@ -35,7 +35,7 @@ use miden_protocol::utils::sync::LazyLock; static STORAGE_SCHEMA_LIBRARY: LazyLock = LazyLock::new(|| { let bytes = include_bytes!(concat!( env!("OUT_DIR"), - "/assets/account_components/metadata/schema_commitment.masl" + "/assets/account_components/metadata/schema_commitment.masp" )); Library::read_from_bytes(bytes).expect("Shipped Storage Schema library is well-formed") }); diff --git a/crates/miden-standards/src/account/mod.rs b/crates/miden-standards/src/account/mod.rs index fb928f2801..2903771c4f 100644 --- a/crates/miden-standards/src/account/mod.rs +++ b/crates/miden-standards/src/account/mod.rs @@ -54,7 +54,7 @@ macro_rules! procedure_root { }; } -/// Macro to declare a static `LazyLock` initialized from a `.masl` asset +/// Macro to declare a static `LazyLock` initialized from a `.masp` asset /// shipped by the `miden-standards` build script. /// /// `$relative_path` is appended to `concat!(env!("OUT_DIR"), "/assets/account_components/")` and @@ -68,7 +68,7 @@ macro_rules! procedure_root { /// /// # Example /// ```ignore -/// account_component_code!(BASIC_WALLET_CODE, "wallets/basic_wallet.masl"); +/// account_component_code!(BASIC_WALLET_CODE, "wallets/basic_wallet.masp"); /// ``` macro_rules! account_component_code { ($name:ident, $relative_path:expr) => { diff --git a/crates/miden-standards/src/account/policies/burn/allow_all.rs b/crates/miden-standards/src/account/policies/burn/allow_all.rs index c63aed86d0..cea4fa8a40 100644 --- a/crates/miden-standards/src/account/policies/burn/allow_all.rs +++ b/crates/miden-standards/src/account/policies/burn/allow_all.rs @@ -7,7 +7,7 @@ use crate::procedure_root; // ALLOW-ALL BURN POLICY // ================================================================================================ -account_component_code!(ALLOW_ALL_BURN_POLICY_CODE, "faucets/policies/burn/allow_all.masl"); +account_component_code!(ALLOW_ALL_BURN_POLICY_CODE, "faucets/policies/burn/allow_all.masp"); procedure_root!( ALLOW_ALL_POLICY_ROOT, diff --git a/crates/miden-standards/src/account/policies/burn/min_burn_amount.rs b/crates/miden-standards/src/account/policies/burn/min_burn_amount.rs index c3498d1357..c63f69a48c 100644 --- a/crates/miden-standards/src/account/policies/burn/min_burn_amount.rs +++ b/crates/miden-standards/src/account/policies/burn/min_burn_amount.rs @@ -24,7 +24,7 @@ use crate::procedure_root; account_component_code!( MIN_BURN_AMOUNT_BURN_POLICY_CODE, - "faucets/policies/burn/min_burn_amount.masl" + "faucets/policies/burn/min_burn_amount.masp" ); procedure_root!( diff --git a/crates/miden-standards/src/account/policies/burn/owner_only.rs b/crates/miden-standards/src/account/policies/burn/owner_only.rs index 4b11793acd..df95b9946c 100644 --- a/crates/miden-standards/src/account/policies/burn/owner_only.rs +++ b/crates/miden-standards/src/account/policies/burn/owner_only.rs @@ -9,7 +9,7 @@ use crate::procedure_root; account_component_code!( OWNER_ONLY_BURN_POLICY_CODE, - "faucets/policies/burn/owner_controlled/owner_only.masl" + "faucets/policies/burn/owner_controlled/owner_only.masp" ); procedure_root!( diff --git a/crates/miden-standards/src/account/policies/manager.rs b/crates/miden-standards/src/account/policies/manager.rs index 22a0e971a4..bbe8ce50ba 100644 --- a/crates/miden-standards/src/account/policies/manager.rs +++ b/crates/miden-standards/src/account/policies/manager.rs @@ -39,7 +39,7 @@ use super::transfer::TransferPolicy; use crate::account::account_component_code; use crate::procedure_root; -account_component_code!(POLICY_MANAGER_CODE, "faucets/policies/policy_manager.masl"); +account_component_code!(POLICY_MANAGER_CODE, "faucets/policies/policy_manager.masp"); // PROCEDURE ROOTS // ================================================================================================ diff --git a/crates/miden-standards/src/account/policies/mint/allow_all.rs b/crates/miden-standards/src/account/policies/mint/allow_all.rs index 69add8cfa1..bd1b5af64c 100644 --- a/crates/miden-standards/src/account/policies/mint/allow_all.rs +++ b/crates/miden-standards/src/account/policies/mint/allow_all.rs @@ -7,7 +7,7 @@ use crate::procedure_root; // ALLOW-ALL MINT POLICY // ================================================================================================ -account_component_code!(ALLOW_ALL_MINT_POLICY_CODE, "faucets/policies/mint/allow_all.masl"); +account_component_code!(ALLOW_ALL_MINT_POLICY_CODE, "faucets/policies/mint/allow_all.masp"); procedure_root!( ALLOW_ALL_POLICY_ROOT, diff --git a/crates/miden-standards/src/account/policies/mint/owner_only.rs b/crates/miden-standards/src/account/policies/mint/owner_only.rs index f94f16c0ac..e60d0aa342 100644 --- a/crates/miden-standards/src/account/policies/mint/owner_only.rs +++ b/crates/miden-standards/src/account/policies/mint/owner_only.rs @@ -9,7 +9,7 @@ use crate::procedure_root; account_component_code!( OWNER_ONLY_MINT_POLICY_CODE, - "faucets/policies/mint/owner_controlled/owner_only.masl" + "faucets/policies/mint/owner_controlled/owner_only.masp" ); procedure_root!( diff --git a/crates/miden-standards/src/account/policies/transfer/allow_all.rs b/crates/miden-standards/src/account/policies/transfer/allow_all.rs index 86239708a7..ead729aac4 100644 --- a/crates/miden-standards/src/account/policies/transfer/allow_all.rs +++ b/crates/miden-standards/src/account/policies/transfer/allow_all.rs @@ -7,7 +7,7 @@ use crate::procedure_root; // ALLOW-ALL TRANSFER POLICY // ================================================================================================ -account_component_code!(ALLOW_ALL_TRANSFER_POLICY_CODE, "faucets/policies/transfer/allow_all.masl"); +account_component_code!(ALLOW_ALL_TRANSFER_POLICY_CODE, "faucets/policies/transfer/allow_all.masp"); procedure_root!( ALLOW_ALL_TRANSFER_POLICY_ROOT, diff --git a/crates/miden-standards/src/account/policies/transfer/allowlist/owner_controlled.rs b/crates/miden-standards/src/account/policies/transfer/allowlist/owner_controlled.rs index e62aa2dc13..914405b353 100644 --- a/crates/miden-standards/src/account/policies/transfer/allowlist/owner_controlled.rs +++ b/crates/miden-standards/src/account/policies/transfer/allowlist/owner_controlled.rs @@ -5,7 +5,7 @@ use crate::account::account_component_code; account_component_code!( ALLOWLIST_OWNER_CONTROLLED_CODE, - "faucets/policies/transfer/allowlist/owner_controlled.masl" + "faucets/policies/transfer/allowlist/owner_controlled.masp" ); /// Account component that exposes `allow_account` and `disallow_account` admin procedures gated diff --git a/crates/miden-standards/src/account/policies/transfer/basic_allowlist.rs b/crates/miden-standards/src/account/policies/transfer/basic_allowlist.rs index 7243f9c8b5..0c89141459 100644 --- a/crates/miden-standards/src/account/policies/transfer/basic_allowlist.rs +++ b/crates/miden-standards/src/account/policies/transfer/basic_allowlist.rs @@ -16,7 +16,7 @@ use crate::procedure_root; account_component_code!( BASIC_ALLOWLIST_TRANSFER_POLICY_CODE, - "faucets/policies/transfer/basic_allowlist.masl" + "faucets/policies/transfer/basic_allowlist.masp" ); procedure_root!( diff --git a/crates/miden-standards/src/account/policies/transfer/basic_blocklist.rs b/crates/miden-standards/src/account/policies/transfer/basic_blocklist.rs index 0606652b0d..92413919d1 100644 --- a/crates/miden-standards/src/account/policies/transfer/basic_blocklist.rs +++ b/crates/miden-standards/src/account/policies/transfer/basic_blocklist.rs @@ -16,7 +16,7 @@ use crate::procedure_root; account_component_code!( BASIC_BLOCKLIST_TRANSFER_POLICY_CODE, - "faucets/policies/transfer/basic_blocklist.masl" + "faucets/policies/transfer/basic_blocklist.masp" ); procedure_root!( diff --git a/crates/miden-standards/src/account/policies/transfer/blocklist/owner_controlled.rs b/crates/miden-standards/src/account/policies/transfer/blocklist/owner_controlled.rs index 37ad7c1d4c..0605a717c0 100644 --- a/crates/miden-standards/src/account/policies/transfer/blocklist/owner_controlled.rs +++ b/crates/miden-standards/src/account/policies/transfer/blocklist/owner_controlled.rs @@ -5,7 +5,7 @@ use crate::account::account_component_code; account_component_code!( BLOCKLIST_OWNER_CONTROLLED_CODE, - "faucets/policies/transfer/blocklist/owner_controlled.masl" + "faucets/policies/transfer/blocklist/owner_controlled.masp" ); /// Account component that exposes `block_account` and `unblock_account` admin procedures gated diff --git a/crates/miden-standards/src/account/wallets/mod.rs b/crates/miden-standards/src/account/wallets/mod.rs index be86f680f5..36a3c2c4b8 100644 --- a/crates/miden-standards/src/account/wallets/mod.rs +++ b/crates/miden-standards/src/account/wallets/mod.rs @@ -27,7 +27,7 @@ use crate::procedure_root; // BASIC WALLET // ================================================================================================ -account_component_code!(BASIC_WALLET_CODE, "wallets/basic_wallet.masl"); +account_component_code!(BASIC_WALLET_CODE, "wallets/basic_wallet.masp"); // Initialize the procedure root of the `receive_asset` procedure of the Basic Wallet only once. procedure_root!( diff --git a/crates/miden-standards/src/code_builder/mod.rs b/crates/miden-standards/src/code_builder/mod.rs index 9bb240d79f..7c8e3ebfe4 100644 --- a/crates/miden-standards/src/code_builder/mod.rs +++ b/crates/miden-standards/src/code_builder/mod.rs @@ -1,14 +1,23 @@ +use alloc::borrow::Cow; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; use alloc::sync::Arc; use alloc::vec::Vec; use miden_protocol::account::AccountComponentCode; +use miden_protocol::assembly::diagnostics::Report; use miden_protocol::assembly::{ Assembler, DefaultSourceManager, Library, + Linkage, + Module, + ModuleKind, + ModuleParser, Parse, - ParseOptions, Path, + SourceFile, + SourceManager, SourceManagerSync, }; use miden_protocol::note::NoteScript; @@ -19,6 +28,150 @@ use miden_protocol::{Felt, Word}; use crate::errors::CodeBuilderError; use crate::standards_lib::StandardsLib; +const NOTE_SCRIPT_MODULE_PATH: &str = "::note_script"; + +/// A value that can provide a compiled Miden library to the code builder. +pub trait CodeBuilderLibrary { + fn as_code_builder_library(&self) -> &Library; +} + +impl CodeBuilderLibrary for &T +where + T: CodeBuilderLibrary + ?Sized, +{ + fn as_code_builder_library(&self) -> &Library { + (*self).as_code_builder_library() + } +} + +impl CodeBuilderLibrary for Library { + fn as_code_builder_library(&self) -> &Library { + self + } +} + +impl CodeBuilderLibrary for Box { + fn as_code_builder_library(&self) -> &Library { + self + } +} + +impl CodeBuilderLibrary for AccountComponentCode { + fn as_code_builder_library(&self) -> &Library { + self.as_library() + } +} + +/// A source value that can be compiled into a note script. +pub trait CodeBuilderNoteScriptSource { + fn parse_note_script( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> Result, Report>; +} + +fn parse_note_script_str( + source: impl AsRef, + warnings_as_errors: bool, + source_manager: Arc, +) -> Result, Report> { + let mut parser = ModuleParser::new(Some(ModuleKind::Library)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_str(Some(Path::new(NOTE_SCRIPT_MODULE_PATH)), source.as_ref(), source_manager) +} + +fn set_default_note_script_path(mut module: Box) -> Box { + if module.path().is_empty() { + module.set_path(Path::new(NOTE_SCRIPT_MODULE_PATH)); + } + module +} + +macro_rules! impl_note_script_source_for_str { + ($($source:ty),* $(,)?) => { + $( + impl CodeBuilderNoteScriptSource for $source { + fn parse_note_script( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> Result, Report> { + parse_note_script_str(self, warnings_as_errors, source_manager) + } + } + )* + }; +} + +impl_note_script_source_for_str!(&str, &String, String, Box, Cow<'_, str>); + +impl CodeBuilderNoteScriptSource for Arc { + fn parse_note_script( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> Result, Report> { + let mut parser = ModuleParser::new(Some(ModuleKind::Library)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse(Some(Path::new(NOTE_SCRIPT_MODULE_PATH)), self, source_manager) + } +} + +impl CodeBuilderNoteScriptSource for Module { + fn parse_note_script( + self, + _warnings_as_errors: bool, + _source_manager: Arc, + ) -> Result, Report> { + Ok(set_default_note_script_path(Box::new(self))) + } +} + +impl CodeBuilderNoteScriptSource for Box { + fn parse_note_script( + self, + _warnings_as_errors: bool, + _source_manager: Arc, + ) -> Result, Report> { + Ok(set_default_note_script_path(self)) + } +} + +impl CodeBuilderNoteScriptSource for Arc { + fn parse_note_script( + self, + _warnings_as_errors: bool, + _source_manager: Arc, + ) -> Result, Report> { + Ok(set_default_note_script_path(Box::new(Arc::unwrap_or_clone(self)))) + } +} + +#[cfg(feature = "std")] +impl CodeBuilderNoteScriptSource for &std::path::Path { + fn parse_note_script( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> Result, Report> { + let mut parser = ModuleParser::new(Some(ModuleKind::Library)); + parser.set_warnings_as_errors(warnings_as_errors); + parser.parse_file(Some(Path::new(NOTE_SCRIPT_MODULE_PATH)), self, source_manager) + } +} + +#[cfg(feature = "std")] +impl CodeBuilderNoteScriptSource for std::path::PathBuf { + fn parse_note_script( + self, + warnings_as_errors: bool, + source_manager: Arc, + ) -> Result, Report> { + self.as_path().parse_note_script(warnings_as_errors, source_manager) + } +} + // CODE BUILDER // ================================================================================================ @@ -59,14 +212,15 @@ use crate::standards_lib::StandardsLib; /// ```no_run /// # use anyhow::Context; /// # use miden_standards::code_builder::CodeBuilder; +/// # use miden_standards::StandardsLib; /// # use miden_protocol::assembly::Library; -/// # use miden_protocol::CoreLibrary; +/// # use miden_protocol::ProtocolLib; /// # fn example() -> anyhow::Result<()> { /// # let module_code = "pub proc test push.1 add end"; /// # let script_code = "begin nop end"; /// # // Create sample libraries for the example -/// # let my_lib: Library = CoreLibrary::default().into(); // Convert CoreLibrary to Library -/// # let fpi_lib: Library = CoreLibrary::default().into(); +/// # let my_lib: Library = StandardsLib::default().into(); +/// # let fpi_lib: Library = ProtocolLib::default().into(); /// let script = CodeBuilder::default() /// .with_linked_module("my::module", module_code).context("failed to link module")? /// .with_statically_linked_library(&my_lib).context("failed to link static library")? @@ -101,8 +255,10 @@ impl CodeBuilder { /// # Arguments /// * `source_manager` - The source manager to use with the internal `Assembler` pub fn with_source_manager(source_manager: Arc) -> Self { - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()) - .with_dynamic_library(StandardsLib::default()) + let mut assembler = + TransactionKernel::assembler_with_source_manager(source_manager.clone()); + assembler + .link_package(Arc::new(StandardsLib::default().into()), Linkage::Dynamic) .expect("linking std lib should work"); Self { assembler, @@ -143,14 +299,14 @@ impl CodeBuilder { pub fn link_module( &mut self, module_path: impl AsRef, - module_code: impl Parse, + module_code: impl ToString, ) -> Result<(), CodeBuilderError> { - let mut parse_options = ParseOptions::for_library(); - parse_options.path = Some(Path::new(module_path.as_ref()).into()); - - let module = module_code.parse_with_options(self.source_manager(), parse_options).map_err( - |err| CodeBuilderError::build_error_with_report("failed to parse module code", err), - )?; + let mut parser = ModuleParser::new(Some(ModuleKind::Library)); + let module = parser + .parse_str(Some(Path::new(module_path.as_ref())), module_code, self.source_manager()) + .map_err(|err| { + CodeBuilderError::build_error_with_report("failed to parse module code", err) + })?; self.assembler.compile_and_statically_link(module).map_err(|err| { CodeBuilderError::build_error_with_report("failed to assemble module", err) @@ -171,9 +327,11 @@ impl CodeBuilder { /// Returns an error if: /// - adding the library to the assembler failed pub fn link_static_library(&mut self, library: &Library) -> Result<(), CodeBuilderError> { - self.assembler.link_static_library(library).map_err(|err| { - CodeBuilderError::build_error_with_report("failed to add static library", err) - }) + self.assembler + .link_package(Arc::new(library.clone()), Linkage::Static) + .map_err(|err| { + CodeBuilderError::build_error_with_report("failed to add static library", err) + }) } /// Dynamically links a library. @@ -190,9 +348,11 @@ impl CodeBuilder { /// # Errors /// Returns an error if the library cannot be added to the assembler pub fn link_dynamic_library(&mut self, library: &Library) -> Result<(), CodeBuilderError> { - self.assembler.link_dynamic_library(library).map_err(|err| { - CodeBuilderError::build_error_with_report("failed to add dynamic library", err) - }) + self.assembler + .link_package(Arc::new(library.clone()), Linkage::Dynamic) + .map_err(|err| { + CodeBuilderError::build_error_with_report("failed to add dynamic library", err) + }) } /// Builder-style method to statically link a library and return the modified builder. @@ -223,9 +383,9 @@ impl CodeBuilder { /// Returns an error if the library cannot be added to the assembler pub fn with_dynamically_linked_library( mut self, - library: impl AsRef, + library: impl CodeBuilderLibrary, ) -> Result { - self.link_dynamic_library(library.as_ref())?; + self.link_dynamic_library(library.as_code_builder_library())?; Ok(self) } @@ -242,7 +402,7 @@ impl CodeBuilder { pub fn with_linked_module( mut self, module_path: impl AsRef, - module_code: impl Parse, + module_code: impl ToString, ) -> Result { self.link_module(module_path, module_code)?; Ok(self) @@ -334,27 +494,25 @@ impl CodeBuilder { pub fn compile_component_code( self, component_path: impl AsRef, - component_code: impl Parse, + component_code: impl ToString, ) -> Result { let CodeBuilder { assembler, source_manager, advice_map } = self; - let mut parse_options = ParseOptions::for_library(); - parse_options.path = Some(Path::new(component_path.as_ref()).into()); - - let module = - component_code - .parse_with_options(source_manager, parse_options) - .map_err(|err| { - CodeBuilderError::build_error_with_report("failed to parse component code", err) - })?; + let mut parser = ModuleParser::new(Some(ModuleKind::Library)); + let module = parser + .parse_str(Some(Path::new(component_path.as_ref())), component_code, source_manager) + .map_err(|err| { + CodeBuilderError::build_error_with_report("failed to parse component code", err) + })?; - let library = assembler.assemble_library([module]).map_err(|err| { - CodeBuilderError::build_error_with_report("failed to parse component code", err) - })?; + let library = assembler + .assemble_library("account-component", module, None::>) + .map_err(|err| { + CodeBuilderError::build_error_with_report("failed to parse component code", err) + })?; Ok(AccountComponentCode::from(Self::apply_advice_map_to_library( - advice_map, - Arc::unwrap_or_clone(library), + advice_map, *library, ))) } @@ -374,9 +532,18 @@ impl CodeBuilder { ) -> Result { let CodeBuilder { assembler, advice_map, .. } = self; - let program = assembler.assemble_program(tx_script).map_err(|err| { - CodeBuilderError::build_error_with_report("failed to parse transaction script", err) - })?; + let program = assembler + .assemble_program("transaction-script", tx_script) + .map_err(|err| { + CodeBuilderError::build_error_with_report("failed to parse transaction script", err) + })? + .try_into_program() + .map_err(|err| { + CodeBuilderError::build_error_with_report( + "failed to convert transaction script package", + err, + ) + })?; Ok(TransactionScript::new(Self::apply_advice_map(advice_map, program))) } @@ -392,23 +559,37 @@ impl CodeBuilder { /// # Errors /// Returns an error if: /// - The note script compiling fails - pub fn compile_note_script(self, source: impl Parse) -> Result { - let CodeBuilder { assembler, advice_map, .. } = self; - - let note_script_lib = assembler.assemble_library([source]).map_err(|err| { - CodeBuilderError::build_error_with_report("failed to parse note script library", err) - })?; + pub fn compile_note_script( + self, + source: impl CodeBuilderNoteScriptSource, + ) -> Result { + let CodeBuilder { assembler, source_manager, advice_map } = self; - NoteScript::from_library(&Self::apply_advice_map_to_library( - advice_map, - Arc::unwrap_or_clone(note_script_lib), - )) - .map_err(|err| { - CodeBuilderError::build_error_with_source( - "failed to create note script from library", - err, - ) - }) + let module = source + .parse_note_script(assembler.warnings_as_errors(), source_manager) + .map_err(|err| { + CodeBuilderError::build_error_with_report( + "failed to parse note script library", + err, + ) + })?; + + let note_script_lib = assembler + .assemble_library("note-script", module, None::>) + .map_err(|err| { + CodeBuilderError::build_error_with_report( + "failed to parse note script library", + err, + ) + })?; + + NoteScript::from_library(&Self::apply_advice_map_to_library(advice_map, *note_script_lib)) + .map_err(|err| { + CodeBuilderError::build_error_with_source( + "failed to create note script from library", + err, + ) + }) } // ACCESSORS @@ -431,11 +612,7 @@ impl CodeBuilder { /// from the kernel library to test them individually. #[cfg(any(feature = "testing", test))] pub fn with_kernel_library(source_manager: Arc) -> Self { - let mut builder = Self::with_source_manager(source_manager); - builder - .link_dynamic_library(&TransactionKernel::library()) - .expect("failed to link kernel library"); - builder + Self::with_source_manager(source_manager) } /// Returns a [`CodeBuilder`] with the `mock::{account, faucet, util}` libraries. @@ -473,11 +650,6 @@ impl CodeBuilder { // standards library. let mut builder = Self::with_source_manager(source_manager); - // Expose kernel procedures under `$kernel` for testing. - builder - .link_dynamic_library(&TransactionKernel::library()) - .expect("failed to link kernel library"); - // Add mock account/faucet libs (built in debug mode) and mock util. for library in Self::mock_libraries() { builder @@ -510,7 +682,6 @@ impl From for Assembler { #[cfg(test)] mod tests { use anyhow::Context; - use miden_protocol::assembly::diagnostics::NamedSource; use miden_protocol::testing::note::DEFAULT_NOTE_SCRIPT; use super::*; @@ -694,15 +865,31 @@ mod tests { "; // Create libraries using the assembler - let temp_assembler = TransactionKernel::assembler(); + let source_manager = Arc::new(DefaultSourceManager::default()); + let mut parser = ModuleParser::new(Some(ModuleKind::Library)); + let static_module = parser + .parse_str( + Some(Path::new("contracts::static_contract")), + account_code_1, + source_manager.clone(), + ) + .map_err(|e| anyhow::anyhow!("failed to parse static library: {}", e))?; + let dynamic_module = parser + .parse_str( + Some(Path::new("contracts::dynamic_contract")), + account_code_2, + source_manager.clone(), + ) + .map_err(|e| anyhow::anyhow!("failed to parse dynamic library: {}", e))?; + let temp_assembler = TransactionKernel::assembler_with_source_manager(source_manager); let static_lib = temp_assembler .clone() - .assemble_library([NamedSource::new("contracts::static_contract", account_code_1)]) + .assemble_library("static-contract", static_module, None::<&str>) .map_err(|e| anyhow::anyhow!("failed to assemble static library: {}", e))?; let dynamic_lib = temp_assembler - .assemble_library([NamedSource::new("contracts::dynamic_contract", account_code_2)]) + .assemble_library("dynamic-contract", dynamic_module, None::<&str>) .map_err(|e| anyhow::anyhow!("failed to assemble dynamic library: {}", e))?; // Test linking both static and dynamic libraries diff --git a/crates/miden-standards/src/testing/mock_account_code.rs b/crates/miden-standards/src/testing/mock_account_code.rs index d0e365d1ef..a2b8e6a7fe 100644 --- a/crates/miden-standards/src/testing/mock_account_code.rs +++ b/crates/miden-standards/src/testing/mock_account_code.rs @@ -27,8 +27,8 @@ const MOCK_ACCOUNT_CODE: &str = " use miden::protocol::native_account use miden::protocol::tx - pub use ::miden::standards::wallets::basic::receive_asset - pub use ::miden::standards::wallets::basic::move_asset_to_note + pub use {receive_asset} from ::miden::standards::wallets::basic + pub use {move_asset_to_note} from ::miden::standards::wallets::basic # Note: all account's export procedures below should be only called or dyncall'ed, so it # is assumed that the operand stack at the beginning of their execution is pad'ed and diff --git a/crates/miden-standards/src/testing/mock_util_lib.rs b/crates/miden-standards/src/testing/mock_util_lib.rs index 7fce87a5c3..c2c5fa2653 100644 --- a/crates/miden-standards/src/testing/mock_util_lib.rs +++ b/crates/miden-standards/src/testing/mock_util_lib.rs @@ -1,7 +1,13 @@ use alloc::sync::Arc; -use miden_protocol::assembly::Library; -use miden_protocol::assembly::diagnostics::NamedSource; +use miden_protocol::assembly::{ + DefaultSourceManager, + Library, + Linkage, + ModuleKind, + ModuleParser, + Path, +}; use miden_protocol::transaction::TransactionKernel; use miden_protocol::utils::sync::LazyLock; @@ -9,8 +15,8 @@ use crate::StandardsLib; const MOCK_UTIL_LIBRARY_CODE: &str = " use miden::protocol::output_note - use miden::protocol::note::NOTE_TYPE_PRIVATE - use miden::standards::wallets::basic->wallet + use {NOTE_TYPE_PRIVATE} from miden::protocol::note + use miden::standards::wallets::basic as wallet #! Inputs: [] #! Outputs: [note_idx] @@ -63,13 +69,17 @@ const MOCK_UTIL_LIBRARY_CODE: &str = " "; static MOCK_UTIL_LIBRARY: LazyLock = LazyLock::new(|| { - Arc::unwrap_or_clone( - TransactionKernel::assembler() - .with_dynamic_library(StandardsLib::default()) - .expect("dynamically linking standards library should work") - .assemble_library([NamedSource::new("mock::util", MOCK_UTIL_LIBRARY_CODE)]) - .expect("mock util library should be valid"), - ) + let source_manager = Arc::new(DefaultSourceManager::default()); + let root = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str(Some(Path::new("mock::util")), MOCK_UTIL_LIBRARY_CODE, source_manager.clone()) + .expect("mock util library should parse"); + let mut assembler = TransactionKernel::assembler_with_source_manager(source_manager); + assembler + .link_package(Arc::new(StandardsLib::default().into()), Linkage::Dynamic) + .expect("dynamically linking standards library should work"); + *assembler + .assemble_library("mock-util", root, None::<&str>) + .expect("mock util library should be valid") }); /// Returns the mock test [`Library`] under the `mock::util` namespace. diff --git a/crates/miden-standards/src/testing/note.rs b/crates/miden-standards/src/testing/note.rs index f52f33fb66..e914938c39 100644 --- a/crates/miden-standards/src/testing/note.rs +++ b/crates/miden-standards/src/testing/note.rs @@ -22,7 +22,7 @@ use miden_protocol::note::{ use miden_protocol::testing::note::DEFAULT_NOTE_SCRIPT; use miden_protocol::vm::{AdviceMap, Package}; use miden_protocol::{Felt, Word}; -use rand::Rng; +use rand::{Rng, RngExt}; use crate::code_builder::CodeBuilder; diff --git a/crates/miden-testing/Cargo.toml b/crates/miden-testing/Cargo.toml index bafbdb051a..0664e5097b 100644 --- a/crates/miden-testing/Cargo.toml +++ b/crates/miden-testing/Cargo.toml @@ -36,7 +36,7 @@ miden-processor = { workspace = true } # External dependencies anyhow = { workspace = true } itertools = { default-features = false, features = ["use_alloc"], version = "0.14" } -rand = { features = ["os_rng", "small_rng"], workspace = true } +rand = { features = ["sys_rng"], workspace = true } rand_chacha = { workspace = true } thiserror = { workspace = true } diff --git a/crates/miden-testing/src/assertion/test_assertion_macros.rs b/crates/miden-testing/src/assertion/test_assertion_macros.rs index f8a9cb6b0f..6dfe41720d 100644 --- a/crates/miden-testing/src/assertion/test_assertion_macros.rs +++ b/crates/miden-testing/src/assertion/test_assertion_macros.rs @@ -206,7 +206,7 @@ async fn not_binary_value_if() { assert_execution_error!( r, matches ExecutionError::OperationError { - err: OperationError::NotBinaryValueIf { .. }, + err: OperationError::NotBinaryValue { .. }, .. } ); @@ -218,7 +218,7 @@ async fn not_binary_value_loop() { assert_execution_error!( r, matches ExecutionError::OperationError { - err: OperationError::NotBinaryValueLoop { .. }, + err: OperationError::NotBinaryValue { .. }, .. } ); @@ -260,8 +260,8 @@ async fn cycle_limit_exceeded() { // Set max_cycles to MIN_TRACE_LEN (64); 100×push body trips it. let body = "push.0 ".repeat(100); let src = format!("begin {body} end"); - let options = ExecutionOptions::new(Some(64), 64, 4096, false, false) - .expect("max_cycles=64 satisfies MIN_TRACE_LEN"); + let options = + ExecutionOptions::new(Some(64), 64, 4096).expect("max_cycles=64 satisfies MIN_TRACE_LEN"); let r = run_masm_with_options(&src, options).await; assert_execution_error!(r, matches ExecutionError::CycleLimitExceeded(_)); } diff --git a/crates/miden-testing/src/executor.rs b/crates/miden-testing/src/executor.rs index b40ed17f6e..12430a2dc4 100644 --- a/crates/miden-testing/src/executor.rs +++ b/crates/miden-testing/src/executor.rs @@ -71,7 +71,11 @@ impl CodeExecutor { // Virtual file name should be unique. let virtual_source_file = source_manager.load(SourceLanguage::Masm, Uri::new("_user_code"), code.to_owned()); - let program = assembler.assemble_program(virtual_source_file).unwrap(); + let program = assembler + .assemble_program("tx-context-code", virtual_source_file) + .unwrap() + .try_into_program() + .unwrap(); self.execute_program(program).await } @@ -89,8 +93,7 @@ impl CodeExecutor { .map_err(ExecError::new)? .with_options(self.execution_options.unwrap_or_default()) .map_err(ExecutionError::advice_error_no_context) - .map_err(ExecError::new)? - .with_debugging(true); + .map_err(ExecError::new)?; let execution_output = processor.execute(&program, &mut self.host).await.map_err(ExecError::new)?; diff --git a/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs b/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs index 62a3fc4dac..7415801bb1 100644 --- a/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs +++ b/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs @@ -37,7 +37,7 @@ use miden_standards::testing::note::NoteBuilder; use miden_standards::tx_script::SendNotesTransactionScript; use miden_tx::LocalTransactionProver; use rand::rngs::SmallRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use super::proven_tx_builder::MockProvenTxBuilder; use crate::utils::create_p2any_note; diff --git a/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs b/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs index 03a8ed3b23..611086075d 100644 --- a/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs +++ b/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs @@ -14,7 +14,7 @@ use miden_protocol::transaction::{ExecutedTransaction, RawOutputNote, Transactio use miden_standards::testing::account_component::MockAccountComponent; use miden_standards::testing::note::NoteBuilder; use miden_tx::LocalTransactionProver; -use rand::Rng; +use rand::RngExt; use super::utils::MockChainBlockExt; use crate::{AccountState, Auth, MockChain, TxContextInput}; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_account.rs b/crates/miden-testing/src/kernel_tests/tx/test_account.rs index c077af913a..9d39d15728 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_account.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_account.rs @@ -28,9 +28,15 @@ use miden_protocol::account::{ StorageSlotType, StorageValuePatch, }; -use miden_protocol::assembly::diagnostics::NamedSource; use miden_protocol::assembly::diagnostics::reporting::PrintDiagnostic; -use miden_protocol::assembly::{DefaultSourceManager, Library}; +use miden_protocol::assembly::{ + DefaultSourceManager, + Library, + Linkage, + ModuleKind, + ModuleParser, + Path, +}; use miden_protocol::asset::{ Asset, AssetAmount, @@ -66,7 +72,7 @@ use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_standards::testing::mock_account::MockAccountExt; use miden_tx::LocalTransactionProver; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rand_chacha::ChaCha20Rng; use super::{Felt, StackInputs, ZERO}; @@ -102,7 +108,7 @@ pub async fn compute_commitment() -> anyhow::Result<()> { use miden::core::word use miden::protocol::active_account - use mock::account->mock_account + use mock::account as mock_account const MOCK_MAP_SLOT = word("{mock_map_slot}") @@ -207,7 +213,7 @@ async fn test_account_validate_id() -> anyhow::Result<()> { let suffix = Felt::try_from((account_id % (1u128 << 64)) as u64)?; let code = " - use $kernel::account_id + use miden::protocol::account_id begin exec.account_id::validate @@ -272,7 +278,7 @@ pub async fn test_compute_code_commitment() -> anyhow::Result<()> { let code = format!( r#" use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account begin exec.prologue::prepare_transaction @@ -331,7 +337,7 @@ async fn test_get_item() -> anyhow::Result<()> { #[tokio::test] async fn test_get_map_item() -> anyhow::Result<()> { let slot = AccountStorage::mock_map_slot(); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_slots(vec![slot.clone()])) .build_existing() @@ -595,7 +601,7 @@ async fn test_set_map_item() -> anyhow::Result<()> { ); let slot = AccountStorage::mock_map_slot(); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_slots(vec![slot.clone()])) .build_existing() @@ -608,7 +614,7 @@ async fn test_set_map_item() -> anyhow::Result<()> { use miden::core::sys use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account const SLOT_NAME=word("{slot_name}") @@ -740,7 +746,7 @@ async fn test_compute_storage_commitment() -> anyhow::Result<()> { let code = format!( r#" use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account const MOCK_VALUE_SLOT0=word("{mock_value_slot0}") const MOCK_MAP_SLOT=word("{mock_map_slot}") @@ -908,7 +914,7 @@ async fn test_get_vault_root() -> anyhow::Result<()> { r#" use miden::protocol::active_account use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account begin exec.prologue::prepare_transaction @@ -1122,7 +1128,7 @@ async fn test_get_init_balance_subtraction() -> anyhow::Result<()> { let remove_existing_source = format!( r#" use miden::protocol::active_account - use miden::standards::wallets::basic->wallet + use miden::standards::wallets::basic as wallet use mock::util begin @@ -1214,7 +1220,7 @@ async fn test_get_init_asset() -> anyhow::Result<()> { let remove_existing_source = format!( r#" use miden::protocol::active_account - use miden::standards::wallets::basic->wallet + use miden::standards::wallets::basic as wallet use mock::util begin @@ -1325,7 +1331,7 @@ async fn test_authenticate_and_track_procedure() -> anyhow::Result<()> { async fn test_was_procedure_called() -> anyhow::Result<()> { // Create a standard account using the mock component let mock_component = MockAccountComponent::with_slots(AccountStorage::mock_storage_slots()); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(mock_component) .build_existing() @@ -1340,7 +1346,7 @@ async fn test_was_procedure_called() -> anyhow::Result<()> { // 5. Checks that `was_procedure_called` returns `true` let tx_script_code = format!( r#" - use mock::account->mock_account + use mock::account as mock_account use miden::protocol::native_account const MOCK_VALUE_SLOT1 = word("{mock_value_slot1}") @@ -1415,28 +1421,41 @@ async fn transaction_executor_account_code_using_custom_library() -> anyhow::Res exec.external_module::external_setter end"; - let external_library_source = - NamedSource::new("external_library::external_module", external_library_code); - let external_library = TransactionKernel::assembler() - .assemble_library([external_library_source]) + let external_source_manager = Arc::new(DefaultSourceManager::default()); + let external_library_source = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str( + Some(Path::new("external_library::external_module")), + &external_library_code, + external_source_manager.clone(), + ) + .unwrap(); + let external_library = + *TransactionKernel::assembler_with_source_manager(external_source_manager) + .assemble_library("external-library", external_library_source, None::<&str>) + .map_err(|err| { + anyhow::anyhow!("failed to assemble library: {}", PrintDiagnostic::new(&err)) + })?; + + let source_manager = Arc::new(DefaultSourceManager::default()); + let mut assembler: miden_protocol::assembly::Assembler = + CodeBuilder::with_mock_libraries_with_source_manager(source_manager.clone()).into(); + assembler + .link_package(Arc::new(external_library.clone()), Linkage::Static) .map_err(|err| { - anyhow::anyhow!("failed to assemble library: {}", PrintDiagnostic::new(&err)) + anyhow::anyhow!("failed to link static library: {}", PrintDiagnostic::new(&err)) })?; - let mut assembler: miden_protocol::assembly::Assembler = - CodeBuilder::with_mock_libraries_with_source_manager(Arc::new( - DefaultSourceManager::default(), - )) - .into(); - assembler.link_static_library(&external_library).map_err(|err| { - anyhow::anyhow!("failed to link static library: {}", PrintDiagnostic::new(&err)) - })?; - - let account_component_source = - NamedSource::new("account_component::account_module", ACCOUNT_COMPONENT_CODE); - let account_component_lib = Arc::unwrap_or_clone( - assembler.clone().assemble_library([account_component_source]).unwrap(), - ); + let account_component_source = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str( + Some(Path::new("account_component::account_module")), + ACCOUNT_COMPONENT_CODE, + source_manager, + ) + .unwrap(); + let account_component_lib = *assembler + .clone() + .assemble_library("account-component", account_component_source, None::<&str>) + .unwrap(); let tx_script_src = "\ use account_component::account_module @@ -1452,7 +1471,7 @@ async fn transaction_executor_account_code_using_custom_library() -> anyhow::Res )?; // Build an existing account with nonce 1. - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(account_component) .build_existing()?; @@ -1520,14 +1539,14 @@ async fn incrementing_nonce_twice_fails() -> anyhow::Result<()> { async fn test_has_procedure() -> anyhow::Result<()> { // Create a standard account using the mock component let mock_component = MockAccountComponent::with_slots(AccountStorage::mock_storage_slots()); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(mock_component) .build_existing() .unwrap(); let tx_script_code = r#" - use mock::account->mock_account + use mock::account as mock_account use miden::protocol::active_account begin @@ -1589,7 +1608,7 @@ async fn test_has_storage_slot() -> anyhow::Result<()> { use miden::core::sys use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account const SLOT_NAME = word("{slot_name}") @@ -1693,7 +1712,7 @@ async fn test_get_initial_item() -> anyhow::Result<()> { r#" use $kernel::account use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account const MOCK_VALUE_SLOT0 = word("{mock_value_slot0}") @@ -1737,7 +1756,7 @@ async fn test_get_initial_item() -> anyhow::Result<()> { #[tokio::test] async fn test_get_initial_map_item() -> anyhow::Result<()> { let map_slot = AccountStorage::mock_map_slot(); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_slots(vec![map_slot.clone()])) .build_existing() @@ -1758,7 +1777,7 @@ async fn test_get_initial_map_item() -> anyhow::Result<()> { let code = format!( r#" use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account const MOCK_MAP_SLOT = word("{mock_map_slot}") @@ -1827,7 +1846,7 @@ async fn test_get_item_and_get_initial_item_for_all_slots() -> anyhow::Result<() }) .collect(); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_slots(slots.clone())) .build_existing() @@ -1877,7 +1896,7 @@ async fn test_get_item_and_get_initial_item_for_all_slots() -> anyhow::Result<() r#" use $kernel::account use $kernel::prologue - use mock::account->mock_account + use mock::account as mock_account {slot_constants} @@ -1938,12 +1957,13 @@ async fn merging_components_with_same_mast_root_succeeds() -> anyhow::Result<()> test_slot_name = &*TEST_SLOT_NAME ); - let source = NamedSource::new("component1::interface", code); - Arc::unwrap_or_clone( - TransactionKernel::assembler() - .assemble_library([source]) - .expect("mock account code should be valid"), - ) + let source_manager = Arc::new(DefaultSourceManager::default()); + let source = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str(Some(Path::new("component1::interface")), &code, source_manager.clone()) + .unwrap(); + *TransactionKernel::assembler_with_source_manager(source_manager) + .assemble_library("component1", source, None::<&str>) + .expect("mock account code should be valid") }); static COMPONENT_2_LIBRARY: LazyLock = LazyLock::new(|| { @@ -1970,12 +1990,13 @@ async fn merging_components_with_same_mast_root_succeeds() -> anyhow::Result<()> test_slot_name = &*TEST_SLOT_NAME ); - let source = NamedSource::new("component2::interface", code); - Arc::unwrap_or_clone( - TransactionKernel::assembler() - .assemble_library([source]) - .expect("mock account code should be valid"), - ) + let source_manager = Arc::new(DefaultSourceManager::default()); + let source = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str(Some(Path::new("component2::interface")), &code, source_manager.clone()) + .unwrap(); + *TransactionKernel::assembler_with_source_manager(source_manager) + .assemble_library("component2", source, None::<&str>) + .expect("mock account code should be valid") }); struct CustomComponent1 { @@ -2018,8 +2039,8 @@ async fn merging_components_with_same_mast_root_succeeds() -> anyhow::Result<()> let tx_script = format!( r#" - use component1::interface->comp1_interface - use component2::interface->comp2_interface + use component1::interface as comp1_interface + use component2::interface as comp2_interface begin call.comp1_interface::get_slot_content @@ -2036,8 +2057,8 @@ async fn merging_components_with_same_mast_root_succeeds() -> anyhow::Result<()> ); let tx_script = CodeBuilder::default() - .with_dynamically_linked_library(COMPONENT_1_LIBRARY.clone())? - .with_dynamically_linked_library(COMPONENT_2_LIBRARY.clone())? + .with_dynamically_linked_library(&*COMPONENT_1_LIBRARY)? + .with_dynamically_linked_library(&*COMPONENT_2_LIBRARY)? .compile_tx_script(tx_script)?; TestTransactionBuilder::new(account) diff --git a/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs b/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs index cdb17bbfbb..aba39b3bf7 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs @@ -24,13 +24,13 @@ use miden_protocol::testing::account_id::{ ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE, ACCOUNT_ID_SENDER, }; -use miden_protocol::transaction::{InputNote, RawOutputNote, TransactionKernel}; +use miden_protocol::transaction::{InputNote, RawOutputNote}; use miden_protocol::{Felt, Word}; use miden_standards::note::{NoteConsumptionStatus, P2idNote, P2ideNote, StandardNote}; use miden_standards::testing::note::NoteBuilder; use miden_tx::auth::UnreachableAuth; use miden_tx::{NoteConsumptionChecker, TransactionExecutor, TransactionExecutorError}; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rand_chacha::ChaCha20Rng; use crate::utils::create_public_p2any_note; @@ -135,7 +135,6 @@ async fn check_note_consumability_partial_success() -> anyhow::Result<()> { ChaCha20Rng::from_seed(ChaCha20Rng::from_seed([0_u8; 32]).random()), ) .code("@note_script pub proc main push.1 drop push.0 div end") - .dynamically_linked_libraries([TransactionKernel::library()]) .build()?; let failing_note_2 = NoteBuilder::new( @@ -143,7 +142,6 @@ async fn check_note_consumability_partial_success() -> anyhow::Result<()> { ChaCha20Rng::from_seed(ChaCha20Rng::from_seed([0_u8; 32]).random()), ) .code("@note_script pub proc main push.2 drop push.0 div end") - .dynamically_linked_libraries([TransactionKernel::library()]) .build()?; let successful_note_1 = builder.add_p2id_note( @@ -300,14 +298,12 @@ async fn check_note_consumability_epilogue_failure_with_new_combination() -> any ChaCha20Rng::from_seed(ChaCha20Rng::from_seed([0_u8; 32]).random()), ) .code("@note_script pub proc main push.1 drop push.1 div end") - .dynamically_linked_libraries([TransactionKernel::library()]) .build()?; let failing_note_1 = NoteBuilder::new( sender, ChaCha20Rng::from_seed(ChaCha20Rng::from_seed([0_u8; 32]).random()), ) .code("@note_script pub proc main push.1 drop push.0 div end") - .dynamically_linked_libraries([TransactionKernel::library()]) .build()?; // Create a note that causes epilogue failure. Adds assets to the transaction without moving diff --git a/crates/miden-testing/src/kernel_tests/tx/test_account_update.rs b/crates/miden-testing/src/kernel_tests/tx/test_account_update.rs index 92ec1cd580..20542f4524 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_account_update.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_account_update.rs @@ -38,7 +38,7 @@ use miden_protocol::{EMPTY_WORD, Felt, Word, ZERO}; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_tx::{LocalTransactionProver, TransactionExecutorError}; -use rand::Rng; +use rand::RngExt; use crate::{Auth, MockChain, TestTransactionBuilder}; @@ -1001,7 +1001,7 @@ async fn recomputing_delta_resets_host_delta() -> anyhow::Result<()> { let auth_code = format!( " use miden::protocol::native_account - use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT + use {{AUTH_UNAUTHORIZED_EVENT}} from miden::protocol::auth {TEST_ACCOUNT_CONVENIENCE_WRAPPERS} @@ -1172,7 +1172,7 @@ const TEST_ACCOUNT_CONVENIENCE_WRAPPERS: &str = " // existed when the kernel epilogue still produced the delta commitment. const DELTA_CHECK_AUTH_CODE: &str = r#" use miden::protocol::native_account - use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT + use {AUTH_UNAUTHORIZED_EVENT} from miden::protocol::auth #! Inputs: [[should_emit, 0, 0, 0], pad(12)] #! Outputs: [pad(16)] diff --git a/crates/miden-testing/src/kernel_tests/tx/test_active_note.rs b/crates/miden-testing/src/kernel_tests/tx/test_active_note.rs index e548e4d455..f342431c9a 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_active_note.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_active_note.rs @@ -100,7 +100,7 @@ async fn test_active_note_get_metadata() -> anyhow::Result<()> { let code = format!( r#" use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note begin @@ -151,7 +151,7 @@ async fn test_active_note_get_metadata_no_extra_word() -> anyhow::Result<()> { let code = format!( r#" use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note begin @@ -221,7 +221,7 @@ async fn test_active_note_is_public_and_is_private( let code = format!( r#" use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note begin @@ -262,7 +262,7 @@ async fn test_active_note_get_sender() -> anyhow::Result<()> { // calling get_sender should return sender of the active note let code = " use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note begin @@ -307,7 +307,7 @@ async fn test_active_note_get_note_type(#[case] note_type: NoteType) -> anyhow:: let code = " use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note use miden::protocol::note @@ -429,7 +429,7 @@ async fn test_active_note_get_assets() -> anyhow::Result<()> { use miden::core::sys use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note proc process_note_0 @@ -559,7 +559,7 @@ async fn test_active_note_get_storage() -> anyhow::Result<()> { let code = format!( r#" use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note begin @@ -819,7 +819,7 @@ async fn test_note_find_attachment( let code = format!( r#" use $kernel::prologue - use $kernel::note->note_internal + use $kernel::note as note_internal use miden::protocol::active_note use miden::protocol::input_note diff --git a/crates/miden-testing/src/kernel_tests/tx/test_array.rs b/crates/miden-testing/src/kernel_tests/tx/test_array.rs index 56231d5469..ba7c16b488 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_array.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_array.rs @@ -11,7 +11,7 @@ use miden_protocol::account::{ StorageSlotName, }; use miden_standards::code_builder::CodeBuilder; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rand_chacha::ChaCha20Rng; use crate::{Auth, TestTransactionBuilder}; @@ -73,7 +73,7 @@ async fn test_array_get_and_set() -> anyhow::Result<()> { )?; // Build an account with the wrapper component that uses the array utility - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(wrapper_component) .build_existing()?; @@ -89,7 +89,7 @@ async fn test_array_get_and_set() -> anyhow::Result<()> { // 2. Sets index 0 to [43, 43, 43, 43] // 3. Gets the updated value at index 0 (should be [43, 43, 43, 43]) let tx_script_code = r#" - use wrapper::component->wrapper + use wrapper::component as wrapper begin # Step 1: Get value at index 0 (should return [42, 42, 42, 42]) @@ -190,7 +190,7 @@ async fn test_double_word_array_get_and_set() -> anyhow::Result<()> { AccountComponentMetadata::mock("wrapper::component"), )?; - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(wrapper_component) .build_existing()?; @@ -204,7 +204,7 @@ async fn test_double_word_array_get_and_set() -> anyhow::Result<()> { let updated_value_1 = Word::from([10u32, 10, 10, 10]); let tx_script_code = format!( r#" - use wrapper::component->wrapper + use wrapper::component as wrapper begin # Step 1: Get value at index {index} (should return the initial double-word) diff --git a/crates/miden-testing/src/kernel_tests/tx/test_faucet.rs b/crates/miden-testing/src/kernel_tests/tx/test_faucet.rs index 0c8ed427d4..ad8f210a65 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_faucet.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_faucet.rs @@ -49,7 +49,7 @@ async fn test_mint_fungible_asset_succeeds() -> anyhow::Result<()> { let code = format!( r#" - use mock::faucet->mock_faucet + use mock::faucet as mock_faucet use miden::protocol::faucet use $kernel::asset_vault use $kernel::memory @@ -242,7 +242,7 @@ async fn test_mint_non_fungible_asset_succeeds() -> anyhow::Result<()> { use $kernel::asset_vault use $kernel::memory use $kernel::prologue - use mock::faucet->mock_faucet + use mock::faucet as mock_faucet begin # mint asset @@ -348,7 +348,7 @@ async fn test_mint_fungible_asset_with_callbacks_enabled() -> anyhow::Result<()> let code = format!( r#" - use mock::faucet->mock_faucet + use mock::faucet as mock_faucet use $kernel::prologue begin @@ -385,7 +385,7 @@ async fn test_burn_fungible_asset_succeeds() -> anyhow::Result<()> { let code = format!( r#" - use mock::faucet->mock_faucet + use mock::faucet as mock_faucet use miden::protocol::faucet use $kernel::asset_vault use $kernel::memory @@ -537,7 +537,7 @@ async fn test_burn_non_fungible_asset_succeeds() -> anyhow::Result<()> { use $kernel::asset_vault use $kernel::memory use $kernel::prologue - use mock::faucet->mock_faucet + use mock::faucet as mock_faucet begin exec.prologue::prepare_transaction @@ -688,8 +688,7 @@ fn setup_non_faucet_account() -> anyhow::Result { )) .compile_component_code( "test::non_faucet_component", - "pub use ::miden::protocol::faucet::mint - pub use ::miden::protocol::faucet::burn", + "pub use {mint, burn} from ::miden::protocol::faucet", )?; let metadata = AccountComponentMetadata::new("test::non_faucet_component"); let faucet_component = AccountComponent::new(faucet_code, vec![], metadata)?; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_fpi.rs b/crates/miden-testing/src/kernel_tests/tx/test_fpi.rs index 4e425e0306..6ca36c6eef 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_fpi.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_fpi.rs @@ -54,7 +54,7 @@ use miden_protocol::{Word, ZERO}; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_tx::LocalTransactionProver; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rand_chacha::ChaCha20Rng; use crate::kernel_tests::tx::ExecutionOutputExt; @@ -100,12 +100,12 @@ async fn test_fpi_memory_single_account() -> anyhow::Result<()> { AccountComponentMetadata::mock("test::foreign_account"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component) .build_existing()?; - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_slots(vec![AccountStorage::mock_map_slot()])) .account_type(AccountType::Public) @@ -370,17 +370,17 @@ async fn test_fpi_memory_two_accounts() -> anyhow::Result<()> { AccountComponentMetadata::mock("test::foreign_account_2"), )?; - let foreign_account_1 = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account_1 = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component_1) .build_existing()?; - let foreign_account_2 = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account_2 = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component_2) .build_existing()?; - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -602,12 +602,12 @@ async fn test_fpi_execute_foreign_procedure() -> anyhow::Result<()> { AccountComponentMetadata::mock("foreign_account"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component.clone()) .build_existing()?; - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -789,13 +789,13 @@ async fn foreign_account_can_get_balance_and_presence_of_asset() -> anyhow::Resu AccountComponentMetadata::mock("foreign_account_code"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component.clone()) .with_assets(vec![fungible_asset, non_fungible_asset]) .build_existing()?; - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -895,13 +895,13 @@ async fn foreign_account_get_initial_balance() -> anyhow::Result<()> { AccountComponentMetadata::mock("foreign_account_code"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component.clone()) .with_assets(vec![fungible_asset]) .build_existing()?; - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1040,10 +1040,11 @@ async fn test_nested_fpi_cyclic_invocation() -> anyhow::Result<()> { AccountComponentMetadata::mock("test::second_foreign_account"), )?; - let second_foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) - .with_auth_component(Auth::IncrNonce) - .with_component(second_foreign_account_component) - .build_existing()?; + let second_foreign_account = + AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) + .with_auth_component(Auth::IncrNonce) + .with_component(second_foreign_account_component) + .build_existing()?; // ------ FIRST FOREIGN ACCOUNT --------------------------------------------------------------- let first_foreign_account_code_source = format!( @@ -1102,13 +1103,14 @@ async fn test_nested_fpi_cyclic_invocation() -> anyhow::Result<()> { AccountComponentMetadata::mock("first_foreign_account"), )?; - let first_foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) - .with_auth_component(Auth::IncrNonce) - .with_component(first_foreign_account_component.clone()) - .build_existing()?; + let first_foreign_account = + AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) + .with_auth_component(Auth::IncrNonce) + .with_component(first_foreign_account_component.clone()) + .build_existing()?; // ------ NATIVE ACCOUNT --------------------------------------------------------------- - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1233,10 +1235,11 @@ async fn test_prove_fpi_two_foreign_accounts_chain() -> anyhow::Result<()> { AccountComponentMetadata::mock("foreign_account"), )?; - let second_foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) - .with_auth_component(Auth::IncrNonce) - .with_component(second_foreign_account_component.clone()) - .build_existing()?; + let second_foreign_account = + AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) + .with_auth_component(Auth::IncrNonce) + .with_component(second_foreign_account_component.clone()) + .build_existing()?; // ------ FIRST FOREIGN ACCOUNT --------------------------------------------------------------- // unique procedure which calls the second foreign account via FPI and then returns @@ -1279,13 +1282,14 @@ async fn test_prove_fpi_two_foreign_accounts_chain() -> anyhow::Result<()> { AccountComponentMetadata::mock("first_foreign_account"), )?; - let first_foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) - .with_auth_component(Auth::IncrNonce) - .with_component(first_foreign_account_component.clone()) - .build_existing()?; + let first_foreign_account = + AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) + .with_auth_component(Auth::IncrNonce) + .with_component(first_foreign_account_component.clone()) + .build_existing()?; // ------ NATIVE ACCOUNT --------------------------------------------------------------- - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1406,11 +1410,12 @@ async fn test_nested_fpi_stack_overflow() -> anyhow::Result<()> { ) .unwrap(); - let last_foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) - .with_auth_component(Auth::IncrNonce) - .with_component(last_foreign_account_component) - .build_existing() - .unwrap(); + let last_foreign_account = + AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) + .with_auth_component(Auth::IncrNonce) + .with_component(last_foreign_account_component) + .build_existing() + .unwrap(); foreign_accounts.push(last_foreign_account); @@ -1458,7 +1463,7 @@ async fn test_nested_fpi_stack_overflow() -> anyhow::Result<()> { ) .unwrap(); - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component) .build_existing() @@ -1468,7 +1473,7 @@ async fn test_nested_fpi_stack_overflow() -> anyhow::Result<()> { } // ------ NATIVE ACCOUNT --------------------------------------------------------------- - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1572,13 +1577,13 @@ async fn test_nested_fpi_native_account_invocation() -> anyhow::Result<()> { AccountComponentMetadata::mock("foreign_account"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component.clone()) .build_existing()?; // ------ NATIVE ACCOUNT --------------------------------------------------------------- - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1779,12 +1784,12 @@ async fn test_fpi_get_account_id() -> anyhow::Result<()> { AccountComponentMetadata::mock("foreign_account"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component.clone()) .build_existing()?; - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1867,7 +1872,7 @@ async fn test_fpi_get_account_id() -> anyhow::Result<()> { async fn test_get_initial_item_and_get_initial_map_item_with_foreign_account() -> anyhow::Result<()> { // Create a native account - let native_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let native_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_empty_slots()) .account_type(AccountType::Public) @@ -1906,7 +1911,7 @@ async fn test_get_initial_item_and_get_initial_map_item_with_foreign_account() - AccountComponentMetadata::mock("foreign_account"), )?; - let foreign_account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let foreign_account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(foreign_account_component.clone()) .build_existing()?; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_link_map.rs b/crates/miden-testing/src/kernel_tests/tx/test_link_map.rs index 94cfddd9fa..abb197e955 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_link_map.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_link_map.rs @@ -603,7 +603,7 @@ fn generate_updates( entries .iter() - .choose_multiple(&mut rng, num_updates) + .sample(&mut rng, num_updates) .into_iter() .map(|(key, _)| (*key, (rand_value::(), rand_value::()))) .collect() diff --git a/crates/miden-testing/src/kernel_tests/tx/test_note.rs b/crates/miden-testing/src/kernel_tests/tx/test_note.rs index 10db2073dc..19e98cd0fa 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_note.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_note.rs @@ -454,12 +454,13 @@ pub async fn test_timelock() -> anyhow::Result<()> { let lock_timestamp = 2_000_000_000; let source_manager = Arc::new(DefaultSourceManager::default()); - let timelock_note = NoteBuilder::new(account.id(), &mut ChaCha20Rng::from_os_rng()) - .note_storage([Felt::from(lock_timestamp)])? - .source_manager(source_manager.clone()) - .code(code.clone()) - .dynamically_linked_libraries(CodeBuilder::mock_libraries()) - .build()?; + let timelock_note = + NoteBuilder::new(account.id(), &mut ChaCha20Rng::from_rng(&mut rand::rng())) + .note_storage([Felt::from(lock_timestamp)])? + .source_manager(source_manager.clone()) + .code(code.clone()) + .dynamically_linked_libraries(CodeBuilder::mock_libraries()) + .build()?; builder.add_output_note(RawOutputNote::Full(timelock_note.clone())); diff --git a/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs b/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs index cdd683f69b..ce843d6a03 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs @@ -198,7 +198,7 @@ async fn test_create_note_too_many_notes() -> anyhow::Result<()> { let code = format!( " use miden::protocol::output_note - use $kernel::constants::MAX_OUTPUT_NOTES_PER_TX + use {{MAX_OUTPUT_NOTES_PER_TX}} from $kernel::constants use $kernel::memory use $kernel::prologue @@ -1220,7 +1220,6 @@ async fn test_add_attachment_with_invalid_num_elements_fails( let code = format!( " use miden::protocol::output_note - use miden::standards::note_tag::DEFAULT_TAG use $kernel::prologue use mock::util @@ -1253,7 +1252,6 @@ async fn test_add_attachment_with_scheme_zero_fails() -> anyhow::Result<()> { let code = " use miden::protocol::output_note - use miden::standards::note_tag::DEFAULT_TAG use $kernel::prologue use mock::util @@ -1923,7 +1921,6 @@ async fn test_add_attachments_with_too_many_overall_elements_fails() -> anyhow:: let code = format!( " use miden::protocol::output_note - use miden::standards::note_tag::DEFAULT_TAG use $kernel::prologue use mock::util diff --git a/crates/miden-testing/src/kernel_tests/tx/test_prologue.rs b/crates/miden-testing/src/kernel_tests/tx/test_prologue.rs index 6c63f2c6ac..ccf620973b 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_prologue.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_prologue.rs @@ -82,7 +82,7 @@ use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_standards::testing::mock_account::MockAccountExt; use miden_tx::TransactionExecutorError; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rand_chacha::ChaCha20Rng; use super::{Felt, ZERO}; @@ -567,7 +567,7 @@ pub async fn create_account_test( pub async fn create_multiple_accounts_test(account_type: AccountType) -> anyhow::Result<()> { let mut accounts = Vec::new(); - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .account_type(account_type) .with_auth_component(Auth::IncrNonce) .with_component(MockAccountComponent::with_slots(vec![StorageSlot::with_value( @@ -602,7 +602,7 @@ pub async fn create_account_invalid_seed() -> anyhow::Result<()> { let mut mock_chain = MockChain::new(); mock_chain.prove_next_block()?; - let account = AccountBuilder::new(ChaCha20Rng::from_os_rng().random()) + let account = AccountBuilder::new(ChaCha20Rng::from_rng(&mut rand::rng()).random()) .with_auth_component(Auth::IncrNonce) .with_component(BasicWallet) .build()?; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_tx.rs b/crates/miden-testing/src/kernel_tests/tx/test_tx.rs index f6b4c6bd16..4e030e4816 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_tx.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_tx.rs @@ -19,8 +19,7 @@ use miden_protocol::account::{ StorageSlot, StorageSlotName, }; -use miden_protocol::assembly::DefaultSourceManager; -use miden_protocol::assembly::diagnostics::NamedSource; +use miden_protocol::assembly::{DefaultSourceManager, ModuleKind, ModuleParser, Path}; use miden_protocol::asset::{Asset, AssetVault, FungibleAsset, NonFungibleAsset}; use miden_protocol::block::BlockNumber; use miden_protocol::errors::ProvenTransactionError; @@ -275,7 +274,7 @@ async fn executed_transaction_output_notes() -> anyhow::Result<()> { let tx_script_src = format!( "\ - use miden::standards::wallets::basic->wallet + use miden::standards::wallets::basic as wallet use miden::protocol::output_note use mock::util @@ -588,11 +587,13 @@ async fn execute_tx_view_script() -> anyhow::Result<()> { end "; - let source = NamedSource::new("test::module_1", test_module_source); let source_manager = Arc::new(DefaultSourceManager::default()); let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); + let source = ModuleParser::new(Some(ModuleKind::Library)) + .parse_str(Some(Path::new("test::module_1")), test_module_source, source_manager.clone()) + .unwrap(); - let library = assembler.assemble_library([source]).unwrap(); + let library = assembler.assemble_library("test-tx-view-script", source, None::<&str>).unwrap(); let source = " use test::module_1 @@ -805,7 +806,7 @@ async fn inputs_created_correctly() -> anyhow::Result<()> { "#; let tx_script = CodeBuilder::default() - .with_dynamically_linked_library(component_code.as_library())? + .with_dynamically_linked_library(component_code)? .compile_tx_script(script)?; assert!(tx_script.mast().advice_map().get(&Word::try_from([1u64, 2, 3, 4])?).is_some()); diff --git a/crates/miden-testing/src/mock_chain/chain_builder.rs b/crates/miden-testing/src/mock_chain/chain_builder.rs index d60efad9b5..9f7fe24dbe 100644 --- a/crates/miden-testing/src/mock_chain/chain_builder.rs +++ b/crates/miden-testing/src/mock_chain/chain_builder.rs @@ -57,7 +57,7 @@ use miden_standards::account::policies::{ use miden_standards::account::wallets::BasicWallet; use miden_standards::note::{BurnNote, MintNote, P2idNote, P2ideNote, SwapNote}; use miden_standards::testing::account_component::MockAccountComponent; -use rand::Rng; +use rand::RngExt; use crate::mock_chain::chain::AccountAuthenticator; use crate::utils::{create_p2any_note, create_spawn_note}; diff --git a/crates/miden-testing/src/mock_host.rs b/crates/miden-testing/src/mock_host.rs index b64afec76b..f0b774825a 100644 --- a/crates/miden-testing/src/mock_host.rs +++ b/crates/miden-testing/src/mock_host.rs @@ -4,8 +4,7 @@ use alloc::vec::Vec; use miden_processor::advice::AdviceMutation; use miden_processor::event::EventError; -use miden_processor::mast::MastForest; -use miden_processor::{BaseHost, FutureMaybeSend, Host, ProcessorState}; +use miden_processor::{BaseHost, FutureMaybeSend, Host, LoadedMastForest, ProcessorState}; use miden_protocol::transaction::TransactionEventId; use miden_protocol::vm::{EventId, EventName}; use miden_protocol::{CoreLibrary, Word}; @@ -98,7 +97,10 @@ impl<'store> BaseHost for MockHost<'store> { } impl<'store> Host for MockHost<'store> { - fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend>> { + fn get_mast_forest( + &self, + node_digest: &Word, + ) -> impl FutureMaybeSend> { self.exec_host.get_mast_forest(node_digest) } diff --git a/crates/miden-testing/src/tx_context/context.rs b/crates/miden-testing/src/tx_context/context.rs index f048fa2e35..a2586978c5 100644 --- a/crates/miden-testing/src/tx_context/context.rs +++ b/crates/miden-testing/src/tx_context/context.rs @@ -3,8 +3,7 @@ use alloc::collections::{BTreeMap, BTreeSet}; use alloc::sync::Arc; use alloc::vec::Vec; -use miden_processor::mast::MastForest; -use miden_processor::{ExecutionOutput, FutureMaybeSend, MastForestStore, Word}; +use miden_processor::{ExecutionOutput, FutureMaybeSend, LoadedMastForest, MastForestStore, Word}; use miden_protocol::account::{ Account, AccountId, @@ -120,7 +119,7 @@ impl TransactionContext { .into(); let program = assembler - .assemble_program(virtual_source_file) + .assemble_program("tx-context-code", virtual_source_file) .expect("code was not well formed"); // Load transaction kernel and the program into the mast forest in self. @@ -128,6 +127,7 @@ impl TransactionContext { // TransactionContextBuilder. self.mast_store.insert(TransactionKernel::library().mast_forest().clone()); self.mast_store.insert(program.mast_forest().clone()); + let program = program.try_into_program().expect("program package should be executable"); let account_procedure_idx_map = AccountProcedureIndexMap::new( [tx_inputs.account().code()] @@ -379,7 +379,7 @@ impl DataStore for TransactionContext { } impl MastForestStore for TransactionContext { - fn get(&self, procedure_hash: &Word) -> Option> { + fn get(&self, procedure_hash: &Word) -> Option { self.mast_store.get(procedure_hash) } } diff --git a/crates/miden-testing/src/utils.rs b/crates/miden-testing/src/utils.rs index 405011ee1e..6c3612bc2f 100644 --- a/crates/miden-testing/src/utils.rs +++ b/crates/miden-testing/src/utils.rs @@ -168,9 +168,8 @@ pub fn create_p2any_note( r#" use mock::account use miden::protocol::active_note - use ::miden::protocol::asset::ASSET_VALUE_MEMORY_OFFSET - use ::miden::protocol::asset::ASSET_SIZE - use miden::standards::wallets::basic->wallet + use {{ASSET_SIZE, ASSET_VALUE_MEMORY_OFFSET}} from ::miden::protocol::asset + use miden::standards::wallets::basic as wallet @note_script pub proc main @@ -228,7 +227,7 @@ where let (note_code, advice_map) = note_script_that_creates_notes(sender_id, output_notes)?; - let note = NoteBuilder::new(sender_id, SmallRng::from_os_rng()) + let note = NoteBuilder::new(sender_id, SmallRng::from_rng(&mut rand::rng())) .code(note_code) .advice_map(advice_map) .dynamically_linked_libraries(CodeBuilder::mock_libraries()) diff --git a/crates/miden-testing/tests/agglayer/asset_conversion.rs b/crates/miden-testing/tests/agglayer/asset_conversion.rs index dc288828d9..4f99027dd6 100644 --- a/crates/miden-testing/tests/agglayer/asset_conversion.rs +++ b/crates/miden-testing/tests/agglayer/asset_conversion.rs @@ -13,7 +13,7 @@ use miden_protocol::asset::FungibleAsset; use miden_protocol::errors::MasmError; use primitive_types::U256; use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use super::test_utils::{assert_execution_fails_with, execute_masm_script}; @@ -110,7 +110,7 @@ async fn test_scale_up_exceeds_max_scale() { end "; - assert_execution_fails_with(script_code, "maximum scaling factor is 18").await; + assert_execution_fails_with(script_code, &ERR_SCALE_AMOUNT_EXCEEDED_LIMIT).await; } // ================================================================================================ @@ -156,7 +156,7 @@ async fn assert_scale_down_ok(x: EthAmount, scale: u32) -> anyhow::Result { /// Assert that scaling down fails with the given y and expected error async fn assert_scale_down_fails(x: EthAmount, scale: u32, y: u64, expected_error: MasmError) { let script = build_scale_down_script(x, scale, y); - assert_execution_fails_with(&script, expected_error.message()).await; + assert_execution_fails_with(&script, &expected_error).await; } /// Test that y-1 and y+1 both fail appropriately diff --git a/crates/miden-testing/tests/agglayer/bridge_in.rs b/crates/miden-testing/tests/agglayer/bridge_in.rs index b83be0a62f..4b0c27c52f 100644 --- a/crates/miden-testing/tests/agglayer/bridge_in.rs +++ b/crates/miden-testing/tests/agglayer/bridge_in.rs @@ -45,7 +45,7 @@ use miden_standards::testing::account_component::IncrNonceAuthComponent; use miden_standards::testing::mock_account::MockAccountExt; use miden_testing::{AccountState, Auth, MockChain, assert_transaction_executor_error}; use miden_tx::utils::hex_to_bytes; -use rand::Rng; +use rand::RngExt; use super::test_utils::{ ClaimDataSource, diff --git a/crates/miden-testing/tests/agglayer/bridge_out.rs b/crates/miden-testing/tests/agglayer/bridge_out.rs index 39a9a2a0a9..30eb435769 100644 --- a/crates/miden-testing/tests/agglayer/bridge_out.rs +++ b/crates/miden-testing/tests/agglayer/bridge_out.rs @@ -40,7 +40,7 @@ use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint, StandardNot use miden_testing::{Auth, MockChain, assert_transaction_executor_error}; use miden_tx::utils::hex_to_bytes; use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use super::merkle_tree_frontier::MerkleTreeFrontier32; use super::test_utils::SOLIDITY_MTF_VECTORS; diff --git a/crates/miden-testing/tests/agglayer/global_index.rs b/crates/miden-testing/tests/agglayer/global_index.rs index 81809641ae..03eac89ef9 100644 --- a/crates/miden-testing/tests/agglayer/global_index.rs +++ b/crates/miden-testing/tests/agglayer/global_index.rs @@ -9,7 +9,7 @@ use miden_agglayer::errors::{ ERR_ROLLUP_INDEX_NON_ZERO, }; use miden_agglayer::{GlobalIndex, agglayer_library}; -use miden_assembly::{Assembler, DefaultSourceManager}; +use miden_assembly::{Assembler, DefaultSourceManager, Linkage}; use miden_core_lib::CoreLibrary; use miden_processor::Program; use miden_testing::{ExecError, assert_execution_error}; @@ -35,11 +35,13 @@ fn assemble_process_global_index_program(global_index: GlobalIndex, proc_name: & ); Assembler::new(Arc::new(DefaultSourceManager::default())) - .with_dynamic_library(CoreLibrary::default()) + .with_package(CoreLibrary::default().package(), Linkage::Dynamic) .unwrap() - .with_dynamic_library(agglayer_library()) + .with_package(Arc::new(agglayer_library()), Linkage::Dynamic) .unwrap() - .assemble_program(&script_code) + .assemble_program("agglayer-test-script", &script_code) + .unwrap() + .try_into_program() .unwrap() } diff --git a/crates/miden-testing/tests/agglayer/leaf_utils.rs b/crates/miden-testing/tests/agglayer/leaf_utils.rs index 87013815d8..bc7132a662 100644 --- a/crates/miden-testing/tests/agglayer/leaf_utils.rs +++ b/crates/miden-testing/tests/agglayer/leaf_utils.rs @@ -4,7 +4,7 @@ use alloc::sync::Arc; use alloc::vec::Vec; use miden_agglayer::{LeafValue, agglayer_library}; -use miden_assembly::{Assembler, DefaultSourceManager}; +use miden_assembly::{Assembler, DefaultSourceManager, Linkage}; use miden_core_lib::CoreLibrary; use miden_crypto::SequentialCommit; use miden_processor::advice::AdviceInputs; @@ -120,11 +120,13 @@ async fn pack_leaf_data() -> anyhow::Result<()> { ); let program = Assembler::new(Arc::new(DefaultSourceManager::default())) - .with_dynamic_library(CoreLibrary::default()) + .with_package(CoreLibrary::default().package(), Linkage::Dynamic) .unwrap() - .with_dynamic_library(agglayer_lib.clone()) + .with_package(Arc::new(agglayer_lib.clone()), Linkage::Dynamic) .unwrap() - .assemble_program(&source) + .assemble_program("agglayer-test-script", &source) + .unwrap() + .try_into_program() .unwrap(); let exec_output = execute_program_with_default_host(program, Some(advice_inputs)).await?; @@ -179,11 +181,13 @@ async fn get_leaf_value() -> anyhow::Result<()> { let agglayer_lib = agglayer_library(); let program = Assembler::new(Arc::new(DefaultSourceManager::default())) - .with_dynamic_library(CoreLibrary::default()) + .with_package(CoreLibrary::default().package(), Linkage::Dynamic) + .unwrap() + .with_package(Arc::new(agglayer_lib.clone()), Linkage::Dynamic) .unwrap() - .with_dynamic_library(agglayer_lib.clone()) + .assemble_program("agglayer-test-script", &source) .unwrap() - .assemble_program(&source) + .try_into_program() .unwrap(); let exec_output = execute_program_with_default_host(program, Some(advice_inputs)).await?; diff --git a/crates/miden-testing/tests/agglayer/solidity_miden_address_conversion.rs b/crates/miden-testing/tests/agglayer/solidity_miden_address_conversion.rs index 5107fcbf54..17b42685df 100644 --- a/crates/miden-testing/tests/agglayer/solidity_miden_address_conversion.rs +++ b/crates/miden-testing/tests/agglayer/solidity_miden_address_conversion.rs @@ -3,7 +3,7 @@ extern crate alloc; use alloc::sync::Arc; use miden_agglayer::{EthEmbeddedAccountId, agglayer_library}; -use miden_assembly::{Assembler, DefaultSourceManager}; +use miden_assembly::{Assembler, DefaultSourceManager, Linkage}; use miden_core_lib::CoreLibrary; use miden_processor::advice::AdviceInputs; use miden_processor::{ @@ -50,8 +50,7 @@ async fn execute_program_with_default_host( let processor = FastProcessor::new(stack_inputs) .with_advice(advice_inputs) - .map_err(ExecutionError::advice_error_no_context)? - .with_debugging(true); + .map_err(ExecutionError::advice_error_no_context)?; processor.execute(&program, &mut host).await } @@ -150,11 +149,13 @@ async fn test_ethereum_address_to_account_id_in_masm() -> anyhow::Result<()> { ); let program = Assembler::new(Arc::new(DefaultSourceManager::default())) - .with_dynamic_library(CoreLibrary::default()) + .with_package(CoreLibrary::default().package(), Linkage::Dynamic) .unwrap() - .with_dynamic_library(agglayer_library()) + .with_package(Arc::new(agglayer_library()), Linkage::Dynamic) .unwrap() - .assemble_program(&script_code) + .assemble_program("agglayer-test-script", &script_code) + .unwrap() + .try_into_program() .unwrap(); let exec_output = execute_program_with_default_host(program).await?; diff --git a/crates/miden-testing/tests/agglayer/test_utils.rs b/crates/miden-testing/tests/agglayer/test_utils.rs index b50f07491f..3c6490edc3 100644 --- a/crates/miden-testing/tests/agglayer/test_utils.rs +++ b/crates/miden-testing/tests/agglayer/test_utils.rs @@ -12,7 +12,7 @@ pub use miden_agglayer::testing::{ SOLIDITY_CANONICAL_ZEROS, SOLIDITY_MERKLE_PROOF_VECTORS, }; -use miden_assembly::{Assembler, DefaultSourceManager}; +use miden_assembly::{Assembler, DefaultSourceManager, Linkage}; use miden_core_lib::CoreLibrary; use miden_processor::advice::AdviceInputs; use miden_processor::{ @@ -23,6 +23,7 @@ use miden_processor::{ Program, StackInputs, }; +use miden_protocol::errors::MasmError; use miden_protocol::transaction::TransactionKernel; use miden_protocol::utils::sync::LazyLock; @@ -70,8 +71,7 @@ pub async fn execute_program_with_default_host( let processor = FastProcessor::new(stack_inputs) .with_advice(advice_inputs) - .map_err(ExecutionError::advice_error_no_context)? - .with_debugging(true); + .map_err(ExecutionError::advice_error_no_context)?; processor.execute(&program, &mut host).await } @@ -80,25 +80,28 @@ pub async fn execute_masm_script(script_code: &str) -> Result anyhow::Result<()> { ); let program = Assembler::new(Arc::new(DefaultSourceManager::default())) - .with_dynamic_library(CoreLibrary::default()) + .with_package(CoreLibrary::default().package(), Linkage::Dynamic) .unwrap() - .with_dynamic_library(agglayer_lib.clone()) + .with_package(Arc::new(agglayer_lib.clone()), Linkage::Dynamic) .unwrap() - .assemble_program(&source) + .assemble_program("agglayer-test-script", &source) + .unwrap() + .try_into_program() .unwrap(); let exec_output = execute_program_with_default_host(program, None).await?; @@ -261,11 +263,13 @@ async fn test_compute_ger_basic() -> anyhow::Result<()> { ); let program = Assembler::new(Arc::new(DefaultSourceManager::default())) - .with_dynamic_library(CoreLibrary::default()) + .with_package(CoreLibrary::default().package(), Linkage::Dynamic) + .unwrap() + .with_package(Arc::new(agglayer_lib.clone()), Linkage::Dynamic) .unwrap() - .with_dynamic_library(agglayer_lib.clone()) + .assemble_program("agglayer-test-script", &source) .unwrap() - .assemble_program(&source) + .try_into_program() .unwrap(); let exec_output = execute_program_with_default_host(program, None).await?; diff --git a/crates/miden-testing/tests/scripts/code_inspection.rs b/crates/miden-testing/tests/scripts/code_inspection.rs index e3d8e2ce69..0219f1fe24 100644 --- a/crates/miden-testing/tests/scripts/code_inspection.rs +++ b/crates/miden-testing/tests/scripts/code_inspection.rs @@ -37,7 +37,7 @@ async fn run_has_procedure_script(proc_root: Word, body: &str) -> anyhow::Result // `call`. No `procref` is used so the stack depth stays at 16 across the call boundary. let tx_script_code = format!( r#" - use miden::standards::components::metadata::code_inspection->code_inspection + use miden::standards::components::metadata::code_inspection as code_inspection begin # stack: [PROC_ROOT, pad(12)] diff --git a/crates/miden-testing/tests/scripts/faucet.rs b/crates/miden-testing/tests/scripts/faucet.rs index 5b5f3cd712..ef356863ef 100644 --- a/crates/miden-testing/tests/scripts/faucet.rs +++ b/crates/miden-testing/tests/scripts/faucet.rs @@ -64,7 +64,7 @@ use miden_testing::{ assert_note_created, assert_transaction_executor_error, }; -use rand::Rng; +use rand::RngExt; use crate::{get_note_with_fungible_asset_and_script, prove_and_verify_transaction}; diff --git a/crates/miden-testing/tests/scripts/non_fungible_faucet.rs b/crates/miden-testing/tests/scripts/non_fungible_faucet.rs index d4fb0fdf2d..8b04501ee9 100644 --- a/crates/miden-testing/tests/scripts/non_fungible_faucet.rs +++ b/crates/miden-testing/tests/scripts/non_fungible_faucet.rs @@ -31,7 +31,7 @@ use miden_testing::{ MockChainBuilder, assert_transaction_executor_error, }; -use rand::Rng; +use rand::RngExt; /// Builds an existing non-fungible faucet with allow-all policies (so a tx-script mint is gated /// only by the test auth) and an owner-controlled authority. diff --git a/crates/miden-testing/tests/scripts/ownable2step.rs b/crates/miden-testing/tests/scripts/ownable2step.rs index 4b82c009d7..cb55bd3109 100644 --- a/crates/miden-testing/tests/scripts/ownable2step.rs +++ b/crates/miden-testing/tests/scripts/ownable2step.rs @@ -37,11 +37,7 @@ fn create_ownable_account( ) -> anyhow::Result { let component_code = r#" use miden::standards::access::ownable2step - pub use ownable2step::get_owner - pub use ownable2step::get_nominated_owner - pub use ownable2step::transfer_ownership - pub use ownable2step::accept_ownership - pub use ownable2step::renounce_ownership + pub use {get_owner, get_nominated_owner, transfer_ownership, accept_ownership, renounce_ownership} from ::miden::standards::access::ownable2step "#; let component_code_obj = CodeBuilder::default().compile_component_code("test::ownable", component_code)?; @@ -78,7 +74,7 @@ fn create_transfer_note( ) -> anyhow::Result { let script = format!( r#" - use miden::standards::access::ownable2step->test_account + use miden::standards::access::ownable2step as test_account @note_script pub proc main repeat.14 push.0 end @@ -106,7 +102,7 @@ fn create_accept_note( source_manager: Arc, ) -> anyhow::Result { let script = r#" - use miden::standards::access::ownable2step->test_account + use miden::standards::access::ownable2step as test_account @note_script pub proc main repeat.16 push.0 end @@ -129,7 +125,7 @@ fn create_cancel_note( source_manager: Arc, ) -> anyhow::Result { let script = r#" - use miden::standards::access::ownable2step->test_account + use miden::standards::access::ownable2step as test_account @note_script pub proc main repeat.14 push.0 end @@ -155,7 +151,7 @@ fn create_renounce_note( source_manager: Arc, ) -> anyhow::Result { let script = r#" - use miden::standards::access::ownable2step->test_account + use miden::standards::access::ownable2step as test_account @note_script pub proc main repeat.16 push.0 end @@ -513,7 +509,7 @@ async fn test_transfer_ownership_fails_with_invalid_account_id() -> anyhow::Resu let script = format!( r#" - use miden::standards::access::ownable2step->test_account + use miden::standards::access::ownable2step as test_account @note_script pub proc main repeat.14 push.0 end diff --git a/crates/miden-testing/tests/scripts/pswap.rs b/crates/miden-testing/tests/scripts/pswap.rs index 422c09f3bf..02da7c5fae 100644 --- a/crates/miden-testing/tests/scripts/pswap.rs +++ b/crates/miden-testing/tests/scripts/pswap.rs @@ -1129,7 +1129,7 @@ async fn pswap_partial_fill_ratio_test( #[tokio::test] async fn pswap_partial_fill_ratio_fuzz(#[case] seed: u64) -> anyhow::Result<()> { use rand::rngs::SmallRng; - use rand::{Rng, SeedableRng}; + use rand::{RngExt, SeedableRng}; const FUZZ_ITERATIONS: usize = 30; diff --git a/crates/miden-tx/src/executor/exec_host.rs b/crates/miden-tx/src/executor/exec_host.rs index a762502eb8..ed7f2bb260 100644 --- a/crates/miden-tx/src/executor/exec_host.rs +++ b/crates/miden-tx/src/executor/exec_host.rs @@ -5,8 +5,7 @@ use alloc::vec::Vec; use miden_processor::advice::AdviceMutation; use miden_processor::event::EventError; -use miden_processor::mast::MastForest; -use miden_processor::{BaseHost, FutureMaybeSend, Host, ProcessorState}; +use miden_processor::{BaseHost, FutureMaybeSend, Host, LoadedMastForest, ProcessorState}; use miden_protocol::account::auth::PublicKeyCommitment; use miden_protocol::account::{ AccountCode, @@ -439,7 +438,10 @@ where STORE: DataStore + Sync, AUTH: TransactionAuthenticator + Sync, { - fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend>> { + fn get_mast_forest( + &self, + node_digest: &Word, + ) -> impl FutureMaybeSend> { let mast_forest = self.base_host.get_mast_forest(node_digest); async move { mast_forest } } diff --git a/crates/miden-tx/src/executor/mod.rs b/crates/miden-tx/src/executor/mod.rs index ab8d76f3c5..02c14d224c 100644 --- a/crates/miden-tx/src/executor/mod.rs +++ b/crates/miden-tx/src/executor/mod.rs @@ -97,8 +97,6 @@ where Some(MAX_TX_EXECUTION_CYCLES), MIN_TX_EXECUTION_CYCLES, ExecutionOptions::DEFAULT_CORE_TRACE_FRAGMENT_SIZE, - false, - false, ) .expect("Must not fail while max cycles is more than min trace length"), _executor: PhantomData, @@ -176,8 +174,7 @@ where /// account code) will be compiled and executed in debug mode. This will ensure that all debug /// instructions present in the original source code are executed. #[must_use] - pub fn with_debug_mode(mut self) -> Self { - self.exec_options = self.exec_options.with_debugging(true); + pub fn with_debug_mode(self) -> Self { self } @@ -188,8 +185,7 @@ where /// transaction kernel complete. This enables collecting basic stats about how long different /// stages of transaction execution take. #[must_use] - pub fn with_tracing(mut self) -> Self { - self.exec_options = self.exec_options.with_tracing(true); + pub fn with_tracing(self) -> Self { self } diff --git a/crates/miden-tx/src/host/mod.rs b/crates/miden-tx/src/host/mod.rs index ec56fc876d..9aff27fe90 100644 --- a/crates/miden-tx/src/host/mod.rs +++ b/crates/miden-tx/src/host/mod.rs @@ -28,14 +28,12 @@ mod tx_progress; mod tx_event; use alloc::boxed::Box; use alloc::collections::BTreeMap; -use alloc::sync::Arc; use alloc::vec::Vec; use miden_processor::advice::AdviceMutation; use miden_processor::event::{EventError, EventHandlerRegistry}; -use miden_processor::mast::MastForest; use miden_processor::trace::RowIndex; -use miden_processor::{Felt, MastForestStore, ProcessorState}; +use miden_processor::{Felt, LoadedMastForest, MastForestStore, ProcessorState}; use miden_protocol::Word; use miden_protocol::account::{ AccountCode, @@ -485,7 +483,7 @@ where STORE: MastForestStore, { /// Returns the [`MastForest`] that contains the procedure with the given `procedure_root`. - pub fn get_mast_forest(&self, procedure_root: &Word) -> Option> { + pub fn get_mast_forest(&self, procedure_root: &Word) -> Option { // Search in the note MAST forest store, otherwise fall back to the user-provided store match self.scripts_mast_store.get(procedure_root) { Some(forest) => Some(forest), diff --git a/crates/miden-tx/src/host/script_mast_forest_store.rs b/crates/miden-tx/src/host/script_mast_forest_store.rs index 6a8e82054d..7e478b880f 100644 --- a/crates/miden-tx/src/host/script_mast_forest_store.rs +++ b/crates/miden-tx/src/host/script_mast_forest_store.rs @@ -1,9 +1,7 @@ use alloc::collections::BTreeMap; -use alloc::sync::Arc; -use miden_processor::MastForestStore; +use miden_processor::{LoadedMastForest, MastForestStore}; use miden_protocol::Word; -use miden_protocol::assembly::mast::MastForest; use miden_protocol::note::NoteScript; use miden_protocol::transaction::TransactionScript; use miden_protocol::vm::AdviceMap; @@ -14,7 +12,7 @@ use miden_protocol::vm::AdviceMap; /// transaction and input note scripts. #[derive(Debug, Clone, Default)] pub struct ScriptMastForestStore { - mast_forests: BTreeMap>, + mast_forests: BTreeMap, advice_map: AdviceMap, } @@ -30,24 +28,24 @@ impl ScriptMastForestStore { }; for note_script in note_scripts { - mast_store.insert(note_script.as_ref().mast()); + mast_store.insert(note_script.as_ref().loaded_mast_forest()); } if let Some(tx_script) = tx_script { - mast_store.insert(tx_script.mast()); + mast_store.insert(tx_script.loaded_mast_forest()); } mast_store } /// Registers all procedures of the provided [MastForest] with this store. - fn insert(&mut self, mast_forest: Arc) { + fn insert(&mut self, loaded_mast_forest: LoadedMastForest) { // only register procedures that are local to this forest - for proc_digest in mast_forest.local_procedure_digests() { - self.mast_forests.insert(proc_digest, mast_forest.clone()); + for proc_digest in loaded_mast_forest.mast_forest().local_procedure_digests() { + self.mast_forests.insert(proc_digest, loaded_mast_forest.clone()); } // collect advice data from the forest - for (key, values) in mast_forest.advice_map().clone() { + for (key, values) in loaded_mast_forest.mast_forest().advice_map().clone() { self.advice_map.insert((*key).into(), values); } } @@ -62,7 +60,7 @@ impl ScriptMastForestStore { // ================================================================================================ impl MastForestStore for ScriptMastForestStore { - fn get(&self, procedure_root: &Word) -> Option> { + fn get(&self, procedure_root: &Word) -> Option { self.mast_forests.get(procedure_root).cloned() } } diff --git a/crates/miden-tx/src/prover/mast_store.rs b/crates/miden-tx/src/prover/mast_store.rs index 0a30ae883c..66b62f4a0e 100644 --- a/crates/miden-tx/src/prover/mast_store.rs +++ b/crates/miden-tx/src/prover/mast_store.rs @@ -1,11 +1,12 @@ use alloc::collections::BTreeMap; use alloc::sync::Arc; -use miden_processor::MastForestStore; +use miden_processor::{LoadedMastForest, MastForestStore}; use miden_protocol::account::AccountCode; use miden_protocol::assembly::mast::MastForest; use miden_protocol::transaction::TransactionKernel; use miden_protocol::utils::sync::RwLock; +use miden_protocol::vm::{Package, PackageDebugInfo, PackageDebugInfoError}; use miden_protocol::{CoreLibrary, ProtocolLib, Word}; use miden_standards::StandardsLib; @@ -20,7 +21,7 @@ use miden_standards::StandardsLib; /// references to external procedures, the store must be loaded with [MastForest]s containing these /// procedures. pub struct TransactionMastStore { - mast_forests: RwLock>>, + mast_forests: RwLock>, } #[allow(clippy::new_without_default)] @@ -37,37 +38,47 @@ impl TransactionMastStore { let store = Self { mast_forests }; // load transaction kernel MAST forest - let kernels_forest = TransactionKernel::kernel().mast_forest().clone(); - store.insert(kernels_forest); + let kernel = TransactionKernel::kernel(); + store.insert_package(&kernel); // load miden-core-lib MAST forest - let miden_core_lib_forest = CoreLibrary::default().mast_forest().clone(); - store.insert(miden_core_lib_forest); + let miden_core_lib = CoreLibrary::default(); + store.insert_package(miden_core_lib.as_ref()); // load protocol lib MAST forest - let protocol_lib_forest = ProtocolLib::default().mast_forest().clone(); - store.insert(protocol_lib_forest); + let protocol_lib = ProtocolLib::default(); + store.insert_package(protocol_lib.as_ref()); // load standards lib MAST forest - let standards_lib_forest = StandardsLib::default().mast_forest().clone(); - store.insert(standards_lib_forest); + let standards_lib = StandardsLib::default(); + store.insert_package(standards_lib.as_ref()); store } /// Registers all procedures of the provided [MastForest] with this store. pub fn insert(&self, mast_forest: Arc) { + self.insert_loaded(LoadedMastForest::new(mast_forest)); + } + + /// Registers all procedures of the provided [Package] with this store. + fn insert_package(&self, package: &Package) { + self.insert_loaded(loaded_mast_forest_from_package(package)); + } + + /// Registers all procedures of the provided loaded MAST forest with this store. + pub fn insert_loaded(&self, loaded_mast_forest: LoadedMastForest) { let mut mast_forests = self.mast_forests.write(); // only register procedures that are local to this forest - for proc_digest in mast_forest.local_procedure_digests() { - mast_forests.insert(proc_digest, mast_forest.clone()); + for proc_digest in loaded_mast_forest.mast_forest().local_procedure_digests() { + mast_forests.insert(proc_digest, loaded_mast_forest.clone()); } } /// Loads the provided account code into this store. pub fn load_account_code(&self, code: &AccountCode) { - self.insert(code.mast().clone()); + self.insert_loaded(code.loaded_mast_forest()); } } @@ -75,11 +86,29 @@ impl TransactionMastStore { // ================================================================================================ impl MastForestStore for TransactionMastStore { - fn get(&self, procedure_root: &Word) -> Option> { + fn get(&self, procedure_root: &Word) -> Option { self.mast_forests.read().get(procedure_root).cloned() } } +fn loaded_mast_forest_from_package(package: &Package) -> LoadedMastForest { + match decode_package_debug_info(package) { + Some(package_debug_info) => LoadedMastForest::with_package_debug_info( + package.mast_forest().clone(), + Ok(Some((*package_debug_info).clone())), + ), + None => LoadedMastForest::new(package.mast_forest().clone()), + } +} + +fn decode_package_debug_info(package: &Package) -> Option> { + match package.debug_info() { + Ok(debug_info) => debug_info.map(Arc::new), + Err(PackageDebugInfoError::UntrustedSections) => None, + Err(_) => None, + } +} + #[cfg(test)] impl TransactionMastStore { /// Returns the number of procedure entries in the store (for testing only). diff --git a/crates/miden-tx/src/prover/prover_host.rs b/crates/miden-tx/src/prover/prover_host.rs index bfb939d3a3..860489d512 100644 --- a/crates/miden-tx/src/prover/prover_host.rs +++ b/crates/miden-tx/src/prover/prover_host.rs @@ -3,8 +3,14 @@ use alloc::vec::Vec; use miden_processor::advice::AdviceMutation; use miden_processor::event::EventError; -use miden_processor::mast::MastForest; -use miden_processor::{BaseHost, FutureMaybeSend, Host, MastForestStore, ProcessorState}; +use miden_processor::{ + BaseHost, + FutureMaybeSend, + Host, + LoadedMastForest, + MastForestStore, + ProcessorState, +}; use miden_protocol::Word; use miden_protocol::account::{AccountPatch, PartialAccount}; use miden_protocol::assembly::debuginfo::Location; @@ -92,7 +98,10 @@ impl Host for TransactionProverHost<'_, STORE> where STORE: MastForestStore, { - fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend>> { + fn get_mast_forest( + &self, + node_digest: &Word, + ) -> impl FutureMaybeSend> { let result = self.base_host.get_mast_forest(node_digest); async move { result } } diff --git a/deny.toml b/deny.toml index 690b65da85..46859850fc 100644 --- a/deny.toml +++ b/deny.toml @@ -51,15 +51,13 @@ skip = [ { name = "digest" }, { name = "keccak" }, { name = "sha3" }, - # Allow duplicate rand versions - miden-field uses 0.10, miden-vm uses 0.9 + # Allow duplicate rand versions - miden-field uses 0.10, proptest uses 0.9. + { name = "getrandom" }, { name = "rand" }, + { name = "rand_chacha" }, { name = "rand_core" }, ] skip-tree = [ - # Allow getrandom v0.2.x - legacy version used by nanorand - { name = "getrandom", version = "=0.2.*" }, - # Allow rand_core v0.6.x - legacy version used by winterfell crates - { name = "rand_core", version = "=0.6.*" }, # Allow rustc_version v0.2.x - build dependency version { name = "rustc_version", version = "=0.2.*" }, # Allow unicode-width v0.1.x - used by miden-formatting vs textwrap conflict diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a37cb5745c..b88d61ab1a 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.94" +channel = "1.96" components = ["clippy", "rust-src", "rustfmt"] profile = "minimal" targets = ["wasm32-unknown-unknown"]