diff --git a/Cargo.lock b/Cargo.lock index e94956126d..cae8740ce3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,7 +106,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -117,7 +117,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -199,15 +199,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "backtrace-ext" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" -dependencies = [ - "backtrace", -] - [[package]] name = "base16ct" version = "0.2.0" @@ -256,6 +247,15 @@ dependencies = [ "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" @@ -307,9 +307,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" @@ -331,9 +331,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.49" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "jobserver", @@ -650,18 +650,18 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "proc-macro2", "quote", @@ -669,6 +669,12 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" @@ -816,7 +822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -853,9 +859,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "findshlibs" @@ -895,9 +901,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fs-err" -version = "3.2.0" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d91fd049c123429b018c47887d3f75a265540dd3c30ba9cb7bae9197edb03a" +checksum = "baf68cef89750956493a66a10f512b9e58d9db21f2a573c079c0bdf1207a54a7" dependencies = [ "autocfg", ] @@ -984,16 +990,17 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" dependencies = [ "cc", "cfg-if", "libc", "log", "rustversion", - "windows", + "windows-link", + "windows-result", ] [[package]] @@ -1157,15 +1164,9 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys", ] -[[package]] -name = "is_ci" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1201,15 +1202,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +checksum = "a87d9b8105c23642f50cbbae03d1f75d8422c5cb98ce7ee9271f7ff7505be6b8" dependencies = [ "jiff-static", "log", @@ -1220,9 +1221,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +checksum = "b787bebb543f8969132630c51fd0afab173a86c6abae56ff3b9e5e3e3f9f6e58" dependencies = [ "proc-macro2", "quote", @@ -1320,12 +1321,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -1386,22 +1381,28 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e663337017ed028dff8c18a0ce1db64aad0e850996e3214f137f98317533c2e1" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "miden-core", + "miden-crypto", "miden-utils-indexing", + "p3-blake3", + "p3-commit", + "p3-dft", + "p3-keccak", + "p3-matrix", + "p3-merkle-tree", + "p3-miden-fri", + "serde", "thiserror", - "winter-air", - "winter-prover", + "tracing", ] [[package]] name = "miden-assembly" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001249195c227624695529c82ebf51c390ec1c28e99a567549ce3a272a2aedf3" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "env_logger", "log", @@ -1414,9 +1415,8 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1963cfa667aa6a157c99982df340a7bd42b054652e6f33d5e3513217531eca73" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "aho-corasick", "env_logger", @@ -1446,9 +1446,8 @@ dependencies = [ [[package]] name = "miden-core" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136debf5474190dc584df3252710dac07a0e45315740c9538a7fc0b72c596365" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "derive_more", "itertools 0.14.0", @@ -1457,20 +1456,19 @@ dependencies = [ "miden-formatting", "miden-utils-core-derive", "miden-utils-indexing", + "miden-utils-sync", "num-derive", "num-traits", "proptest", "proptest-derive", + "serde", "thiserror", - "winter-math", - "winter-utils", ] [[package]] name = "miden-core-lib" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcec9fb9a256d2fae347162d9a94653a1790dd33b4af73ad29686475b63deb34" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "env_logger", "fs-err", @@ -1485,9 +1483,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.19.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc7981c1d907bb9864e24f2bd6304c4fca03a41fc4606c09edd6a7f5a8fc80fc" +checksum = "5faabb0c18b902bc08e0af0375ecd96252939492ab138f0fc94c112a8dcb40e3" dependencies = [ "blake3", "cc", @@ -1500,28 +1498,34 @@ dependencies = [ "hkdf", "k256", "miden-crypto-derive", + "miden-serde-utils", "num", "num-complex", + "p3-air", + "p3-challenger", + "p3-field", + "p3-miden-air", + "p3-miden-goldilocks", + "p3-miden-prover", + "p3-symmetric", "rand", "rand_chacha", "rand_core 0.9.3", "rand_hc", "rayon", + "serde", "sha2", "sha3", "subtle", "thiserror", - "winter-crypto", - "winter-math", - "winter-utils", "x25519-dalek", ] [[package]] name = "miden-crypto-derive" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83479e7af490784c6f2d2e02cec5210fd6e5bc6ce3d4427734e36a773bca72d2" +checksum = "7ac7d0e73d4cf3a5682846dfabcc53fc28d24fa2462a5668ef1f8d5d65614d3f" dependencies = [ "quote", "syn 2.0.111", @@ -1529,9 +1533,8 @@ dependencies = [ [[package]] name = "miden-debug-types" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dc25083822c3d582c42ad10aeee0138dec15a130f3017b05495bb91e31fde4a" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "memchr", "miden-crypto", @@ -1556,9 +1559,8 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da35f2fc1eacbfd0b6b995e888c2b778bd646acebf34dab27f9f7ed9b3effaa2" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "derive_more", "miden-assembly-syntax", @@ -1572,8 +1574,6 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eef536978f24a179d94fa2a41e4f92b28e7d8aab14b8d23df28ad2a3d7098b20" dependencies = [ - "backtrace", - "backtrace-ext", "cfg-if", "futures", "indenter", @@ -1586,11 +1586,7 @@ dependencies = [ "serde_json", "spin 0.9.8", "strip-ansi-escapes", - "supports-color", - "supports-hyperlinks", - "supports-unicode", "syn 2.0.111", - "terminal_size", "textwrap", "thiserror", "trybuild", @@ -1610,9 +1606,8 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb298dbdda739080497c18eace4d56c58f3e8d257676c9b2f407be441131ecd" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "itertools 0.14.0", "miden-air", @@ -1620,12 +1615,12 @@ dependencies = [ "miden-debug-types", "miden-utils-diagnostics", "miden-utils-indexing", + "p3-matrix", "paste", "rayon", "thiserror", "tokio", "tracing", - "winter-prover", ] [[package]] @@ -1649,6 +1644,7 @@ dependencies = [ "miden-processor", "miden-protocol", "miden-protocol-macros", + "miden-test-utils", "miden-utils-sync", "miden-verifier", "pprof", @@ -1664,7 +1660,6 @@ dependencies = [ "toml", "walkdir", "winter-air", - "winter-rand-utils", ] [[package]] @@ -1679,16 +1674,32 @@ dependencies = [ [[package]] name = "miden-prover" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8506c8eb4d980134c0145887af50bd4631df4010eb23d6e454764cb1ee28836c" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ + "bincode", "miden-air", + "miden-core", + "miden-crypto", "miden-debug-types", "miden-processor", + "p3-matrix", + "p3-merkle-tree", + "serde", + "tokio", "tracing", - "winter-maybe-async", - "winter-prover", +] + +[[package]] +name = "miden-serde-utils" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6448da86226ead305347408061e224d9214deafa2bd946bd2e471b48419b289f" +dependencies = [ + "p3-field", + "p3-miden-goldilocks", + "winter-math", + "winter-utils", ] [[package]] @@ -1710,6 +1721,24 @@ dependencies = [ "walkdir", ] +[[package]] +name = "miden-test-utils" +version = "0.1.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" +dependencies = [ + "env_logger", + "miden-air", + "miden-assembly", + "miden-core", + "miden-crypto", + "miden-processor", + "miden-prover", + "miden-verifier", + "pretty_assertions", + "proptest", + "test-case", +] + [[package]] name = "miden-testing" version = "0.13.0" @@ -1717,6 +1746,7 @@ dependencies = [ "anyhow", "assert_matches", "itertools 0.14.0", + "miden-air", "miden-block-prover", "miden-processor", "miden-protocol", @@ -1728,7 +1758,6 @@ dependencies = [ "rstest", "tokio", "winter-rand-utils", - "winterfell", ] [[package]] @@ -1737,7 +1766,10 @@ version = "0.13.0" dependencies = [ "anyhow", "assert_matches", + "bincode", + "miden-air", "miden-assembly", + "miden-crypto", "miden-processor", "miden-protocol", "miden-prover", @@ -1758,9 +1790,8 @@ dependencies = [ [[package]] name = "miden-utils-core-derive" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0807840c07a4491a292153258cfae27914333e1a7240777a77c22d8ca3b55873" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "proc-macro2", "quote", @@ -1769,9 +1800,8 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b28b1b29e300b471b0f1cbc286997a1326c900814a73b0b28338d5926ce192c" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "miden-crypto", "miden-debug-types", @@ -1782,35 +1812,35 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bd0c1966de07d48a4ed0b2821466919c061f4866296be87afc56970a49716a" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ + "serde", "thiserror", ] [[package]] name = "miden-utils-sync" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa7e37db2fbf2dee6ba6e411b3570ef48d52ec780b9c8125623f9ddca30da3" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ "lock_api", "loom", + "once_cell", "parking_lot", ] [[package]] name = "miden-verifier" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383c934eed92f89be4c1e3dbc97ccf37b48433a0b33727c92a5abbfa2d45f420" +version = "0.21.0" +source = "git+https://github.com/0xPolygonMiden/miden-vm?branch=next#285d6c872820c10bdde04322ba387c7731e6cc27" dependencies = [ + "bincode", "miden-air", "miden-core", + "miden-crypto", "thiserror", "tracing", - "winter-verifier", ] [[package]] @@ -1865,7 +1895,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -2009,155 +2039,483 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] -name = "parking_lot" -version = "0.12.5" +name = "p3-air" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "60414dc4fe4b8676bd4b6136b309185e6b3c006eb5564ef4cf5dfae6d9d47f32" dependencies = [ - "lock_api", - "parking_lot_core", + "p3-field", + "p3-matrix", ] [[package]] -name = "parking_lot_core" -version = "0.9.12" +name = "p3-blake3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "3db49d8917c4d4d4dfeaf8b8a392921800cc05d877e5021509d4cc87c45f59dd" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link 0.2.1", + "blake3", + "p3-symmetric", + "p3-util", ] [[package]] -name = "paste" -version = "1.0.15" +name = "p3-challenger" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +checksum = "b8a66da8af6115b9e2df4363cd55efebf2c6d30de0af3e99dac56dd7b77aff24" +dependencies = [ + "p3-field", + "p3-maybe-rayon", + "p3-monty-31", + "p3-symmetric", + "p3-util", + "tracing", +] [[package]] -name = "petgraph" -version = "0.7.1" +name = "p3-commit" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "95104feb4b9895733f92204ec70ba8944dbab39c39b235c0a00adf1456149619" dependencies = [ - "fixedbitset", - "indexmap", + "itertools 0.14.0", + "p3-challenger", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-util", + "serde", ] [[package]] -name = "phf_shared" -version = "0.11.3" +name = "p3-dft" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "81b2f57569293b9964b1bae68d64e796bfbf3c271718268beb53a0fb761a5819" dependencies = [ - "siphasher", + "itertools 0.14.0", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "spin 0.10.0", + "tracing", ] [[package]] -name = "pin-project-lite" -version = "0.2.16" +name = "p3-field" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "56aae7630ff6df83fb7421d5bd97df27620e5f0e29422b7e8f6a294d44cce297" +dependencies = [ + "itertools 0.14.0", + "num-bigint", + "p3-maybe-rayon", + "p3-util", + "paste", + "rand", + "serde", + "tracing", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "p3-interpolation" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "4b0bb6a709b26cead74e7c605f4e51e793642870e54a7c280a05cd66b7914866" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", +] [[package]] -name = "pkcs8" -version = "0.10.2" +name = "p3-keccak" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "ac5bb06ef1f2794dbd303b5d6a46a4b0ef34a6f7fb787b7202177438abf5bb66" dependencies = [ - "der", - "spki", + "p3-field", + "p3-symmetric", + "p3-util", + "tiny-keccak", ] [[package]] -name = "plotters" -version = "0.3.7" +name = "p3-matrix" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +checksum = "d916550e4261126457d4f139fc3156fc796b1cf2f2687bf1c9b269b1efa8ad42" dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", + "itertools 0.14.0", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand", + "serde", + "tracing", + "transpose", ] [[package]] -name = "plotters-backend" -version = "0.3.7" +name = "p3-maybe-rayon" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" +checksum = "0db6a290f867061aed54593d48f0dfd7ff2d0f706a603d03209fd0eac79518f3" [[package]] -name = "plotters-svg" -version = "0.3.7" +name = "p3-mds" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +checksum = "745a478473a5f3699f76b284378651eaa9d74e74f820b34ea563a4a72ab8a4a6" dependencies = [ - "plotters-backend", + "p3-dft", + "p3-field", + "p3-symmetric", + "p3-util", + "rand", ] [[package]] -name = "poly1305" -version = "0.8.0" +name = "p3-merkle-tree" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "615f09d1c83ca2ad0dd1f8fb4e496445f9c24a224bac81b98849973f444ee86c" dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", + "itertools 0.14.0", + "p3-commit", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "rand", + "serde", + "thiserror", + "tracing", ] [[package]] -name = "portable-atomic" -version = "1.11.1" +name = "p3-miden-air" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "b4217edd6ea816e81c1282c8e052516973582cb86add4729036bdbaabdb38d8f" +dependencies = [ + "p3-air", + "p3-field", + "p3-matrix", +] [[package]] -name = "portable-atomic-util" -version = "0.2.4" +name = "p3-miden-fri" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "9be454c3047e0727b7ae494b4d86e6f64ea57eb7bc3f1323b000d8c4f6d563de" dependencies = [ - "portable-atomic", + "itertools 0.14.0", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "rand", + "serde", + "tracing", ] [[package]] -name = "pprof" -version = "0.15.0" +name = "p3-miden-goldilocks" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a01da47675efa7673b032bf8efd8214f1917d89685e07e395ab125ea42b187" +checksum = "a883bc797df1c43b06f2d467340625ee736f748928d1ceb402d27eb05e694394" dependencies = [ - "aligned-vec", - "backtrace", - "cfg-if", - "criterion 0.5.1", - "findshlibs", - "inferno", - "libc", - "log", - "nix", - "once_cell", - "smallvec", - "spin 0.10.0", - "symbolic-demangle", - "tempfile", - "thiserror", + "num-bigint", + "p3-challenger", + "p3-dft", + "p3-field", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "paste", + "rand", + "serde", ] [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "p3-miden-prover" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e043fcf77772ac765e21335d73b513d76ba9b4adb54994d925ba38dcd557811" +dependencies = [ + "itertools 0.14.0", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-miden-air", + "p3-miden-uni-stark", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-miden-uni-stark" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6580b5e0fca4e3fb03e9a1d0a70e2068ec26ea04fe84932815a49c02bedf319f" +dependencies = [ + "itertools 0.14.0", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-uni-stark", + "p3-util", + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "p3-monty-31" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f124f989bc5697728a9e71d2094eda673c45a536c6a8b8ec87b7f3660393aad0" +dependencies = [ + "itertools 0.14.0", + "num-bigint", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "paste", + "rand", + "serde", + "spin 0.10.0", + "tracing", + "transpose", +] + +[[package]] +name = "p3-poseidon2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0c96988fd809e7a3086d8d683ddb93c965f8bb08b37c82e3617d12347bf77f" +dependencies = [ + "p3-field", + "p3-mds", + "p3-symmetric", + "p3-util", + "rand", +] + +[[package]] +name = "p3-symmetric" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabf1c93a83305b291118dec6632357da69f3137d33fc1791225e38fcb615836" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "serde", +] + +[[package]] +name = "p3-uni-stark" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88335b341c58063007e0f09773a0bc9136b03cc123db61ac4282031e97dbf7cc" +dependencies = [ + "itertools 0.14.0", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "p3-util" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92074eab13c8a30d23ad7bcf99b82787a04c843133a0cba39ca1cf39d434492" +dependencies = [ + "serde", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "petgraph" +version = "0.7.1" +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", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "pprof" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38a01da47675efa7673b032bf8efd8214f1917d89685e07e395ab125ea42b187" +dependencies = [ + "aligned-vec", + "backtrace", + "cfg-if", + "criterion 0.5.1", + "findshlibs", + "inferno", + "libc", + "log", + "nix", + "once_cell", + "smallvec", + "spin 0.10.0", + "symbolic-demangle", + "tempfile", + "thiserror", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ @@ -2170,6 +2528,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-crate" version = "3.4.0" @@ -2181,9 +2549,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -2441,28 +2809,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "linux-raw-sys", + "windows-sys", ] [[package]] @@ -2471,12 +2826,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - [[package]] name = "same-file" version = "1.0.6" @@ -2569,23 +2918,23 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "indexmap", "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -2700,6 +3049,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" +[[package]] +name = "strength_reduce" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" + [[package]] name = "string_cache" version = "0.8.9" @@ -2727,27 +3082,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "supports-color" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" -dependencies = [ - "is_ci", -] - -[[package]] -name = "supports-hyperlinks" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" - -[[package]] -name = "supports-unicode" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" - [[package]] name = "symbolic-common" version = "12.17.0" @@ -2800,15 +3134,15 @@ checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix 1.1.2", - "windows-sys 0.61.2", + "rustix", + "windows-sys", ] [[package]] @@ -2817,7 +3151,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" dependencies = [ - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -2830,13 +3164,36 @@ dependencies = [ ] [[package]] -name = "terminal_size" -version = "0.3.0" +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "test-case-macros" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ - "rustix 0.38.44", - "windows-sys 0.48.0", + "proc-macro2", + "quote", + "syn 2.0.111", + "test-case-core", ] [[package]] @@ -2879,6 +3236,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -2936,9 +3302,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.8" +version = "0.9.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" dependencies = [ "indexmap", "serde_core", @@ -2951,18 +3317,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", "toml_datetime", @@ -2972,24 +3338,24 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3009,9 +3375,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -3067,6 +3433,16 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "transpose" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" +dependencies = [ + "num-integer", + "strength_reduce", +] + [[package]] name = "trybuild" version = "1.0.114" @@ -3274,7 +3650,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -3283,130 +3659,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.61.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" -dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-link 0.1.3", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core", - "windows-link 0.1.3", - "windows-threading", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core", - "windows-link 0.1.3", -] - [[package]] name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -3415,139 +3680,9 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows-link", ] -[[package]] -name = "windows-threading" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "winnow" version = "0.7.14" @@ -3602,31 +3737,6 @@ dependencies = [ "winter-utils", ] -[[package]] -name = "winter-maybe-async" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d31a19dae58475d019850e25b0170e94b16d382fbf6afee9c0e80fdc935e73e" -dependencies = [ - "quote", - "syn 2.0.111", -] - -[[package]] -name = "winter-prover" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84cc631ed56cd39b78ef932c1ec4060cc6a44d114474291216c32f56655b3048" -dependencies = [ - "tracing", - "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-maybe-async", - "winter-utils", -] - [[package]] name = "winter-rand-utils" version = "0.13.1" @@ -3642,33 +3752,6 @@ name = "winter-utils" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9951263ef5317740cd0f49e618db00c72fabb70b75756ea26c4d5efe462c04dd" -dependencies = [ - "rayon", -] - -[[package]] -name = "winter-verifier" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0425ea81f8f703a1021810216da12003175c7974a584660856224df04b2e2fdb" -dependencies = [ - "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", -] - -[[package]] -name = "winterfell" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f824ddd5aec8ca6a54307f20c115485a8a919ea94dd26d496d856ca6185f4f" -dependencies = [ - "winter-air", - "winter-prover", - "winter-verifier", -] [[package]] name = "wit-bindgen" @@ -3686,6 +3769,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "zerocopy" version = "0.8.31" @@ -3711,3 +3800,9 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zmij" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d" diff --git a/Cargo.toml b/Cargo.toml index 6bd3cf0716..6db8d6017b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,11 +30,6 @@ lto = true inherits = "dev" opt-level = 1 -# Avoid running the expensive debug assertion in winter-prover -# https://github.com/facebook/winterfell/blob/cd32dce2fd4986c94516113568eefd938fafe31c/prover/src/lib.rs#L355C1-L356 -[profile.test-dev.package.winter-prover] -debug-assertions = false - [profile.bench] codegen-units = 1 lto = true @@ -50,17 +45,17 @@ miden-tx = { default-features = false, path = "crates/miden-tx", ve miden-tx-batch-prover = { default-features = false, path = "crates/miden-tx-batch-prover", version = "0.13" } # Miden dependencies -miden-air = { default-features = false, version = "0.20" } -miden-assembly = { default-features = false, version = "0.20" } -miden-assembly-syntax = { default-features = false, version = "0.20" } -miden-core = { default-features = false, version = "0.20" } -miden-core-lib = { default-features = false, version = "0.20" } -miden-crypto = { default-features = false, version = "0.19" } -miden-mast-package = { default-features = false, version = "0.20" } -miden-processor = { default-features = false, version = "0.20" } -miden-prover = { default-features = false, version = "0.20" } -miden-utils-sync = { default-features = false, version = "0.20" } -miden-verifier = { default-features = false, version = "0.20" } +miden-air = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-assembly = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-assembly-syntax = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-core = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-core-lib = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-crypto = { default-features = false, version = "0.20.1" } +miden-mast-package = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-processor = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-prover = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-utils-sync = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } +miden-verifier = { branch = "next", default-features = false, git = "https://github.com/0xPolygonMiden/miden-vm" } # External dependencies anyhow = { default-features = false, features = ["backtrace", "std"], version = "1.0" } diff --git a/Makefile b/Makefile index 10f3f8823a..1f5121eb0c 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ clippy: ## Runs Clippy with configs .PHONY: clippy-no-std clippy-no-std: ## Runs Clippy with configs - cargo clippy --no-default-features --target wasm32-unknown-unknown --workspace --lib -- -D warnings + cargo clippy --no-default-features --target wasm32-unknown-unknown --workspace --lib --exclude bench-note-checker --exclude bench-transaction -- -D warnings .PHONY: fix diff --git a/crates/miden-protocol-macros/Cargo.toml b/crates/miden-protocol-macros/Cargo.toml index 0ec8930785..801afab9ba 100644 --- a/crates/miden-protocol-macros/Cargo.toml +++ b/crates/miden-protocol-macros/Cargo.toml @@ -21,7 +21,7 @@ quote = "1.0" syn = { features = ["extra-traits", "full"], version = "2.0" } [dev-dependencies] -miden-protocol = { path = "../miden-protocol" } +miden-protocol = { default-features = false, path = "../miden-protocol" } [package.metadata.cargo-machete] ignored = ["proc-macro2"] diff --git a/crates/miden-protocol-macros/tests/integration_test.rs b/crates/miden-protocol-macros/tests/integration_test.rs index 05a925e4d5..63a4776a43 100644 --- a/crates/miden-protocol-macros/tests/integration_test.rs +++ b/crates/miden-protocol-macros/tests/integration_test.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod tests { - use miden_protocol::{Felt, FieldElement, Word}; + use miden_protocol::{Felt, ONE, Word, ZERO}; use miden_protocol_macros::WordWrapper; #[derive(Debug, Clone, Copy, PartialEq, Eq, WordWrapper)] @@ -9,15 +9,15 @@ mod tests { #[test] fn test_word_wrapper_accessors() { // Create a test Word - let word = Word::from([Felt::ONE, Felt::ONE, Felt::ZERO, Felt::ZERO]); + let word = Word::from([ONE, ONE, ZERO, ZERO]); // Use the new_unchecked method generated by the macro let test_id = TestId::from_raw(word); // Test as_elements let elements = test_id.as_elements(); assert_eq!(elements.len(), 4); - assert_eq!(elements[0], Felt::ONE); - assert_eq!(elements[1], Felt::ONE); + assert_eq!(elements[0], ONE); + assert_eq!(elements[1], ONE); // Test as_bytes let bytes = test_id.as_bytes(); @@ -35,7 +35,7 @@ mod tests { #[test] fn test_new_unchecked_is_generated() { // This test verifies that new_unchecked is generated by the macro - let word = Word::from([Felt::ONE, Felt::ONE, Felt::ZERO, Felt::ZERO]); + let word = Word::from([ONE, ONE, ZERO, ZERO]); let test_id = TestId::from_raw(word); assert_eq!(test_id.as_word(), word); } diff --git a/crates/miden-protocol/Cargo.toml b/crates/miden-protocol/Cargo.toml index ea4b9c629d..508a3c820b 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", "dep:winter-rand-utils", "miden-air/testing"] +testing = ["dep:miden-test-utils", "dep:rand_chacha", "dep:rand_xoshiro", "miden-air/testing"] [dependencies] # Miden dependencies @@ -43,9 +43,9 @@ miden-crypto = { workspace = true } miden-mast-package = { workspace = true } miden-processor = { workspace = true } miden-protocol-macros = { workspace = true } +miden-test-utils = { branch = "next", git = "https://github.com/0xPolygonMiden/miden-vm", optional = true } miden-utils-sync = { workspace = true } miden-verifier = { workspace = true } -winter-rand-utils = { optional = true, version = "0.13" } # External dependencies bech32 = { default-features = false, features = ["alloc"], version = "0.11" } @@ -65,19 +65,19 @@ getrandom = { features = ["wasm_js"], version = "0.3" } anyhow = { features = ["backtrace", "std"], workspace = true } assert_matches = { workspace = true } criterion = { default-features = false, features = ["html_reports"], version = "0.5" } -miden-protocol = { features = ["testing"], path = "." } +miden-protocol = { default-features = false, features = ["testing"], path = "." } pprof = { default-features = false, features = ["criterion", "flamegraph"], version = "0.15" } rstest = { workspace = true } tempfile = { version = "3.19" } winter-air = { version = "0.13" } # for HashFunction/ExecutionProof::new_dummy color-eyre = { version = "0.5" } -miden-air = { features = ["std", "testing"], workspace = true } +miden-air = { default-features = false, features = ["std", "testing"], workspace = true } [build-dependencies] fs-err = { version = "3" } -miden-assembly = { workspace = true } -miden-core = { workspace = true } -miden-core-lib = { workspace = true } +miden-assembly = { default-features = false, workspace = true } +miden-core = { default-features = false, workspace = true } +miden-core-lib = { default-features = false, workspace = true } regex = { version = "1.11" } walkdir = { version = "2.5" } diff --git a/crates/miden-protocol/src/account/account_id/id_prefix.rs b/crates/miden-protocol/src/account/account_id/id_prefix.rs index 46207bcc85..2c4e9ddb9b 100644 --- a/crates/miden-protocol/src/account/account_id/id_prefix.rs +++ b/crates/miden-protocol/src/account/account_id/id_prefix.rs @@ -1,6 +1,8 @@ use alloc::string::{String, ToString}; use core::fmt; +use miden_core::field::PrimeField64; + use super::v0; use crate::Felt; use crate::account::account_id::AccountIdPrefixV0; @@ -162,8 +164,7 @@ impl AccountIdPrefix { // Set the fungible bit to zero by taking the bitwise `and` of the felt with the // inverted is_faucet mask. let clear_fungible_bit_mask = !AccountIdV0::IS_FAUCET_MASK; - Felt::try_from(felt.as_int() & clear_fungible_bit_mask) - .expect("felt should still be valid as we cleared a bit and did not set any") + Felt::from(felt.as_int() & clear_fungible_bit_mask) }, } } @@ -237,8 +238,16 @@ impl TryFrom for AccountIdPrefix { /// Returns an error if any of the ID constraints are not met. See the [constraints /// documentation](super::AccountId#constraints) for details. fn try_from(value: u64) -> Result { - let element = Felt::try_from(value.to_le_bytes().as_slice()) - .map_err(AccountIdError::AccountIdInvalidPrefixFieldElement)?; + // Validate that the value is within the field modulus + if value >= Felt::ORDER_U64 { + return Err(AccountIdError::AccountIdInvalidPrefixFieldElement( + DeserializationError::InvalidValue(format!( + "Value {} outside field modulus", + value + )), + )); + } + let element = Felt::new(value); Self::new(element) } } diff --git a/crates/miden-protocol/src/account/account_id/v0/mod.rs b/crates/miden-protocol/src/account/account_id/v0/mod.rs index c14095819d..0018af356c 100644 --- a/crates/miden-protocol/src/account/account_id/v0/mod.rs +++ b/crates/miden-protocol/src/account/account_id/v0/mod.rs @@ -6,6 +6,7 @@ use core::hash::Hash; use bech32::Bech32m; use bech32::primitives::decode::{ByteIter, CheckedHrpstring}; +use miden_core::field::PrimeField64; use miden_crypto::utils::hex_to_bytes; pub use prefix::AccountIdPrefixV0; @@ -118,8 +119,7 @@ impl AccountIdV0 { let prefix_bytes = bytes[0..8].try_into().expect("we should have sliced off exactly 8 bytes"); - let prefix = Felt::try_from(u64::from_be_bytes(prefix_bytes)) - .expect("should be a valid felt due to the most significant bit being zero"); + let prefix = Felt::from(u64::from_be_bytes(prefix_bytes)); let mut suffix_bytes = [0; 8]; // Overwrite first 7 bytes, leaving the 8th byte 0 (which will be cleared by @@ -130,8 +130,7 @@ impl AccountIdV0 { let mut suffix = Felt::new(u64::from_be_bytes(suffix_bytes)); // Clear the most significant bit of the suffix. - suffix = Felt::try_from(suffix.as_int() & 0x7fff_ffff_ffff_ffff) - .expect("no bits were set so felt should still be valid"); + suffix = Felt::from(suffix.as_int() & 0x7fff_ffff_ffff_ffff); suffix = shape_suffix(suffix); @@ -369,11 +368,34 @@ impl TryFrom<[u8; 15]> for AccountIdV0 { let mut suffix_bytes = [0; 8]; suffix_bytes[1..8].copy_from_slice(suffix_slice); - let prefix = Felt::try_from(prefix_slice) - .map_err(AccountIdError::AccountIdInvalidPrefixFieldElement)?; - - let suffix = Felt::try_from(suffix_bytes.as_slice()) - .map_err(AccountIdError::AccountIdInvalidSuffixFieldElement)?; + // Convert prefix bytes to u64 and validate + let prefix_array: [u8; 8] = prefix_slice.try_into().map_err(|_| { + AccountIdError::AccountIdInvalidPrefixFieldElement(DeserializationError::InvalidValue( + "Invalid prefix byte length".to_string(), + )) + })?; + let prefix_u64 = u64::from_le_bytes(prefix_array); + if prefix_u64 >= Felt::ORDER_U64 { + return Err(AccountIdError::AccountIdInvalidPrefixFieldElement( + DeserializationError::InvalidValue(format!( + "Prefix value {} outside field modulus", + prefix_u64 + )), + )); + } + let prefix = Felt::new(prefix_u64); + + // Convert suffix bytes to u64 and validate + let suffix_u64 = u64::from_le_bytes(suffix_bytes); + if suffix_u64 >= Felt::ORDER_U64 { + return Err(AccountIdError::AccountIdInvalidSuffixFieldElement( + DeserializationError::InvalidValue(format!( + "Suffix value {} outside field modulus", + suffix_u64 + )), + )); + } + let suffix = Felt::new(suffix_u64); Self::try_from([prefix, suffix]) } @@ -509,7 +531,7 @@ fn shape_suffix(suffix: Felt) -> Felt { suffix &= 0xffff_ffff_ffff_ff00; // SAFETY: Felt was previously valid and we only cleared bits, so it must still be valid. - Felt::try_from(suffix).expect("no bits were set so felt should still be valid") + Felt::from(suffix) } // COMMON TRAIT IMPLS @@ -562,8 +584,8 @@ mod tests { #[test] fn account_id_from_felts_with_max_pop_count() { - let valid_suffix = Felt::try_from(0x7fff_ffff_ffff_ff00u64).unwrap(); - let valid_prefix = Felt::try_from(0x7fff_ffff_ffff_ff70u64).unwrap(); + let valid_suffix = Felt::from(0x7fff_ffff_ffff_ff00u64); + let valid_prefix = Felt::from(0x7fff_ffff_ffff_ff70u64); let id1 = AccountIdV0::new_unchecked([valid_prefix, valid_suffix]); assert_eq!(id1.account_type(), AccountType::NonFungibleFaucet); diff --git a/crates/miden-protocol/src/account/account_id/v0/prefix.rs b/crates/miden-protocol/src/account/account_id/v0/prefix.rs index d2b0f6d116..8041368fcc 100644 --- a/crates/miden-protocol/src/account/account_id/v0/prefix.rs +++ b/crates/miden-protocol/src/account/account_id/v0/prefix.rs @@ -3,6 +3,7 @@ use core::fmt; use core::hash::Hash; use miden_core::Felt; +use miden_core::field::PrimeField64; use miden_core::utils::{ByteReader, ByteWriter, Deserializable, Serializable}; use miden_processor::DeserializationError; @@ -142,13 +143,21 @@ impl TryFrom<[u8; 8]> for AccountIdPrefixV0 { /// See [`TryFrom<[u8; 8]> for /// AccountIdPrefix`](crate::account::AccountIdPrefix#impl-TryFrom<%5Bu8;+8% /// 5D>-for-AccountIdPrefix) for details. - fn try_from(mut value: [u8; 8]) -> Result { - // Felt::try_from expects little-endian order. - value.reverse(); - - Felt::try_from(value.as_slice()) - .map_err(AccountIdError::AccountIdInvalidPrefixFieldElement) - .and_then(Self::new) + fn try_from(value: [u8; 8]) -> Result { + // Convert from big-endian bytes to u64 + // (serialization uses to_be_bytes, so deserialization must use from_be_bytes) + let value_u64 = u64::from_be_bytes(value); + // Validate that the value is within the field modulus + if value_u64 >= Felt::ORDER_U64 { + return Err(AccountIdError::AccountIdInvalidPrefixFieldElement( + DeserializationError::InvalidValue(format!( + "Value {} is outside field modulus", + value_u64 + )), + )); + } + let element = Felt::new(value_u64); + Self::new(element) } } @@ -159,8 +168,16 @@ impl TryFrom for AccountIdPrefixV0 { /// AccountIdPrefix`](crate::account::AccountIdPrefix#impl-TryFrom-for-AccountIdPrefix) /// for details. fn try_from(value: u64) -> Result { - let element = Felt::try_from(value.to_le_bytes().as_slice()) - .map_err(AccountIdError::AccountIdInvalidPrefixFieldElement)?; + // Validate that the value is within the field modulus + if value >= Felt::ORDER_U64 { + return Err(AccountIdError::AccountIdInvalidPrefixFieldElement( + DeserializationError::InvalidValue(format!( + "Value {} is outside field modulus", + value + )), + )); + } + let element = Felt::new(value); Self::new(element) } } diff --git a/crates/miden-protocol/src/account/builder/mod.rs b/crates/miden-protocol/src/account/builder/mod.rs index e02aac4152..f1b3aa411b 100644 --- a/crates/miden-protocol/src/account/builder/mod.rs +++ b/crates/miden-protocol/src/account/builder/mod.rs @@ -1,8 +1,6 @@ use alloc::boxed::Box; use alloc::vec::Vec; -use miden_core::FieldElement; - use crate::account::{ Account, AccountCode, @@ -15,14 +13,15 @@ use crate::account::{ AccountType, }; use crate::asset::AssetVault; -use crate::{AccountError, Felt, Word}; +#[allow(unused_imports)] // Used by public API methods that may not be called in all contexts +use crate::{AccountError, Felt, ONE, Word, ZERO}; /// A convenient builder for an [`Account`] allowing for safe construction of an account by /// combining multiple [`AccountComponent`]s. /// /// This will build a valid new account with these properties: /// - An empty [`AssetVault`]. -/// - The nonce set to [`Felt::ZERO`]. +/// - The nonce set to [`ZERO`]. /// - A seed which results in an [`AccountId`] valid for the configured account type and storage /// mode. /// @@ -225,8 +224,7 @@ impl AccountBuilder { // SAFETY: The account ID was derived from the seed and the seed is provided, so it is safe // to bypass the checks of `Account::new`. - let account = - Account::new_unchecked(account_id, vault, storage, code, Felt::ZERO, Some(seed)); + let account = Account::new_unchecked(account_id, vault, storage, code, ZERO, Some(seed)); Ok(account) } @@ -252,7 +250,7 @@ impl AccountBuilder { self } - /// Builds the account as an existing account, that is, with the nonce set to [`Felt::ONE`]. + /// Builds the account as an existing account, that is, with the nonce set to [`ONE`]. /// /// The [`AccountId`] is constructed by slightly modifying `init_seed[0..8]` to be a valid ID. /// @@ -271,8 +269,8 @@ impl AccountBuilder { ) }; - // Use the nonce value set by the Self::nonce method or Felt::ONE as a default. - let nonce = self.nonce.unwrap_or(Felt::ONE); + // Use the nonce value set by the Self::nonce method or ONE as a default. + let nonce = self.nonce.unwrap_or(ONE); Ok(Account::new_existing(account_id, vault, storage, code, nonce)) } @@ -281,13 +279,12 @@ impl AccountBuilder { // TESTS // ================================================================================================ -#[cfg(test)] +#[cfg(all(test, feature = "std"))] mod tests { use std::sync::LazyLock; use assert_matches::assert_matches; use miden_assembly::{Assembler, Library}; - use miden_core::FieldElement; use miden_processor::MastNodeExt; use super::*; @@ -386,7 +383,7 @@ mod tests { .unwrap(); // Account should be new, i.e. nonce = zero. - assert_eq!(account.nonce(), Felt::ZERO); + assert_eq!(account.nonce(), ZERO); let computed_id = AccountId::new( account.seed().unwrap(), diff --git a/crates/miden-protocol/src/account/component/storage/schema.rs b/crates/miden-protocol/src/account/component/storage/schema.rs index 9ae69f7b7a..9dff86646a 100644 --- a/crates/miden-protocol/src/account/component/storage/schema.rs +++ b/crates/miden-protocol/src/account/component/storage/schema.rs @@ -11,7 +11,7 @@ use super::{InitStorageData, StorageValueName, WordValue}; use crate::account::storage::is_reserved_slot_name; use crate::account::{StorageMap, StorageSlot, StorageSlotName}; use crate::errors::AccountComponentTemplateError; -use crate::{Felt, FieldElement, Word}; +use crate::{Felt, Word, ZERO}; // STORAGE SCHEMA // ================================================================================================ @@ -376,7 +376,7 @@ impl WordSchema { } }, WordSchema::Composite { value } => { - let mut result = [Felt::ZERO; 4]; + let mut result = [ZERO; 4]; for (index, felt_schema) in value.iter().enumerate() { result[index] = felt_schema.try_build_felt(init_storage_data, value_prefix.clone())?; @@ -622,7 +622,7 @@ impl FeltSchema { } if self.r#type == SchemaTypeId::void() { - return Ok(Felt::ZERO); + return Ok(ZERO); } if let Some(default_value) = self.default_value { @@ -900,7 +900,7 @@ pub(super) fn parse_word_value_with_schema( }, WordSchema::Composite { value } => match raw_value { WordValue::Elements(elements) => { - let mut felts = [Felt::ZERO; 4]; + let mut felts = [ZERO; 4]; for index in 0..4 { let felt_type = value[index].felt_type(); felts[index] = SCHEMA_TYPE_REGISTRY diff --git a/crates/miden-protocol/src/account/component/storage/toml/tests.rs b/crates/miden-protocol/src/account/component/storage/toml/tests.rs index 419992673e..8fc9d17a9a 100644 --- a/crates/miden-protocol/src/account/component/storage/toml/tests.rs +++ b/crates/miden-protocol/src/account/component/storage/toml/tests.rs @@ -1,8 +1,9 @@ use alloc::string::ToString; use core::error::Error; -use miden_core::{Felt, FieldElement, Word}; +use miden_core::{Felt, Word}; +use crate::ZERO; use crate::account::component::toml::init_storage_data::InitStorageDataError; use crate::account::component::{ AccountComponentMetadata, @@ -541,7 +542,7 @@ fn extensive_schema_metadata_and_init_toml_example() { }; let symbol_felt: Felt = TokenSymbol::new("TST").unwrap().into(); let expected_token_metadata = - Word::from([Felt::from(1_000_000u32), symbol_felt, Felt::from(6u8), Felt::ZERO]); + Word::from([Felt::from(1_000_000u32), symbol_felt, Felt::from(6u8), ZERO]); assert_eq!(token_metadata_word, &expected_token_metadata); let owner_pub_key_name = StorageSlotName::new("demo::owner_pub_key").unwrap(); @@ -558,10 +559,7 @@ fn extensive_schema_metadata_and_init_toml_example() { let StorageSlotContent::Value(protocol_version_word) = protocol_version_slot.content() else { panic!("expected value slot for protocol_version"); }; - assert_eq!( - protocol_version_word, - &Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::from(7u8)]) - ); + assert_eq!(protocol_version_word, &Word::from([ZERO, ZERO, ZERO, Felt::from(7u8)])); let static_word_name = StorageSlotName::new("demo::static_word").unwrap(); let static_word_slot = slots.iter().find(|s| s.name() == &static_word_name).unwrap(); @@ -588,8 +586,8 @@ fn extensive_schema_metadata_and_init_toml_example() { assert_eq!(static_map.num_entries(), 2); assert_eq!(static_map.get(&Word::parse("0x1").unwrap()), Word::parse("0x10").unwrap()); assert_eq!( - static_map.get(&Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(2)])), - Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(32)]) + static_map.get(&Word::from([ZERO, ZERO, ZERO, Felt::new(2)])), + Word::from([ZERO, ZERO, ZERO, Felt::new(32)]) ); let typed_map_new_slot = slots.iter().find(|s| s.name() == &typed_map_new_name).unwrap(); @@ -634,11 +632,8 @@ fn extensive_schema_metadata_and_init_toml_example() { }; assert_eq!(typed_map_new_contents.num_entries(), 2); - let key1 = Word::from([Felt::new(1), Felt::new(2), Felt::ZERO, Felt::ZERO]); - assert_eq!( - typed_map_new_contents.get(&key1), - Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(16)]) - ); + let key1 = Word::from([Felt::new(1), Felt::new(2), ZERO, ZERO]); + assert_eq!(typed_map_new_contents.get(&key1), Word::from([ZERO, ZERO, ZERO, Felt::new(16)])); let token_metadata_slot = slots_with_maps.iter().find(|s| s.name() == &token_metadata_name).unwrap(); @@ -647,7 +642,7 @@ fn extensive_schema_metadata_and_init_toml_example() { }; let symbol_felt: Felt = TokenSymbol::new("BTC").unwrap().into(); let expected_token_metadata_overridden = - Word::from([Felt::from(1_000_000u32), symbol_felt, Felt::from(6u8), Felt::ZERO]); + Word::from([Felt::from(1_000_000u32), symbol_felt, Felt::from(6u8), ZERO]); assert_eq!(token_metadata_word, &expected_token_metadata_overridden); let legacy_word_slot = slots_with_maps.iter().find(|s| s.name() == &legacy_word_name).unwrap(); @@ -663,8 +658,8 @@ fn extensive_schema_metadata_and_init_toml_example() { assert_eq!(static_map.num_entries(), 3); assert_eq!(static_map.get(&Word::parse("0x1").unwrap()), Word::parse("0x99").unwrap()); assert_eq!( - static_map.get(&Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(2)])), - Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(32)]) + static_map.get(&Word::from([ZERO, ZERO, ZERO, Felt::new(2)])), + Word::from([ZERO, ZERO, ZERO, Felt::new(32)]) ); assert_eq!(static_map.get(&Word::parse("0x3").unwrap()), Word::parse("0x30").unwrap()); } @@ -741,6 +736,6 @@ fn typed_map_supports_non_numeric_value_types() { let key = Word::parse("0x1").unwrap(); let symbol_felt: Felt = TokenSymbol::new("BTC").unwrap().into(); - let expected_value = Word::from([Felt::ZERO, Felt::ZERO, Felt::ZERO, symbol_felt]); + let expected_value = Word::from([ZERO, ZERO, ZERO, symbol_felt]); assert_eq!(map.get(&key), expected_value); } diff --git a/crates/miden-protocol/src/account/component/storage/type_registry.rs b/crates/miden-protocol/src/account/component/storage/type_registry.rs index 45512f5e95..b82bc617fa 100644 --- a/crates/miden-protocol/src/account/component/storage/type_registry.rs +++ b/crates/miden-protocol/src/account/component/storage/type_registry.rs @@ -5,7 +5,7 @@ use core::error::Error; use core::fmt::{self, Display}; use miden_core::utils::{ByteReader, ByteWriter, Deserializable, Serializable}; -use miden_core::{Felt, FieldElement, Word}; +use miden_core::{Felt, Word, ZERO}; use miden_crypto::dsa::{ecdsa_k256_keccak, falcon512_rpo}; use miden_processor::DeserializationError; use thiserror::Error; @@ -366,7 +366,7 @@ impl FeltType for Felt { .map_err(|err| { SchemaTypeError::parse(input.to_string(), ::type_name(), err) })?; - Felt::try_from(n).map_err(|_| SchemaTypeError::ConversionError(input.to_string())) + Ok(Felt::from(n)) } fn display_felt(value: Felt) -> Result { @@ -614,7 +614,7 @@ impl SchemaTypeRegistry { TypeKind::Word => Ok(()), TypeKind::Felt => { // Felt types stored as words must have the form [0, 0, 0, ] - if word[0] != Felt::ZERO || word[1] != Felt::ZERO || word[2] != Felt::ZERO { + if word[0] != ZERO || word[1] != ZERO || word[2] != ZERO { return Err(SchemaTypeError::ConversionError(format!( "expected a word of the form [0, 0, 0, ] for type `{type_name}`" ))); diff --git a/crates/miden-protocol/src/account/delta/mod.rs b/crates/miden-protocol/src/account/delta/mod.rs index 178f3a8020..c9cf2df3a7 100644 --- a/crates/miden-protocol/src/account/delta/mod.rs +++ b/crates/miden-protocol/src/account/delta/mod.rs @@ -586,8 +586,8 @@ fn validate_nonce( mod tests { use assert_matches::assert_matches; + use miden_core::Felt; use miden_core::utils::Serializable; - use miden_core::{Felt, FieldElement}; use super::{AccountDelta, AccountStorageDelta, AccountVaultDelta}; use crate::account::delta::AccountUpdateDetails; @@ -643,7 +643,7 @@ mod tests { let vault_delta = AccountVaultDelta::default(); let nonce_delta0 = ONE; - let nonce_delta1 = Felt::try_from(0xffff_ffff_0000_0000u64).unwrap(); + let nonce_delta1 = Felt::from(0xffff_ffff_0000_0000u64); let mut delta0 = AccountDelta::new(account_id, storage_delta.clone(), vault_delta.clone(), nonce_delta0) @@ -732,13 +732,8 @@ mod tests { let account_code = AccountCode::mock(); assert_eq!(account_code.to_bytes().len(), account_code.get_size_hint()); - let account = Account::new_existing( - account_id, - asset_vault, - account_storage, - account_code, - Felt::ONE, - ); + let account = + Account::new_existing(account_id, asset_vault, account_storage, account_code, ONE); assert_eq!(account.to_bytes().len(), account.get_size_hint()); // AccountUpdateDetails diff --git a/crates/miden-protocol/src/account/delta/storage.rs b/crates/miden-protocol/src/account/delta/storage.rs index c8f9a852de..0af4f972f9 100644 --- a/crates/miden-protocol/src/account/delta/storage.rs +++ b/crates/miden-protocol/src/account/delta/storage.rs @@ -2,6 +2,8 @@ use alloc::collections::BTreeMap; use alloc::collections::btree_map::Entry; use alloc::vec::Vec; +use miden_core::field::PrimeField64; + use super::{ AccountDeltaError, ByteReader, @@ -194,9 +196,12 @@ impl AccountStorageDelta { elements.extend_from_slice(value.as_elements()); } - let num_changed_entries = Felt::try_from(map_delta.num_entries()).expect( - "number of changed entries should not exceed max representable felt", + let num_entries = map_delta.num_entries() as u64; + assert!( + num_entries < Felt::ORDER_U64, + "number of changed entries should not exceed max representable felt" ); + let num_changed_entries = Felt::new(num_entries); elements.extend_from_slice(&[ DOMAIN_MAP, diff --git a/crates/miden-protocol/src/account/file.rs b/crates/miden-protocol/src/account/file.rs index 4b6f5d4287..d2b9ca95d5 100644 --- a/crates/miden-protocol/src/account/file.rs +++ b/crates/miden-protocol/src/account/file.rs @@ -99,17 +99,19 @@ impl Deserializable for AccountFile { #[cfg(test)] mod tests { - use miden_crypto::utils::{Deserializable, Serializable}; - use storage::AccountStorage; #[cfg(feature = "std")] - use tempfile::tempdir; - - use super::AccountFile; - use crate::account::auth::AuthSecretKey; - use crate::account::{Account, AccountCode, AccountId, Felt, storage}; - use crate::asset::AssetVault; - use crate::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE; + use { + super::AccountFile, + crate::account::auth::AuthSecretKey, + crate::account::{Account, AccountCode, AccountId, Felt, storage}, + crate::asset::AssetVault, + crate::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE, + miden_crypto::utils::{Deserializable, Serializable}, + storage::AccountStorage, + tempfile::tempdir, + }; + #[cfg(feature = "std")] fn build_account_file() -> AccountFile { let id = AccountId::try_from(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE).unwrap(); let code = AccountCode::mock(); @@ -125,6 +127,7 @@ mod tests { AccountFile::new(account, vec![auth_secret_key, auth_secret_key_2]) } + #[cfg(feature = "std")] #[test] fn test_serde() { let account_file = build_account_file(); diff --git a/crates/miden-protocol/src/account/mod.rs b/crates/miden-protocol/src/account/mod.rs index 7f94221a46..f099bce23f 100644 --- a/crates/miden-protocol/src/account/mod.rs +++ b/crates/miden-protocol/src/account/mod.rs @@ -580,7 +580,6 @@ mod tests { use assert_matches::assert_matches; use miden_assembly::Assembler; - use miden_core::FieldElement; use miden_crypto::utils::{Deserializable, Serializable}; use miden_crypto::{Felt, Word}; @@ -592,7 +591,6 @@ mod tests { AccountStorageDelta, AccountVaultDelta, }; - use crate::AccountError; use crate::account::AccountStorageMode::Network; use crate::account::{ Account, @@ -614,6 +612,7 @@ mod tests { }; use crate::testing::add_component::AddComponent; use crate::testing::noop_auth_component::NoopAuthComponent; + use crate::{AccountError, ONE, ZERO}; #[test] fn test_serde_account() { @@ -873,26 +872,20 @@ mod tests { )?; // Set nonce to 1 so the account is considered existing and provide the seed. - let err = Account::new(id, vault.clone(), storage.clone(), code.clone(), Felt::ONE, seed) - .unwrap_err(); + let err = + Account::new(id, vault.clone(), storage.clone(), code.clone(), ONE, seed).unwrap_err(); assert_matches!(err, AccountError::ExistingAccountWithSeed); // Set nonce to 0 so the account is considered new but don't provide the seed. - let err = Account::new(id, vault.clone(), storage.clone(), code.clone(), Felt::ZERO, None) - .unwrap_err(); + let err = + Account::new(id, vault.clone(), storage.clone(), code.clone(), ZERO, None).unwrap_err(); assert_matches!(err, AccountError::NewAccountMissingSeed); // Set nonce to 0 so the account is considered new and provide a valid seed that results in // a different ID than the provided one. - let err = Account::new( - id, - vault.clone(), - storage.clone(), - code.clone(), - Felt::ZERO, - Some(other_seed), - ) - .unwrap_err(); + let err = + Account::new(id, vault.clone(), storage.clone(), code.clone(), ZERO, Some(other_seed)) + .unwrap_err(); assert_matches!(err, AccountError::AccountIdSeedMismatch { .. }); // Set nonce to 0 so the account is considered new and provide a seed that results in an @@ -902,7 +895,7 @@ mod tests { vault.clone(), storage.clone(), code.clone(), - Felt::ZERO, + ZERO, Some(Word::from([1, 2, 3, 4u32])), ) .unwrap_err(); @@ -910,11 +903,11 @@ mod tests { // Set nonce to 1 so the account is considered existing and don't provide the seed, which // should be valid. - Account::new(id, vault.clone(), storage.clone(), code.clone(), Felt::ONE, None)?; + Account::new(id, vault.clone(), storage.clone(), code.clone(), ONE, None)?; // Set nonce to 0 so the account is considered new and provide the original seed, which // should be valid. - Account::new(id, vault.clone(), storage.clone(), code.clone(), Felt::ZERO, seed)?; + Account::new(id, vault.clone(), storage.clone(), code.clone(), ZERO, seed)?; Ok(()) } @@ -925,7 +918,7 @@ mod tests { .with_auth_component(NoopAuthComponent) .with_component(AddComponent) .build()?; - account.increment_nonce(Felt::ONE)?; + account.increment_nonce(ONE)?; assert_matches!(account.seed(), None); diff --git a/crates/miden-protocol/src/account/storage/header.rs b/crates/miden-protocol/src/account/storage/header.rs index 8f48bfe646..6a7ca776f0 100644 --- a/crates/miden-protocol/src/account/storage/header.rs +++ b/crates/miden-protocol/src/account/storage/header.rs @@ -12,7 +12,7 @@ use crate::utils::serde::{ DeserializationError, Serializable, }; -use crate::{AccountError, FieldElement, ZERO}; +use crate::{AccountError, ZERO}; // ACCOUNT STORAGE HEADER // ================================================================================================ @@ -259,12 +259,7 @@ impl StorageSlotHeader { pub(crate) fn to_elements(&self) -> [Felt; StorageSlot::NUM_ELEMENTS] { let id = self.id(); let mut elements = [ZERO; StorageSlot::NUM_ELEMENTS]; - elements[0..4].copy_from_slice(&[ - Felt::ZERO, - self.r#type.as_felt(), - id.suffix(), - id.prefix(), - ]); + elements[0..4].copy_from_slice(&[ZERO, self.r#type.as_felt(), id.suffix(), id.prefix()]); elements[4..8].copy_from_slice(self.value.as_elements()); elements } diff --git a/crates/miden-protocol/src/account/storage/map/mod.rs b/crates/miden-protocol/src/account/storage/map/mod.rs index 2882496190..648615978b 100644 --- a/crates/miden-protocol/src/account/storage/map/mod.rs +++ b/crates/miden-protocol/src/account/storage/map/mod.rs @@ -160,7 +160,7 @@ impl StorageMap { /// Returns an iterator over the key-value pairs in this storage map. /// /// Note that the returned key is the raw map key. - pub fn entries(&self) -> impl Iterator { + pub fn entries(&self) -> impl Iterator + '_ { self.entries.iter() } @@ -193,7 +193,7 @@ impl StorageMap { pub fn apply_delta(&mut self, delta: &StorageMapDelta) -> Result { // apply the updated and cleared leaves to the storage map for (&key, &value) in delta.entries().iter() { - self.insert(key.into_inner(), value)?; + self.insert(*key.inner(), value)?; } Ok(self.root()) diff --git a/crates/miden-protocol/src/account/storage/slot/slot_name.rs b/crates/miden-protocol/src/account/storage/slot/slot_name.rs index 27d0c7ce45..bb660687ee 100644 --- a/crates/miden-protocol/src/account/storage/slot/slot_name.rs +++ b/crates/miden-protocol/src/account/storage/slot/slot_name.rs @@ -245,7 +245,7 @@ impl Deserializable for StorageSlotName { // TESTS // ================================================================================================ -#[cfg(test)] +#[cfg(all(test, feature = "std"))] mod tests { use std::borrow::ToOwned; diff --git a/crates/miden-protocol/src/asset/nonfungible.rs b/crates/miden-protocol/src/asset/nonfungible.rs index d48b26602b..2e7f816827 100644 --- a/crates/miden-protocol/src/asset/nonfungible.rs +++ b/crates/miden-protocol/src/asset/nonfungible.rs @@ -6,11 +6,14 @@ use core::fmt; use super::vault::AssetVaultKey; use super::{AccountIdPrefix, AccountType, Asset, AssetError, Felt, Hasher, Word}; use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; -use crate::{FieldElement, WORD_SIZE}; +use crate::{WORD_SIZE, ZERO}; /// Position of the faucet_id inside the [`NonFungibleAsset`] word having fields in BigEndian. const FAUCET_ID_POS_BE: usize = 3; +/// Number of bytes in a Felt (Goldilocks is 64-bit = 8 bytes) +const FELT_NUM_BYTES: usize = 8; + // NON-FUNGIBLE ASSET // ================================================================================================ @@ -48,7 +51,7 @@ impl NonFungibleAsset { /// The serialized size of a [`NonFungibleAsset`] in bytes. /// /// Currently represented as a word. - pub const SERIALIZED_SIZE: usize = Felt::ELEMENT_BYTES * WORD_SIZE; + pub const SERIALIZED_SIZE: usize = FELT_NUM_BYTES * WORD_SIZE; // CONSTRUCTORS // -------------------------------------------------------------------------------------------- @@ -214,11 +217,8 @@ impl NonFungibleAsset { // The last felt in the data_hash will be replaced by the faucet id, so we can set it to // zero here. - NonFungibleAsset::from_parts( - faucet_id_prefix, - Word::from([hash_0, hash_1, hash_2, Felt::ZERO]), - ) - .map_err(|err| DeserializationError::InvalidValue(err.to_string())) + NonFungibleAsset::from_parts(faucet_id_prefix, Word::from([hash_0, hash_1, hash_2, ZERO])) + .map_err(|err| DeserializationError::InvalidValue(err.to_string())) } } diff --git a/crates/miden-protocol/src/batch/proposed_batch.rs b/crates/miden-protocol/src/batch/proposed_batch.rs index 5d5cb0f97b..699c227f91 100644 --- a/crates/miden-protocol/src/batch/proposed_batch.rs +++ b/crates/miden-protocol/src/batch/proposed_batch.rs @@ -425,9 +425,10 @@ impl Deserializable for ProposedBatch { #[cfg(test)] mod tests { use anyhow::Context; + use miden_air::HashFunction; use miden_crypto::merkle::mmr::{Mmr, PartialMmr}; + use miden_test_utils::rand::rand_value; use miden_verifier::ExecutionProof; - use winter_rand_utils::rand_value; use super::*; use crate::Word; @@ -472,7 +473,7 @@ mod tests { let block_num = reference_block_header.block_num(); let block_ref = reference_block_header.commitment(); let expiration_block_num = reference_block_header.block_num() + 1; - let proof = ExecutionProof::new_dummy(); + let proof = ExecutionProof::new(Vec::new(), HashFunction::Blake3_256, Vec::new()); let tx = ProvenTransactionBuilder::new( account_id, diff --git a/crates/miden-protocol/src/block/account_tree/backend.rs b/crates/miden-protocol/src/block/account_tree/backend.rs index 78dc989786..8d0fe61bb8 100644 --- a/crates/miden-protocol/src/block/account_tree/backend.rs +++ b/crates/miden-protocol/src/block/account_tree/backend.rs @@ -129,9 +129,8 @@ where type Error = MerkleError; fn num_leaves(&self) -> usize { - // LargeSmt::num_leaves returns Result - // We'll unwrap or return 0 on error - LargeSmt::num_leaves(self).map_err(large_smt_error_to_merkle_error).unwrap_or(0) + // LargeSmt::num_leaves now returns usize directly + LargeSmt::num_leaves(self) } fn leaves<'a>(&'a self) -> Box, SmtLeaf)>> { @@ -215,9 +214,7 @@ impl AccountTree { // SAFETY: Since we only inserted account IDs into the SMT, it is guaranteed that // the leaf_idx is a valid Felt as well as a valid account ID prefix. AccountTreeError::DuplicateStateCommitments { - prefix: AccountIdPrefix::new_unchecked( - crate::Felt::try_from(leaf_idx).expect("leaf index should be a valid felt"), - ), + prefix: AccountIdPrefix::new_unchecked(crate::Felt::from(leaf_idx)), } })?; @@ -235,5 +232,11 @@ fn large_smt_error_to_merkle_error(err: LargeSmtError) -> MerkleError { panic!("Storage error encountered: {:?}", storage_err) }, LargeSmtError::Merkle(merkle_err) => merkle_err, + LargeSmtError::RootMismatch { .. } => { + panic!("Root mismatch error encountered: {:?}", err) + }, + LargeSmtError::StorageNotEmpty => { + panic!("Storage not empty error encountered") + }, } } diff --git a/crates/miden-protocol/src/block/account_tree/mod.rs b/crates/miden-protocol/src/block/account_tree/mod.rs index f48ce04425..f573d36678 100644 --- a/crates/miden-protocol/src/block/account_tree/mod.rs +++ b/crates/miden-protocol/src/block/account_tree/mod.rs @@ -415,7 +415,7 @@ impl AccountMutationSet { // TESTS // ================================================================================================ -#[cfg(test)] +#[cfg(all(test, feature = "std"))] pub(super) mod tests { use std::vec::Vec; diff --git a/crates/miden-protocol/src/block/account_tree/partial.rs b/crates/miden-protocol/src/block/account_tree/partial.rs index af84f725ae..5a1b4bba75 100644 --- a/crates/miden-protocol/src/block/account_tree/partial.rs +++ b/crates/miden-protocol/src/block/account_tree/partial.rs @@ -187,7 +187,7 @@ impl PartialAccountTree { } } -#[cfg(test)] +#[cfg(all(test, feature = "std"))] mod tests { use assert_matches::assert_matches; use miden_crypto::merkle::smt::Smt; @@ -254,7 +254,12 @@ mod tests { #[test] fn upsert_state_commitments_fails_on_untracked_key() { - let mut partial_tree = PartialAccountTree::default(); + // Create a non-empty partial tree with a specific root. We use a non-empty root because + // PartialSmt treats all keys as implicitly tracked in an empty tree (since all leaves + // are provably empty via the empty subtree root). + use crate::Felt; + let non_empty_root = Word::from([Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)]); + let mut partial_tree = PartialAccountTree::new(non_empty_root); let [update, _] = setup_duplicate_prefix_ids(); let err = partial_tree.upsert_state_commitments([update]).unwrap_err(); diff --git a/crates/miden-protocol/src/block/blockchain.rs b/crates/miden-protocol/src/block/blockchain.rs index a70159fbd0..7169944bfb 100644 --- a/crates/miden-protocol/src/block/blockchain.rs +++ b/crates/miden-protocol/src/block/blockchain.rs @@ -140,13 +140,14 @@ impl Blockchain { let mut partial_mmr = PartialMmr::from_peaks(peaks); for block_num in blocks.iter() { let leaf = self.mmr.get(block_num.as_usize())?; - let path = self.open_at(*block_num, checkpoint)?.merkle_path; + let proof = self.open_at(*block_num, checkpoint)?; + let path = proof.merkle_path(); // SAFETY: We should be able to fill the partial MMR with data from the partial // blockchain without errors, otherwise it indicates the blockchain is // invalid. partial_mmr - .track(block_num.as_usize(), leaf, &path) + .track(block_num.as_usize(), leaf, path) .expect("filling partial mmr with data from mmr should succeed"); } diff --git a/crates/miden-protocol/src/block/header.rs b/crates/miden-protocol/src/block/header.rs index fec485c164..480abb839b 100644 --- a/crates/miden-protocol/src/block/header.rs +++ b/crates/miden-protocol/src/block/header.rs @@ -399,7 +399,7 @@ impl Deserializable for FeeParameters { mod tests { use assert_matches::assert_matches; use miden_core::Word; - use winter_rand_utils::rand_value; + use miden_test_utils::rand::rand_value; use super::*; use crate::testing::account_id::ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET; diff --git a/crates/miden-protocol/src/block/nullifier_tree/backend.rs b/crates/miden-protocol/src/block/nullifier_tree/backend.rs index 603258ea0a..7b3716008e 100644 --- a/crates/miden-protocol/src/block/nullifier_tree/backend.rs +++ b/crates/miden-protocol/src/block/nullifier_tree/backend.rs @@ -114,12 +114,8 @@ where type Error = MerkleError; fn num_entries(&self) -> usize { - // SAFETY: We panic on storage errors here as they represent unrecoverable I/O failures. - // This maintains API compatibility with the non-fallible Smt::num_entries(). - // See issue #2010 for future improvements to error handling. + // LargeSmt::num_entries now returns usize directly LargeSmt::num_entries(self) - .map_err(large_smt_error_to_merkle_error) - .expect("Storage I/O error accessing num_entries") } fn entries(&self) -> Box + '_> { @@ -231,5 +227,11 @@ pub(super) fn large_smt_error_to_merkle_error(err: LargeSmtError) -> MerkleError panic!("Storage error encountered: {:?}", storage_err) }, LargeSmtError::Merkle(merkle_err) => merkle_err, + LargeSmtError::RootMismatch { .. } => { + panic!("Root mismatch error encountered: {:?}", err) + }, + LargeSmtError::StorageNotEmpty => { + panic!("Storage not empty error encountered") + }, } } diff --git a/crates/miden-protocol/src/block/nullifier_tree/mod.rs b/crates/miden-protocol/src/block/nullifier_tree/mod.rs index 812e3906c2..bd1431b24f 100644 --- a/crates/miden-protocol/src/block/nullifier_tree/mod.rs +++ b/crates/miden-protocol/src/block/nullifier_tree/mod.rs @@ -7,7 +7,7 @@ use crate::crypto::merkle::smt::{MutationSet, SMT_DEPTH, Smt}; use crate::errors::NullifierTreeError; use crate::note::Nullifier; use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; -use crate::{Felt, FieldElement, Word}; +use crate::{Felt, Word, ZERO}; mod backend; pub use backend::NullifierTreeBackend; @@ -277,7 +277,7 @@ impl NullifierBlock { .map(BlockNumber::from) .map_err(|_| NullifierTreeError::InvalidNullifierBlockNumber(word))?; - if word[1..4].iter().any(|felt| *felt != Felt::ZERO) { + if word[1..4].iter().any(|felt| *felt != ZERO) { return Err(NullifierTreeError::InvalidNullifierBlockNumber(word)); } @@ -309,7 +309,7 @@ impl From for BlockNumber { impl From for Word { fn from(value: NullifierBlock) -> Word { - Word::from([Felt::from(value.0), Felt::ZERO, Felt::ZERO, Felt::ZERO]) + Word::from([Felt::from(value.0), ZERO, ZERO, ZERO]) } } diff --git a/crates/miden-protocol/src/block/nullifier_tree/partial.rs b/crates/miden-protocol/src/block/nullifier_tree/partial.rs index 0bcb90c80d..89883e1fe8 100644 --- a/crates/miden-protocol/src/block/nullifier_tree/partial.rs +++ b/crates/miden-protocol/src/block/nullifier_tree/partial.rs @@ -111,7 +111,7 @@ impl PartialNullifierTree { mod tests { use assert_matches::assert_matches; use miden_crypto::merkle::smt::Smt; - use winter_rand_utils::rand_value; + use miden_test_utils::rand::rand_value; use super::*; use crate::block::nullifier_tree::NullifierTree; diff --git a/crates/miden-protocol/src/lib.rs b/crates/miden-protocol/src/lib.rs index c84363f82a..d11753c77a 100644 --- a/crates/miden-protocol/src/lib.rs +++ b/crates/miden-protocol/src/lib.rs @@ -56,7 +56,7 @@ pub use errors::{ }; pub use miden_core::mast::{MastForest, MastNodeId}; pub use miden_core::prettier::PrettyPrint; -pub use miden_core::{EMPTY_WORD, Felt, FieldElement, ONE, StarkField, WORD_SIZE, ZERO}; +pub use miden_core::{EMPTY_WORD, Felt, ONE, WORD_SIZE, ZERO}; pub use miden_core_lib::CoreLibrary; pub use miden_crypto::hash::rpo::Rpo256 as Hasher; pub use miden_crypto::word; diff --git a/crates/miden-protocol/src/note/metadata.rs b/crates/miden-protocol/src/note/metadata.rs index 31cdd14bcd..6558ae2fdc 100644 --- a/crates/miden-protocol/src/note/metadata.rs +++ b/crates/miden-protocol/src/note/metadata.rs @@ -221,7 +221,7 @@ fn merge_id_type_and_hint_tag( // SAFETY: The most significant bit of the suffix is zero by construction so the bytes will be a // valid felt. - Felt::try_from(merged).expect("encoded value should be a valid felt") + Felt::from(merged) } /// Unmerges the given felt into the suffix of an [`AccountId`], a [`NoteType`] and the tag of @@ -241,7 +241,7 @@ fn unmerge_id_type_and_hint_tag(element: Felt) -> Result<(Felt, NoteType, u8), N // SAFETY: The input was a valid felt and we cleared additional bits and did not set any // bits, so it must still be a valid felt. - let sender_id_suffix = Felt::try_from(element).expect("element should still be valid"); + let sender_id_suffix = Felt::from(element); Ok((sender_id_suffix, note_type, tag_bits)) } @@ -272,7 +272,7 @@ fn merge_note_tag_and_hint_payload( // SAFETY: The payload is guaranteed to never be u32::MAX so at least one of the upper 32 bits // is zero, hence the felt is valid even if note_tag is u32::MAX. - Felt::try_from(felt_int).expect("bytes should be a valid felt") + Felt::from(felt_int) } /// Unmerges the given felt into a [`NoteExecutionHint`] payload and a [`NoteTag`] and constructs a @@ -310,7 +310,7 @@ mod tests { let sender = AccountId::try_from(ACCOUNT_ID_MAX_ONES).unwrap(); let note_type = NoteType::Public; let tag = NoteTag::from_account_id(sender); - let aux = Felt::try_from(0xffff_ffff_0000_0000u64).unwrap(); + let aux = Felt::from(0xffff_ffff_0000_0000u64); for execution_hint in [ NoteExecutionHint::always(), diff --git a/crates/miden-protocol/src/note/nullifier.rs b/crates/miden-protocol/src/note/nullifier.rs index 26377caa8a..f7f92a2fcf 100644 --- a/crates/miden-protocol/src/note/nullifier.rs +++ b/crates/miden-protocol/src/note/nullifier.rs @@ -78,9 +78,7 @@ impl Nullifier { #[cfg(any(feature = "testing", test))] pub fn dummy(n: u64) -> Self { - use miden_core::FieldElement; - - Self(Word::new([Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::new(n)])) + Self(Word::new([ZERO, ZERO, ZERO, Felt::new(n)])) } } diff --git a/crates/miden-protocol/src/note/script.rs b/crates/miden-protocol/src/note/script.rs index 457d72cfb5..12eec0ddb1 100644 --- a/crates/miden-protocol/src/note/script.rs +++ b/crates/miden-protocol/src/note/script.rs @@ -2,6 +2,7 @@ use alloc::sync::Arc; use alloc::vec::Vec; use core::fmt::Display; +use miden_core::field::PrimeField64; use miden_processor::MastNodeExt; use super::Felt; @@ -134,12 +135,21 @@ impl TryFrom<&[Felt]> for NoteScript { return Err(DeserializationError::UnexpectedEOF); } - let entrypoint: u32 = elements[0].try_into().map_err(DeserializationError::InvalidValue)?; - let len = elements[1].as_int(); + let entrypoint_u64 = elements[0].as_canonical_u64(); + let entrypoint: u32 = entrypoint_u64.try_into().map_err(|_| { + DeserializationError::InvalidValue(format!( + "Entrypoint value {} doesn't fit in u32", + entrypoint_u64 + )) + })?; + let len = elements[1].as_canonical_u64(); let mut data = Vec::with_capacity(elements.len() * 4); for &felt in &elements[2..] { - let v: u32 = felt.try_into().map_err(DeserializationError::InvalidValue)?; + let felt_u64 = felt.as_canonical_u64(); + let v: u32 = felt_u64.try_into().map_err(|_| { + DeserializationError::InvalidValue(format!("Value {} doesn't fit in u32", felt_u64)) + })?; data.extend(v.to_le_bytes()) } data.shrink_to(len as usize); diff --git a/crates/miden-protocol/src/testing/block.rs b/crates/miden-protocol/src/testing/block.rs index 3ef1a2c624..41e8389f69 100644 --- a/crates/miden-protocol/src/testing/block.rs +++ b/crates/miden-protocol/src/testing/block.rs @@ -1,6 +1,6 @@ use miden_crypto::merkle::smt::Smt; #[cfg(not(target_family = "wasm"))] -use winter_rand_utils::rand_value; +use miden_test_utils::rand::rand_value; use crate::Word; use crate::account::Account; diff --git a/crates/miden-protocol/src/transaction/kernel/advice_inputs.rs b/crates/miden-protocol/src/transaction/kernel/advice_inputs.rs index c536f6e188..d0a2ce31a9 100644 --- a/crates/miden-protocol/src/transaction/kernel/advice_inputs.rs +++ b/crates/miden-protocol/src/transaction/kernel/advice_inputs.rs @@ -16,7 +16,7 @@ use crate::transaction::{ TransactionKernel, }; use crate::vm::AdviceInputs; -use crate::{EMPTY_WORD, Felt, FieldElement, Word, ZERO}; +use crate::{EMPTY_WORD, Felt, ONE, Word, ZERO}; // TRANSACTION ADVICE INPUTS // ================================================================================================ @@ -358,7 +358,7 @@ impl TransactionAdviceInputs { match input_note { InputNote::Authenticated { note, proof } => { // Push the `is_authenticated` flag - note_data.push(Felt::ONE); + note_data.push(ONE); // Merkle path self.extend_merkle_store(proof.authenticated_nodes(note.commitment())); @@ -380,7 +380,7 @@ impl TransactionAdviceInputs { }, InputNote::Unauthenticated { .. } => { // push the `is_authenticated` flag - note_data.push(Felt::ZERO) + note_data.push(ZERO) }, } } diff --git a/crates/miden-protocol/src/transaction/partial_blockchain.rs b/crates/miden-protocol/src/transaction/partial_blockchain.rs index 0d63027fe8..ff6ac123b9 100644 --- a/crates/miden-protocol/src/transaction/partial_blockchain.rs +++ b/crates/miden-protocol/src/transaction/partial_blockchain.rs @@ -5,7 +5,7 @@ use core::ops::RangeTo; use crate::PartialBlockchainError; use crate::block::{BlockHeader, BlockNumber}; use crate::crypto::merkle::InnerNodeInfo; -use crate::crypto::merkle::mmr::{MmrPeaks, PartialMmr}; +use crate::crypto::merkle::mmr::{MmrPeaks, MmrProof, PartialMmr}; use crate::utils::serde::{Deserializable, Serializable}; // PARTIAL BLOCKCHAIN @@ -67,12 +67,14 @@ impl PartialBlockchain { for (block_num, block) in partial_chain.blocks.iter() { // SAFETY: new_unchecked returns an error if a block is not tracked in the MMR, so // retrieving a proof here should succeed. - let proof = partial_chain + let path = partial_chain .mmr .open(block_num.as_usize()) .expect("block should not exceed chain length") .expect("block should be tracked in the partial MMR"); + let proof = MmrProof::new(path, block.commitment()); + partial_chain.mmr.peaks().verify(block.commitment(), proof).map_err(|source| { PartialBlockchainError::BlockHeaderCommitmentMismatch { block_num: *block_num, @@ -307,8 +309,8 @@ mod tests { partial_blockchain.add_block(&block_header, true); assert_eq!( - mmr.open(block_num as usize).unwrap(), - partial_blockchain.mmr.open(block_num as usize).unwrap().unwrap() + mmr.open(block_num as usize).unwrap().merkle_path(), + partial_blockchain.mmr.open(block_num as usize).unwrap().unwrap().merkle_path() ); // add one more block to the partial blockchain, the number of peaks is again 2 @@ -318,8 +320,8 @@ mod tests { partial_blockchain.add_block(&block_header, true); assert_eq!( - mmr.open(block_num as usize).unwrap(), - partial_blockchain.mmr.open(block_num as usize).unwrap().unwrap() + mmr.open(block_num as usize).unwrap().merkle_path(), + partial_blockchain.mmr.open(block_num as usize).unwrap().unwrap().merkle_path() ); // add one more block to the partial blockchain, the number of peaks is still 2 @@ -329,8 +331,8 @@ mod tests { partial_blockchain.add_block(&block_header, true); assert_eq!( - mmr.open(block_num as usize).unwrap(), - partial_blockchain.mmr.open(block_num as usize).unwrap().unwrap() + mmr.open(block_num as usize).unwrap().merkle_path(), + partial_blockchain.mmr.open(block_num as usize).unwrap().unwrap().merkle_path() ); } @@ -348,7 +350,7 @@ mod tests { let mut partial_mmr = PartialMmr::from_peaks(mmr.peaks()); for i in 0..3 { partial_mmr - .track(i, mmr.get(i).unwrap(), &mmr.open(i).unwrap().merkle_path) + .track(i, mmr.get(i).unwrap(), mmr.open(i).unwrap().merkle_path()) .unwrap(); } @@ -398,7 +400,7 @@ mod tests { let mut partial_mmr = PartialMmr::from_peaks(mmr.peaks()); partial_mmr - .track(1, block_header1.commitment(), &mmr.open(1).unwrap().merkle_path) + .track(1, block_header1.commitment(), mmr.open(1).unwrap().merkle_path()) .unwrap(); let error = @@ -465,7 +467,7 @@ mod tests { for i in 0..total_blocks { let i: usize = i as usize; partial_mmr - .track(i, full_mmr.get(i).unwrap(), &full_mmr.open(i).unwrap().merkle_path) + .track(i, full_mmr.get(i).unwrap(), full_mmr.open(i).unwrap().merkle_path()) .unwrap(); } let mut chain = PartialBlockchain::new(partial_mmr, headers).unwrap(); diff --git a/crates/miden-protocol/src/transaction/proven_tx.rs b/crates/miden-protocol/src/transaction/proven_tx.rs index 0e25ba6e5d..a864a26f40 100644 --- a/crates/miden-protocol/src/transaction/proven_tx.rs +++ b/crates/miden-protocol/src/transaction/proven_tx.rs @@ -683,11 +683,13 @@ impl Deserializable for InputNoteCommitment { #[cfg(test)] mod tests { use alloc::collections::BTreeMap; + use alloc::vec::Vec; use anyhow::Context; + use miden_air::HashFunction; use miden_core::utils::Deserializable; + use miden_test_utils::rand::rand_value; use miden_verifier::ExecutionProof; - use winter_rand_utils::rand_value; use super::ProvenTransaction; use crate::account::delta::AccountUpdateDetails; @@ -815,7 +817,7 @@ mod tests { let ref_block_num = BlockNumber::from(1); let ref_block_commitment = Word::empty(); let expiration_block_num = BlockNumber::from(2); - let proof = ExecutionProof::new_dummy(); + let proof = ExecutionProof::new(Vec::new(), HashFunction::Blake3_256, Vec::new()); let tx = ProvenTransactionBuilder::new( account_id, diff --git a/crates/miden-protocol/src/transaction/tx_args.rs b/crates/miden-protocol/src/transaction/tx_args.rs index 598ce1b94b..29a475e58c 100644 --- a/crates/miden-protocol/src/transaction/tx_args.rs +++ b/crates/miden-protocol/src/transaction/tx_args.rs @@ -345,8 +345,10 @@ impl Deserializable for TransactionScript { } } -#[cfg(test)] +#[cfg(all(test, feature = "std"))] mod tests { + use alloc::vec::Vec; + use miden_core::AdviceMap; use miden_core::utils::{Deserializable, Serializable}; @@ -355,7 +357,7 @@ mod tests { #[test] fn test_tx_args_serialization() { let tx_args = TransactionArgs::new(AdviceMap::default()); - let bytes: std::vec::Vec = tx_args.to_bytes(); + let bytes: Vec = tx_args.to_bytes(); let decoded = TransactionArgs::read_from_bytes(&bytes).unwrap(); assert_eq!(tx_args, decoded); diff --git a/crates/miden-protocol/tests/test_accountid_prefix_endianness.rs b/crates/miden-protocol/tests/test_accountid_prefix_endianness.rs new file mode 100644 index 0000000000..10b45bec9b --- /dev/null +++ b/crates/miden-protocol/tests/test_accountid_prefix_endianness.rs @@ -0,0 +1,67 @@ +//! Test to verify AccountIdPrefix serialization endianness consistency + +use miden_protocol::account::AccountIdPrefix; +use miden_protocol::utils::serde::{Deserializable, Serializable}; + +#[test] +fn test_accountid_prefix_endianness_roundtrip() { + // Create a test AccountIdPrefix from known bytes + let bytes: [u8; 8] = [170, 0, 0, 0, 0, 0, 188, 32]; + + println!("Original bytes: {:?}", bytes); + + // Deserialize + let prefix = match AccountIdPrefix::read_from_bytes(&bytes) { + Ok(p) => { + println!("✓ Deserialization succeeded: {:?}", p); + p + }, + Err(e) => { + println!("✗ Deserialization failed: {:?}", e); + panic!("Failed to deserialize AccountIdPrefix"); + }, + }; + + // Serialize back + let serialized = prefix.to_bytes(); + println!("Serialized bytes: {:?}", serialized); + + // Verify roundtrip + assert_eq!( + bytes, + serialized.as_slice(), + "Roundtrip failed: serialized bytes don't match original" + ); +} + +#[test] +fn test_accountid_prefix_version_extraction() { + // Test that version byte is extracted correctly from various prefixes + let test_cases = vec![ + ([170, 0, 0, 0, 0, 0, 188, 32], "Faucet ID"), + ([188, 0, 0, 0, 0, 0, 202, 48], "Non-fungible faucet"), + ]; + + for (bytes, description) in test_cases { + println!("\nTesting {}: {:?}", description, bytes); + + match AccountIdPrefix::read_from_bytes(&bytes) { + Ok(prefix) => { + let version = prefix.version(); + println!("✓ Version extracted: {:?}", version); + + // Version should always be 0 for V0 + assert_eq!( + format!("{:?}", version), + "Version0", + "Expected Version0 for {}", + description + ); + }, + Err(e) => { + println!("✗ Failed to deserialize {}: {:?}", description, e); + panic!("Version extraction failed for {}", description); + }, + } + } +} diff --git a/crates/miden-standards/Cargo.toml b/crates/miden-standards/Cargo.toml index a57fb2814e..3bb1b6a773 100644 --- a/crates/miden-standards/Cargo.toml +++ b/crates/miden-standards/Cargo.toml @@ -30,20 +30,20 @@ thiserror = { workspace = true } [build-dependencies] fs-err = { version = "3" } -miden-assembly = { workspace = true } -miden-core = { workspace = true } -miden-core-lib = { workspace = true } -miden-protocol = { workspace = true } +miden-assembly = { default-features = false, workspace = true } +miden-core = { default-features = false, workspace = true } +miden-core-lib = { default-features = false, workspace = true } +miden-protocol = { default-features = false, workspace = true } regex = { version = "1.11" } walkdir = { version = "2.5" } [dev-dependencies] anyhow = "1.0" assert_matches = { workspace = true } -miden-processor = { features = ["testing"], workspace = true } -miden-protocol = { features = ["testing"], workspace = true } +miden-processor = { default-features = false, features = ["testing"], workspace = true } +miden-protocol = { default-features = false, features = ["testing"], workspace = true } # When building as a dev-dependency (e.g., `cargo test --workspace` or `cargo check --all-targets`), # enable the `testing` feature. This is a workaround for Cargo's lack of test-specific features. # See: https://github.com/rust-lang/cargo/issues/2911#issuecomment-1483256987 -miden-standards = { features = ["testing"], path = "." } +miden-standards = { default-features = false, features = ["testing"], path = "." } diff --git a/crates/miden-standards/src/account/faucets/basic_fungible.rs b/crates/miden-standards/src/account/faucets/basic_fungible.rs index 329937ebd4..ff840c82c7 100644 --- a/crates/miden-standards/src/account/faucets/basic_fungible.rs +++ b/crates/miden-standards/src/account/faucets/basic_fungible.rs @@ -9,7 +9,7 @@ use miden_protocol::account::{ StorageSlotName, }; use miden_protocol::asset::{FungibleAsset, TokenSymbol}; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Felt, Word, ZERO}; use super::FungibleFaucetError; use crate::account::AuthScheme; @@ -189,12 +189,8 @@ impl From for AccountComponent { fn from(faucet: BasicFungibleFaucet) -> Self { // Note: data is stored as [a0, a1, a2, a3] but loaded onto the stack as // [a3, a2, a1, a0, ...] - let metadata = Word::new([ - faucet.max_supply, - Felt::from(faucet.decimals), - faucet.symbol.into(), - Felt::ZERO, - ]); + let metadata = + Word::new([faucet.max_supply, Felt::from(faucet.decimals), faucet.symbol.into(), ZERO]); let storage_slot = StorageSlot::with_value(BasicFungibleFaucet::metadata_slot().clone(), metadata); @@ -313,7 +309,7 @@ mod tests { use assert_matches::assert_matches; use miden_protocol::account::AccountStorage; use miden_protocol::account::auth::PublicKeyCommitment; - use miden_protocol::{FieldElement, ONE, Word}; + use miden_protocol::{ONE, Word, ZERO}; use super::{ AccountBuilder, @@ -381,7 +377,7 @@ mod tests { // allow_unauthorized_input_notes=true, this should be [1, 0, 1, 0]. assert_eq!( faucet_account.storage().get_item(AuthRpoFalcon512Acl::config_slot()).unwrap(), - [Felt::ONE, Felt::ZERO, Felt::ONE, Felt::ZERO].into() + [ONE, ZERO, ONE, ZERO].into() ); // The procedure root map should contain the distribute procedure root. @@ -391,7 +387,7 @@ mod tests { .storage() .get_map_item( AuthRpoFalcon512Acl::trigger_procedure_roots_slot(), - [Felt::ZERO, Felt::ZERO, Felt::ZERO, Felt::ZERO].into() + [ZERO, ZERO, ZERO, ZERO].into() ) .unwrap(), distribute_root @@ -400,7 +396,7 @@ mod tests { // Check that faucet metadata was initialized to the given values. assert_eq!( faucet_account.storage().get_item(BasicFungibleFaucet::metadata_slot()).unwrap(), - [Felt::new(123), Felt::new(2), token_symbol.into(), Felt::ZERO].into() + [Felt::new(123), Felt::new(2), token_symbol.into(), ZERO].into() ); assert!(faucet_account.is_faucet()); diff --git a/crates/miden-standards/src/account/faucets/network_fungible.rs b/crates/miden-standards/src/account/faucets/network_fungible.rs index 912e89e863..9ddccf579e 100644 --- a/crates/miden-standards/src/account/faucets/network_fungible.rs +++ b/crates/miden-standards/src/account/faucets/network_fungible.rs @@ -11,7 +11,7 @@ use miden_protocol::account::{ }; use miden_protocol::asset::TokenSymbol; use miden_protocol::utils::sync::LazyLock; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Felt, Word, ZERO}; use super::{BasicFungibleFaucet, FungibleFaucetError}; use crate::account::auth::NoAuth; @@ -211,7 +211,7 @@ impl From for AccountComponent { network_faucet.faucet.max_supply(), Felt::from(network_faucet.faucet.decimals()), network_faucet.faucet.symbol().into(), - Felt::ZERO, + ZERO, ]); // Convert AccountId into its Word encoding for storage. diff --git a/crates/miden-standards/src/account/interface/component.rs b/crates/miden-standards/src/account/interface/component.rs index 75bba9bb8f..207610f149 100644 --- a/crates/miden-standards/src/account/interface/component.rs +++ b/crates/miden-standards/src/account/interface/component.rs @@ -4,7 +4,7 @@ use alloc::vec::Vec; use miden_protocol::account::auth::PublicKeyCommitment; use miden_protocol::account::{AccountId, AccountProcedureRoot, AccountStorage, StorageSlotName}; use miden_protocol::note::PartialNote; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Felt, Word, ZERO}; use crate::AuthScheme; use crate::account::auth::{ @@ -313,7 +313,7 @@ fn extract_multisig_auth_scheme( // Read each public key from the map for key_index in 0..num_approvers { // The multisig component stores keys using pattern [index, 0, 0, 0] - let map_key = [Felt::new(key_index as u64), Felt::ZERO, Felt::ZERO, Felt::ZERO]; + let map_key = [Felt::new(key_index as u64), ZERO, ZERO, ZERO]; match storage.get_map_item(approver_public_keys_slot, map_key.into()) { Ok(pub_key) => { diff --git a/crates/miden-standards/src/note/well_known_note.rs b/crates/miden-standards/src/note/well_known_note.rs index df0f219782..e4d7348efe 100644 --- a/crates/miden-standards/src/note/well_known_note.rs +++ b/crates/miden-standards/src/note/well_known_note.rs @@ -378,10 +378,14 @@ fn parse_p2ide_inputs(note_inputs: &[Felt]) -> Result<(AccountId, u32, u32), Sta let receiver_account_id = try_read_account_id_from_inputs(note_inputs)?; - let reclaim_height = u32::try_from(note_inputs[2]) + let reclaim_height_u64 = note_inputs[2].as_int(); + let reclaim_height: u32 = reclaim_height_u64 + .try_into() .map_err(|_err| StaticAnalysisError::new("reclaim block height should be a u32"))?; - let timelock_height = u32::try_from(note_inputs[3]) + let timelock_height_u64 = note_inputs[3].as_int(); + let timelock_height: u32 = timelock_height_u64 + .try_into() .map_err(|_err| StaticAnalysisError::new("timelock block height should be a u32"))?; Ok((receiver_account_id, reclaim_height, timelock_height)) diff --git a/crates/miden-testing/Cargo.toml b/crates/miden-testing/Cargo.toml index 4420fa6249..c293cf5551 100644 --- a/crates/miden-testing/Cargo.toml +++ b/crates/miden-testing/Cargo.toml @@ -24,6 +24,7 @@ miden-tx = { features = ["testing"], workspace = true } miden-tx-batch-prover = { features = ["testing"], workspace = true } # Miden dependencies +miden-air = { workspace = true } miden-processor = { workspace = true } # External dependencies @@ -31,12 +32,11 @@ anyhow = { workspace = true } itertools = { default-features = false, features = ["use_alloc"], version = "0.14" } rand = { features = ["os_rng", "small_rng"], workspace = true } rand_chacha = { workspace = true } -winterfell = { version = "0.13" } [dev-dependencies] anyhow = { features = ["backtrace", "std"], workspace = true } assert_matches = { workspace = true } -miden-protocol = { features = ["std"], workspace = true } +miden-protocol = { default-features = false, features = ["std"], workspace = true } rstest = { workspace = true } tokio = { features = ["macros", "rt"], workspace = true } winter-rand-utils = { version = "0.13" } 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 3f6b1f509f..b5e45365b2 100644 --- a/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs +++ b/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs @@ -561,15 +561,26 @@ fn input_and_output_notes_commitment() -> anyhow::Result<()> { assert_eq!(batch.output_notes().len(), 3); assert_eq!(batch.output_notes(), expected_output_notes); - // Input notes are sorted by the order in which they appeared in the batch. + // Check that we have exactly 2 input notes (note1 was erased as it was created and consumed + // in the batch). assert_eq!(batch.input_notes().num_notes(), 2); - assert_eq!( - batch.input_notes().clone().into_vec(), - &[ - InputNoteCommitment::from(&InputNote::unauthenticated(note5)), - InputNoteCommitment::from(&InputNote::unauthenticated(note4)), - ] - ); + + // The input notes come from a BTreeMap, so their order depends on + // Nullifier::Ord. We verify set equality rather than order equality. + let expected_input_notes = vec![ + InputNoteCommitment::from(&InputNote::unauthenticated(note5)), + InputNoteCommitment::from(&InputNote::unauthenticated(note4)), + ]; + let actual_input_notes = batch.input_notes().clone().into_vec(); + + assert_eq!(actual_input_notes.len(), expected_input_notes.len()); + for note in &expected_input_notes { + assert!( + actual_input_notes.contains(note), + "Expected note with nullifier {:?} not found in batch input notes", + note.nullifier() + ); + } Ok(()) } diff --git a/crates/miden-testing/src/kernel_tests/batch/proven_tx_builder.rs b/crates/miden-testing/src/kernel_tests/batch/proven_tx_builder.rs index 95be1c04c5..65064ad402 100644 --- a/crates/miden-testing/src/kernel_tests/batch/proven_tx_builder.rs +++ b/crates/miden-testing/src/kernel_tests/batch/proven_tx_builder.rs @@ -1,6 +1,7 @@ use alloc::vec::Vec; use anyhow::Context; +use miden_air::HashFunction; use miden_protocol::Word; use miden_protocol::account::AccountId; use miden_protocol::asset::FungibleAsset; @@ -111,7 +112,7 @@ impl MockProvenTxBuilder { self.ref_block_commitment.unwrap_or_default(), self.fee, self.expiration_block_num, - ExecutionProof::new_dummy(), + ExecutionProof::new(Vec::new(), HashFunction::Blake3_256, Vec::new()), ) .add_input_notes(self.input_notes.unwrap_or_default()) .add_input_notes(self.nullifiers.unwrap_or_default()) diff --git a/crates/miden-testing/src/kernel_tests/block/header_errors.rs b/crates/miden-testing/src/kernel_tests/block/header_errors.rs index a4a48262c1..8a02a89b1a 100644 --- a/crates/miden-testing/src/kernel_tests/block/header_errors.rs +++ b/crates/miden-testing/src/kernel_tests/block/header_errors.rs @@ -2,6 +2,7 @@ use alloc::vec::Vec; use anyhow::Context; use assert_matches::assert_matches; +use miden_air::HashFunction; use miden_protocol::account::delta::AccountUpdateDetails; use miden_protocol::account::{ Account, @@ -391,7 +392,7 @@ async fn block_building_fails_on_creating_account_with_duplicate_account_id_pref genesis_block.commitment(), FungibleAsset::mock(500).unwrap_fungible(), BlockNumber::from(u32::MAX), - ExecutionProof::new_dummy(), + ExecutionProof::new(Vec::new(), HashFunction::Blake3_256, Vec::new()), ) .account_update_details(AccountUpdateDetails::Private) .build() 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 cce09fcaaa..51797e0490 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 @@ -11,7 +11,7 @@ use miden_protocol::block::{BlockInputs, ProposedBlock}; use miden_protocol::note::{Note, NoteType}; use miden_protocol::testing::account_id::ACCOUNT_ID_SENDER; use miden_protocol::transaction::{ExecutedTransaction, OutputNote, TransactionHeader}; -use miden_protocol::{Felt, FieldElement}; +use miden_protocol::{Felt, ONE, ZERO}; use miden_standards::testing::account_component::MockAccountComponent; use miden_standards::testing::note::NoteBuilder; use miden_tx::LocalTransactionProver; @@ -331,7 +331,7 @@ async fn generate_conditional_tx( ) -> ExecutedTransaction { let auth_args = [ // increment nonce if modify_storage is true - if modify_storage { Felt::ONE } else { Felt::ZERO }, + if modify_storage { ONE } else { ZERO }, Felt::new(99), Felt::new(98), Felt::new(97), 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 342da526a3..7928066cff 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_account.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_account.rs @@ -5,6 +5,7 @@ use std::collections::BTreeMap; use anyhow::Context; use assert_matches::assert_matches; use miden_processor::{ExecutionError, Word}; +use miden_protocol::LexicographicWord; use miden_protocol::account::delta::AccountUpdateDetails; use miden_protocol::account::{ Account, @@ -48,7 +49,6 @@ use miden_protocol::testing::account_id::{ use miden_protocol::testing::storage::{MOCK_MAP_SLOT, MOCK_VALUE_SLOT0, MOCK_VALUE_SLOT1}; use miden_protocol::transaction::{OutputNote, TransactionKernel}; use miden_protocol::utils::sync::LazyLock; -use miden_protocol::{LexicographicWord, StarkField}; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_standards::testing::mock_account::MockAccountExt; @@ -69,6 +69,18 @@ use crate::{ assert_transaction_executor_error, }; +// HELPER FUNCTIONS +// ================================================================================================ + +fn rand_word() -> Word { + Word::from([ + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + ]) +} + // ACCOUNT COMMITMENT TESTS // ================================================================================================ @@ -204,7 +216,7 @@ async fn test_account_type() -> miette::Result<()> { .await?; let type_matches = account_id.account_type() == expected_type; - let expected_result = Felt::from(type_matches); + let expected_result = if type_matches { Felt::new(1) } else { Felt::new(0) }; has_type |= type_matches; assert_eq!( @@ -256,8 +268,8 @@ async fn test_account_validate_id() -> miette::Result<()> { for (account_id, expected_error) in test_cases.iter() { // Manually split the account ID into prefix and suffix since we can't use AccountId methods // on invalid ids. - let prefix = Felt::try_from((account_id / (1u128 << 64)) as u64).unwrap(); - let suffix = Felt::try_from((account_id % (1u128 << 64)) as u64).unwrap(); + let prefix = Felt::from((account_id / (1u128 << 64)) as u64); + let suffix = Felt::from((account_id % (1u128 << 64)) as u64); let code = " use $kernel::account_id @@ -929,7 +941,7 @@ async fn prove_account_creation_with_non_empty_storage() -> anyhow::Result<()> { let slot1 = StorageSlot::with_value(slot_name1.clone(), Word::from([10, 20, 30, 40u32])); let mut map_entries = Vec::new(); for _ in 0..10 { - map_entries.push((rand_value::(), rand_value::())); + map_entries.push((rand_word(), rand_word())); } let map_slot = StorageSlot::with_map(slot_name2.clone(), StorageMap::with_entries(map_entries.clone())?); @@ -979,7 +991,7 @@ async fn prove_account_creation_with_non_empty_storage() -> anyhow::Result<()> { assert!(tx.account_delta().vault().is_empty()); assert_eq!(tx.final_account().nonce(), Felt::new(1)); - let proven_tx = LocalTransactionProver::default().prove(tx.clone())?; + let proven_tx = LocalTransactionProver::default().prove_async(tx.clone()).await?; // The delta should be present on the proven tx. let AccountUpdateDetails::Delta(delta) = proven_tx.account_update().details() else { @@ -1758,8 +1770,8 @@ async fn incrementing_nonce_overflow_fails() -> anyhow::Result<()> { .build_existing() .context("failed to build account")?; // Increment the nonce to the maximum felt value. The nonce is already 1, so we increment by - // modulus - 2. - account.increment_nonce(Felt::new(Felt::MODULUS - 2))?; + // modulus - 2 (Goldilocks: 2^64 - 2^32 + 1). + account.increment_nonce(Felt::new(0xffffffff00000000 - 1))?; let result = TransactionContextBuilder::new(account).build()?.execute().await; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_account_delta.rs b/crates/miden-testing/src/kernel_tests/tx/test_account_delta.rs index bf2473d7f5..7a7b9f4bb2 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_account_delta.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_account_delta.rs @@ -37,7 +37,7 @@ use miden_protocol::testing::constants::{ }; use miden_protocol::testing::storage::{MOCK_MAP_SLOT, MOCK_VALUE_SLOT0}; use miden_protocol::transaction::TransactionScript; -use miden_protocol::{EMPTY_WORD, Felt, FieldElement, LexicographicWord, Word, ZERO}; +use miden_protocol::{EMPTY_WORD, Felt, LexicographicWord, ONE, Word, ZERO}; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_tx::LocalTransactionProver; @@ -48,6 +48,18 @@ use winter_rand_utils::rand_value; use crate::utils::create_public_p2any_note; use crate::{Auth, MockChain, TransactionContextBuilder}; +// HELPER FUNCTIONS +// ================================================================================================ + +fn rand_word() -> Word { + Word::from([ + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + ]) +} + // ACCOUNT DELTA TESTS // // Note that in all of these tests, the transaction executor will ensure that the account delta @@ -223,12 +235,12 @@ async fn storage_delta_for_value_slots() -> anyhow::Result<()> { async fn storage_delta_for_map_slots() -> anyhow::Result<()> { // Test with random keys to make sure the ordering in the MASM and Rust implementations // matches. - let key0 = rand_value::(); - let key1 = rand_value::(); - let key2 = rand_value::(); - let key3 = rand_value::(); - let key4 = rand_value::(); - let key5 = rand_value::(); + let key0 = rand_word(); + let key1 = rand_word(); + let key2 = rand_word(); + let key3 = rand_word(); + let key4 = rand_word(); + let key5 = rand_word(); let key0_init_value = EMPTY_WORD; let key1_init_value = EMPTY_WORD; @@ -816,13 +828,13 @@ async fn asset_and_storage_delta() -> anyhow::Result<()> { async fn proven_tx_storage_maps_matches_executed_tx_for_new_account() -> anyhow::Result<()> { // Use two identical maps to test that they are properly handled // (see also https://github.com/0xMiden/miden-base/issues/2037). - let map0 = StorageMap::with_entries([(rand_value(), rand_value())])?; + let map0 = StorageMap::with_entries([(rand_word(), rand_word())])?; let map1 = map0.clone(); let mut map2 = StorageMap::with_entries([ - (rand_value(), rand_value()), - (rand_value(), rand_value()), - (rand_value(), rand_value()), - (rand_value(), rand_value()), + (rand_word(), rand_word()), + (rand_word(), rand_word()), + (rand_word(), rand_word()), + (rand_word(), rand_word()), ])?; let map0_slot_name = StorageSlotName::mock(1); @@ -977,7 +989,7 @@ async fn delta_for_new_account_retains_empty_value_storage_slots() -> anyhow::Re let recreated_account = Account::try_from(delta)?; // The recreated account should match the original account with the nonce incremented (and the // seed removed). - account.increment_nonce(Felt::ONE)?; + account.increment_nonce(ONE)?; assert_eq!(recreated_account, account); Ok(()) @@ -1020,7 +1032,7 @@ async fn delta_for_new_account_retains_empty_map_storage_slots() -> anyhow::Resu let recreated_account = Account::try_from(delta)?; // The recreated account should match the original account with the nonce incremented (and the // seed removed). - account.increment_nonce(Felt::ONE)?; + account.increment_nonce(ONE)?; assert_eq!(recreated_account, account); Ok(()) 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 8be831ff05..eb547b70ba 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,7 +24,7 @@ use miden_protocol::testing::account_id::{ ACCOUNT_ID_SENDER, }; use miden_protocol::transaction::{InputNote, OutputNote, TransactionKernel}; -use miden_protocol::{Felt, StarkField, Word, ZERO}; +use miden_protocol::{Felt, Word, ZERO}; use miden_standards::note::{ NoteConsumptionStatus, WellKnownNote, @@ -484,7 +484,7 @@ async fn test_check_note_consumability_static_analysis_invalid_inputs() -> anyho [ target_account_id.suffix().as_int(), target_account_id.prefix().as_u64(), - Felt::MODULUS - 1, + 0xffffffff00000000, // Goldilocks MODULUS - 1 4, ], sender_account_id, @@ -495,7 +495,7 @@ async fn test_check_note_consumability_static_analysis_invalid_inputs() -> anyho target_account_id.suffix().as_int(), target_account_id.prefix().as_u64(), 3, - Felt::MODULUS - 1, + 0xffffffff00000000, // Goldilocks MODULUS - 1 ], sender_account_id, ); 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 907a3b58a6..518a9da817 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_faucet.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_faucet.rs @@ -420,7 +420,7 @@ async fn burn_fungible_asset_fails_on_non_faucet_account() -> anyhow::Result<()> async fn test_burn_fungible_asset_inconsistent_faucet_id() -> anyhow::Result<()> { let tx_context = TransactionContextBuilder::with_fungible_faucet( ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, - Felt::try_from(FUNGIBLE_FAUCET_INITIAL_BALANCE).unwrap(), + Felt::from(FUNGIBLE_FAUCET_INITIAL_BALANCE), ) .build()?; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_fee.rs b/crates/miden-testing/src/kernel_tests/tx/test_fee.rs index 0a865d1098..2e1b15e962 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_fee.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_fee.rs @@ -12,6 +12,18 @@ use winter_rand_utils::rand_value; use crate::utils::create_public_p2any_note; use crate::{Auth, MockChain}; +// HELPER FUNCTIONS +// ================================================================================================ + +fn rand_word() -> Word { + Word::from([ + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + ]) +} + // FEE TESTS // ================================================================================================ @@ -132,10 +144,10 @@ async fn mutate_account_with_storage() -> anyhow::Result { let account = builder.add_existing_mock_account_with_storage_and_assets( Auth::IncrNonce, [ - StorageSlot::with_value(StorageSlotName::mock(0), rand_value()), + StorageSlot::with_value(StorageSlotName::mock(0), rand_word()), StorageSlot::with_map( StorageSlotName::mock(1), - StorageMap::with_entries([(rand_value(), rand_value())])?, + StorageMap::with_entries([(rand_word(), rand_word())])?, ), ], [Asset::from(native_asset), NonFungibleAsset::mock(&[1, 2, 3, 4])], @@ -166,9 +178,9 @@ async fn create_output_notes() -> anyhow::Result { [ StorageSlot::with_map( StorageSlotName::mock(0), - StorageMap::with_entries([(rand_value(), rand_value())])?, + StorageMap::with_entries([(rand_word(), rand_word())])?, ), - StorageSlot::with_value(StorageSlotName::mock(1), rand_value()), + StorageSlot::with_value(StorageSlotName::mock(1), rand_word()), ], [Asset::from(native_asset), NonFungibleAsset::mock(&[1, 2, 3, 4])], )?; 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 42b0cb4098..5acc3794ed 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_fpi.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_fpi.rs @@ -2,8 +2,8 @@ use alloc::sync::Arc; use alloc::vec; use alloc::vec::Vec; +use miden_processor::AdviceInputs; use miden_processor::fast::ExecutionOutput; -use miden_processor::{AdviceInputs, Felt}; use miden_protocol::account::{ Account, AccountBuilder, @@ -38,7 +38,7 @@ use miden_protocol::transaction::memory::{ NUM_ACCT_PROCEDURES_OFFSET, NUM_ACCT_STORAGE_SLOTS_OFFSET, }; -use miden_protocol::{FieldElement, Word, ZERO}; +use miden_protocol::{ONE, Word, ZERO}; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; use miden_tx::LocalTransactionProver; @@ -1284,7 +1284,7 @@ async fn test_prove_fpi_two_foreign_accounts_chain() -> anyhow::Result<()> { .await?; // Prove the executed transaction which uses FPI across two foreign accounts. - LocalTransactionProver::default().prove(executed_transaction)?; + LocalTransactionProver::default().prove_async(executed_transaction).await?; Ok(()) } @@ -1614,10 +1614,9 @@ async fn test_fpi_stale_account() -> anyhow::Result<()> { // Modify the account's storage to change its storage commitment and in turn the account // commitment. - foreign_account.storage_mut().set_item( - mock_value_slot0.name(), - Word::from([Felt::ONE, Felt::ONE, Felt::ONE, Felt::ONE]), - )?; + foreign_account + .storage_mut() + .set_item(mock_value_slot0.name(), Word::from([ONE, ONE, ONE, ONE]))?; // We pass the modified foreign account with a witness that is valid against the ref block. This // means the foreign account's commitment does not match the commitment that the account witness 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 fca31cf22a..d4d5ec9f7d 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 @@ -4,13 +4,28 @@ use std::string::String; use anyhow::Context; use miden_processor::{ONE, ZERO}; -use miden_protocol::{EMPTY_WORD, LexicographicWord, Word}; +use miden_protocol::{EMPTY_WORD, Felt, LexicographicWord, Word}; use miden_tx::{LinkMap, MemoryViewer}; use rand::seq::IteratorRandom; use winter_rand_utils::rand_value; use crate::TransactionContextBuilder; +// HELPER FUNCTIONS +// ================================================================================================ + +fn rand_word() -> Word { + Word::from([ + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + Felt::new(rand_value::()), + ]) +} + +// TESTS +// ================================================================================================ + /// Tests the following properties: /// - Insertion into an empty map. /// - Insertion after an existing entry. @@ -604,8 +619,8 @@ fn generate_entries(count: u64) -> Vec<(LexicographicWord, (Word, Word))> { (0..count) .map(|_| { let key = rand_link_map_key(); - let value0 = rand_value::(); - let value1 = rand_value::(); + let value0 = rand_word(); + let value1 = rand_word(); (key, (value0, value1)) }) .collect() @@ -621,10 +636,10 @@ fn generate_updates( .iter() .choose_multiple(&mut rng, num_updates) .into_iter() - .map(|(key, _)| (*key, (rand_value::(), rand_value::()))) + .map(|(key, _)| (*key, (rand_word(), rand_word()))) .collect() } fn rand_link_map_key() -> LexicographicWord { - LexicographicWord::new(rand_value()) + LexicographicWord::new(rand_word()) } 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 8bee856271..5b9568658d 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_note.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_note.rs @@ -382,7 +382,7 @@ async fn test_build_metadata() -> miette::Result<()> { NoteTag::from_account_id(receiver), NoteExecutionHint::after_block(500.into()) .map_err(|e| miette::miette!("Failed to create execution hint: {}", e))?, - Felt::try_from(1u64 << 63).map_err(|e| miette::miette!("Failed to convert felt: {}", e))?, + Felt::from(1u64 << 63), ) .map_err(|e| miette::miette!("Failed to create metadata: {}", e))?; let test_metadata2 = NoteMetadata::new( @@ -392,7 +392,7 @@ async fn test_build_metadata() -> miette::Result<()> { NoteTag::for_public_use_case((1 << 14) - 1, u16::MAX, NoteExecutionMode::Local) .map_err(|e| miette::miette!("Failed to create note tag: {}", e))?, NoteExecutionHint::on_block_slot(u8::MAX, u8::MAX, u8::MAX), - Felt::try_from(0u64).map_err(|e| miette::miette!("Failed to convert felt: {}", e))?, + Felt::from(0u64), ) .map_err(|e| miette::miette!("Failed to create metadata: {}", e))?; 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 7354f55c90..6640208f4c 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_tx.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_tx.rs @@ -49,7 +49,7 @@ use miden_protocol::transaction::{ TransactionKernel, TransactionSummary, }; -use miden_protocol::{Felt, FieldElement, Hasher, ONE, Word}; +use miden_protocol::{Felt, Hasher, ONE, Word, ZERO}; use miden_standards::AuthScheme; use miden_standards::account::interface::{AccountInterface, AccountInterfaceExt}; use miden_standards::account::wallets::BasicWallet; @@ -456,14 +456,8 @@ async fn user_code_can_abort_transaction_with_summary() -> anyhow::Result<()> { // Consume and create a note so the input and outputs notes commitment is not the empty word. let mut rng = RpoRandomCoin::new(Word::empty()); - let output_note = create_p2id_note( - account.id(), - account.id(), - vec![], - NoteType::Private, - Felt::ZERO, - &mut rng, - )?; + let output_note = + create_p2id_note(account.id(), account.id(), vec![], NoteType::Private, ZERO, &mut rng)?; let input_note = create_spawn_note(vec![&output_note])?; let mut builder = MockChain::builder(); @@ -499,14 +493,8 @@ async fn tx_summary_commitment_is_signed_by_falcon_auth() -> anyhow::Result<()> let mut builder = MockChain::builder(); let account = builder.add_existing_mock_account(Auth::BasicAuth)?; let mut rng = RpoRandomCoin::new(Word::empty()); - let p2id_note = create_p2id_note( - account.id(), - account.id(), - vec![], - NoteType::Private, - Felt::ZERO, - &mut rng, - )?; + let p2id_note = + create_p2id_note(account.id(), account.id(), vec![], NoteType::Private, ZERO, &mut rng)?; let spawn_note = builder.add_spawn_note([&p2id_note])?; let chain = builder.build()?; @@ -563,14 +551,8 @@ async fn tx_summary_commitment_is_signed_by_ecdsa_auth() -> anyhow::Result<()> { let mut builder = MockChain::builder(); let account = builder.add_existing_mock_account(Auth::EcdsaK256KeccakAuth)?; let mut rng = RpoRandomCoin::new(Word::empty()); - let p2id_note = create_p2id_note( - account.id(), - account.id(), - vec![], - NoteType::Private, - Felt::ZERO, - &mut rng, - )?; + let p2id_note = + create_p2id_note(account.id(), account.id(), vec![], NoteType::Private, ZERO, &mut rng)?; let spawn_note = builder.add_spawn_note([&p2id_note])?; let chain = builder.build()?; diff --git a/crates/miden-testing/src/mock_chain/chain.rs b/crates/miden-testing/src/mock_chain/chain.rs index 5e94bc5df9..56a3eec888 100644 --- a/crates/miden-testing/src/mock_chain/chain.rs +++ b/crates/miden-testing/src/mock_chain/chain.rs @@ -32,9 +32,8 @@ use miden_protocol::transaction::{ }; use miden_tx::LocalTransactionProver; use miden_tx::auth::BasicAuthenticator; -use miden_tx::utils::{ByteReader, Deserializable, Serializable}; +use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, Serializable}; use miden_tx_batch_prover::LocalBatchProver; -use winterfell::ByteWriter; use super::note::MockChainNote; use crate::{MockChainBuilder, TransactionContextBuilder}; diff --git a/crates/miden-testing/src/mock_chain/chain_builder.rs b/crates/miden-testing/src/mock_chain/chain_builder.rs index 34be3a1044..b6fa595be9 100644 --- a/crates/miden-testing/src/mock_chain/chain_builder.rs +++ b/crates/miden-testing/src/mock_chain/chain_builder.rs @@ -46,7 +46,7 @@ use miden_protocol::note::{Note, NoteDetails, NoteType}; use miden_protocol::testing::account_id::ACCOUNT_ID_NATIVE_ASSET_FAUCET; use miden_protocol::testing::random_signer::RandomBlockSigner; use miden_protocol::transaction::{OrderedTransactionHeaders, OutputNote, TransactionKernel}; -use miden_protocol::{Felt, FieldElement, MAX_OUTPUT_NOTES_PER_BATCH, NoteError, Word, ZERO}; +use miden_protocol::{Felt, MAX_OUTPUT_NOTES_PER_BATCH, NoteError, Word, ZERO}; use miden_standards::account::faucets::{BasicFungibleFaucet, NetworkFungibleFaucet}; use miden_standards::account::wallets::BasicWallet; use miden_standards::note::{create_p2id_note, create_p2ide_note, create_swap_note}; @@ -308,9 +308,7 @@ impl MockChainBuilder { ) -> anyhow::Result { let token_symbol = TokenSymbol::new(token_symbol) .with_context(|| format!("invalid token symbol: {token_symbol}"))?; - let max_supply_felt = max_supply.try_into().map_err(|_| { - anyhow::anyhow!("max supply value cannot be converted to Felt: {max_supply}") - })?; + let max_supply_felt: Felt = max_supply.into(); let basic_faucet = BasicFungibleFaucet::new(token_symbol, DEFAULT_FAUCET_DECIMALS, max_supply_felt) .context("failed to create BasicFungibleFaucet")?; @@ -553,7 +551,7 @@ impl MockChainBuilder { target_account_id, asset.to_vec(), note_type, - Felt::ZERO, + ZERO, &mut self.rng, )?; self.add_output_note(OutputNote::Full(note.clone())); @@ -604,9 +602,9 @@ impl MockChainBuilder { offered_asset, requested_asset, NoteType::Public, - Felt::ZERO, + ZERO, payback_note_type, - Felt::ZERO, + ZERO, &mut self.rng, )?; diff --git a/crates/miden-testing/src/mock_chain/note.rs b/crates/miden-testing/src/mock_chain/note.rs index 759ef257ea..3e3884135d 100644 --- a/crates/miden-testing/src/mock_chain/note.rs +++ b/crates/miden-testing/src/mock_chain/note.rs @@ -1,8 +1,7 @@ use miden_processor::DeserializationError; use miden_protocol::note::{Note, NoteId, NoteInclusionProof, NoteMetadata}; use miden_protocol::transaction::InputNote; -use miden_tx::utils::{ByteReader, Deserializable, Serializable}; -use winterfell::ByteWriter; +use miden_tx::utils::{ByteReader, ByteWriter, Deserializable, Serializable}; // MOCK CHAIN NOTE // ================================================================================================ diff --git a/crates/miden-testing/src/tx_context/builder.rs b/crates/miden-testing/src/tx_context/builder.rs index 453bb2c73e..16c0a7741a 100644 --- a/crates/miden-testing/src/tx_context/builder.rs +++ b/crates/miden-testing/src/tx_context/builder.rs @@ -43,7 +43,7 @@ use crate::{MockChain, MockChainNote}; /// ``` /// # use anyhow::Result; /// # use miden_testing::TransactionContextBuilder; -/// # use miden_protocol::{account::AccountBuilder,Felt, FieldElement}; +/// # use miden_protocol::{account::AccountBuilder,Felt}; /// # use miden_protocol::transaction::TransactionKernel; /// # /// # #[tokio::main(flavor = "current_thread")] diff --git a/crates/miden-testing/tests/auth/ecdsa_acl.rs b/crates/miden-testing/tests/auth/ecdsa_acl.rs index 9bdaf80ebc..a1d4cfa8aa 100644 --- a/crates/miden-testing/tests/auth/ecdsa_acl.rs +++ b/crates/miden-testing/tests/auth/ecdsa_acl.rs @@ -12,7 +12,7 @@ use miden_protocol::account::{ use miden_protocol::note::Note; use miden_protocol::testing::storage::MOCK_VALUE_SLOT0; use miden_protocol::transaction::OutputNote; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Word, ZERO}; use miden_standards::account::auth::AuthEcdsaK256KeccakAcl; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; @@ -153,7 +153,7 @@ async fn test_ecdsa_acl() -> anyhow::Result<()> { .execute() .await .expect("trigger 1 with auth should succeed"); - prove_and_verify_transaction(executed_tx_with_auth_1)?; + prove_and_verify_transaction(executed_tx_with_auth_1).await?; // Test 2: Transaction WITH authenticator calling trigger procedure 2 (should succeed) let tx_context_with_auth_2 = mock_chain @@ -191,7 +191,7 @@ async fn test_ecdsa_acl() -> anyhow::Result<()> { .expect("no trigger, no auth should succeed"); assert_eq!( executed.account_delta().nonce_delta(), - Felt::ZERO, + ZERO, "no auth but should still trigger nonce increment" ); @@ -231,7 +231,7 @@ async fn test_ecdsa_acl_with_allow_unauthorized_output_notes() -> anyhow::Result .expect("no trigger, no auth should succeed"); assert_eq!( executed.account_delta().nonce_delta(), - Felt::ZERO, + ZERO, "no auth but should still trigger nonce increment" ); diff --git a/crates/miden-testing/tests/auth/multisig.rs b/crates/miden-testing/tests/auth/multisig.rs index 2c32f08211..87e72d4de6 100644 --- a/crates/miden-testing/tests/auth/multisig.rs +++ b/crates/miden-testing/tests/auth/multisig.rs @@ -706,9 +706,8 @@ async fn test_multisig_update_signers_remove_owner() -> anyhow::Result<()> { mock_chain.add_pending_executed_transaction(&update_approvers_tx)?; mock_chain.prove_next_block()?; - // Apply delta to get updated account - let mut updated_multisig_account = multisig_account.clone(); - updated_multisig_account.apply_delta(update_approvers_tx.account_delta())?; + // Get the updated account from the chain (after the block was proven) + let updated_multisig_account = mock_chain.committed_account(multisig_account.id())?; // Verify public keys were updated for (i, expected_key) in new_public_keys.iter().enumerate() { @@ -728,7 +727,7 @@ async fn test_multisig_update_signers_remove_owner() -> anyhow::Result<()> { assert_eq!(threshold_config[1], Felt::new(num_of_approvers), "Num approvers not updated"); // Verify extracted public keys - let extracted_pub_keys = get_public_keys_from_account(&updated_multisig_account); + let extracted_pub_keys = get_public_keys_from_account(updated_multisig_account); assert_eq!(extracted_pub_keys.len(), 2, "Should have 2 public keys after update"); for expected_key in new_public_keys.iter() { diff --git a/crates/miden-testing/tests/auth/rpo_falcon_acl.rs b/crates/miden-testing/tests/auth/rpo_falcon_acl.rs index 91519a07bb..cfa0b0e77a 100644 --- a/crates/miden-testing/tests/auth/rpo_falcon_acl.rs +++ b/crates/miden-testing/tests/auth/rpo_falcon_acl.rs @@ -13,7 +13,7 @@ use miden_protocol::account::{ use miden_protocol::note::Note; use miden_protocol::testing::storage::MOCK_VALUE_SLOT0; use miden_protocol::transaction::OutputNote; -use miden_protocol::{Felt, FieldElement, Word}; +use miden_protocol::{Word, ZERO}; use miden_standards::account::auth::AuthRpoFalcon512Acl; use miden_standards::code_builder::CodeBuilder; use miden_standards::testing::account_component::MockAccountComponent; @@ -189,7 +189,7 @@ async fn test_rpo_falcon_acl() -> anyhow::Result<()> { .context("no trigger, no auth should succeed")?; assert_eq!( executed.account_delta().nonce_delta(), - Felt::ZERO, + ZERO, "no auth but should still trigger nonce increment" ); @@ -229,7 +229,7 @@ async fn test_rpo_falcon_acl_with_allow_unauthorized_output_notes() -> anyhow::R .expect("no trigger, no auth should succeed"); assert_eq!( executed.account_delta().nonce_delta(), - Felt::ZERO, + ZERO, "no auth but should still trigger nonce increment" ); diff --git a/crates/miden-testing/tests/lib.rs b/crates/miden-testing/tests/lib.rs index 37339b3b25..4cb7a14ba9 100644 --- a/crates/miden-testing/tests/lib.rs +++ b/crates/miden-testing/tests/lib.rs @@ -24,7 +24,7 @@ use miden_tx::{ // ================================================================================================ #[cfg(test)] -pub fn prove_and_verify_transaction( +pub async fn prove_and_verify_transaction( executed_transaction: ExecutedTransaction, ) -> Result<(), TransactionVerifierError> { use miden_protocol::transaction::TransactionHeader; @@ -35,7 +35,7 @@ pub fn prove_and_verify_transaction( let proof_options = ProvingOptions::default(); let prover = LocalTransactionProver::new(proof_options); - let proven_transaction = prover.prove(executed_transaction).unwrap(); + let proven_transaction = prover.prove_async(executed_transaction).await.unwrap(); let proven_tx_header = TransactionHeader::from(&proven_transaction); assert_eq!(proven_transaction.id(), executed_transaction_id); diff --git a/crates/miden-testing/tests/scripts/faucet.rs b/crates/miden-testing/tests/scripts/faucet.rs index 38b378a903..d3c61c03bc 100644 --- a/crates/miden-testing/tests/scripts/faucet.rs +++ b/crates/miden-testing/tests/scripts/faucet.rs @@ -301,7 +301,7 @@ async fn prove_burning_fungible_asset_on_existing_faucet_succeeds() -> anyhow::R .await?; // Prove, serialize/deserialize and verify the transaction - prove_and_verify_transaction(executed_transaction.clone())?; + prove_and_verify_transaction(executed_transaction.clone()).await?; assert_eq!(executed_transaction.account_delta().nonce_delta(), Felt::new(1)); assert_eq!(executed_transaction.input_notes().get_note(0).id(), note.id()); diff --git a/crates/miden-testing/tests/scripts/fee.rs b/crates/miden-testing/tests/scripts/fee.rs index 3fd41d7b78..144f445d08 100644 --- a/crates/miden-testing/tests/scripts/fee.rs +++ b/crates/miden-testing/tests/scripts/fee.rs @@ -45,7 +45,7 @@ async fn prove_account_creation_with_fees() -> anyhow::Result<()> { // account commitment should not be the empty word assert_ne!(tx.account_delta().to_commitment(), Word::empty()); - prove_and_verify_transaction(tx)?; + prove_and_verify_transaction(tx).await?; Ok(()) } diff --git a/crates/miden-testing/tests/scripts/p2id.rs b/crates/miden-testing/tests/scripts/p2id.rs index 870bd7a193..5763bcd944 100644 --- a/crates/miden-testing/tests/scripts/p2id.rs +++ b/crates/miden-testing/tests/scripts/p2id.rs @@ -128,7 +128,7 @@ async fn prove_consume_note_with_new_account() -> anyhow::Result<()> { executed_transaction.final_account().commitment(), target_account_after.commitment() ); - prove_and_verify_transaction(executed_transaction)?; + prove_and_verify_transaction(executed_transaction).await?; Ok(()) } @@ -170,7 +170,8 @@ async fn prove_consume_multiple_notes() -> anyhow::Result<()> { panic!("Resulting asset should be fungible"); } - Ok(prove_and_verify_transaction(executed_transaction)?) + prove_and_verify_transaction(executed_transaction).await?; + Ok(()) } /// Consumes two existing notes and creates two other notes in the same transaction diff --git a/crates/miden-testing/tests/scripts/swap.rs b/crates/miden-testing/tests/scripts/swap.rs index bce9193a6c..ead2d5fc02 100644 --- a/crates/miden-testing/tests/scripts/swap.rs +++ b/crates/miden-testing/tests/scripts/swap.rs @@ -90,7 +90,7 @@ pub async fn prove_send_swap_note() -> anyhow::Result<()> { let swap_output_note = create_swap_note_tx.output_notes().iter().next().unwrap(); assert_eq!(swap_output_note.assets().unwrap().iter().next().unwrap(), &offered_asset); - assert!(prove_and_verify_transaction(create_swap_note_tx).is_ok()); + assert!(prove_and_verify_transaction(create_swap_note_tx).await.is_ok()); Ok(()) } @@ -156,9 +156,11 @@ async fn consume_swap_note_private_payback_note() -> anyhow::Result<()> { assert!(sender_account.vault().assets().any(|asset| asset == requested_asset)); prove_and_verify_transaction(consume_swap_note_tx) + .await .context("failed to prove/verify consume_swap_note_tx")?; prove_and_verify_transaction(consume_payback_tx) + .await .context("failed to prove/verify consume_payback_tx")?; Ok(()) diff --git a/crates/miden-tx/Cargo.toml b/crates/miden-tx/Cargo.toml index e78138760f..d1202a337d 100644 --- a/crates/miden-tx/Cargo.toml +++ b/crates/miden-tx/Cargo.toml @@ -14,9 +14,16 @@ version.workspace = true [features] concurrent = ["miden-prover/concurrent", "std"] -default = ["std"] -std = ["miden-processor/std", "miden-protocol/std", "miden-prover/std", "miden-standards/std", "miden-verifier/std"] -testing = ["miden-processor/testing", "miden-protocol/testing", "miden-standards/testing"] +default = ["std"] +std = [ + "miden-air/std", + "miden-processor/std", + "miden-protocol/std", + "miden-prover/std", + "miden-standards/std", + "miden-verifier/std", +] +testing = ["miden-processor/testing", "miden-protocol/testing", "miden-standards/testing"] [dependencies] # Workspace dependencies @@ -24,16 +31,19 @@ miden-protocol = { workspace = true } miden-standards = { workspace = true } # Miden dependencies +miden-air = { workspace = true } +miden-crypto = { workspace = true } miden-processor = { workspace = true } miden-prover = { workspace = true } miden-verifier = { workspace = true } # External dependencies +bincode = "1.3" thiserror = { workspace = true } [dev-dependencies] anyhow = { features = ["backtrace", "std"], workspace = true } assert_matches = { workspace = true } -miden-assembly = { workspace = true } -miden-tx = { features = ["testing"], path = "." } +miden-assembly = { default-features = false, workspace = true } +miden-tx = { default-features = false, features = ["testing"], path = "." } rstest = { workspace = true } diff --git a/crates/miden-tx/src/auth/tx_authenticator.rs b/crates/miden-tx/src/auth/tx_authenticator.rs index 4845421445..bacfc35e27 100644 --- a/crates/miden-tx/src/auth/tx_authenticator.rs +++ b/crates/miden-tx/src/auth/tx_authenticator.rs @@ -274,7 +274,7 @@ impl TransactionAuthenticator for () { } } -#[cfg(test)] +#[cfg(all(test, feature = "std"))] mod test { use miden_protocol::account::auth::AuthSecretKey; use miden_protocol::utils::{Deserializable, Serializable}; diff --git a/crates/miden-tx/src/executor/mod.rs b/crates/miden-tx/src/executor/mod.rs index 105dbe7ff2..cc3c67c20f 100644 --- a/crates/miden-tx/src/executor/mod.rs +++ b/crates/miden-tx/src/executor/mod.rs @@ -80,6 +80,7 @@ where exec_options: ExecutionOptions::new( Some(MAX_TX_EXECUTION_CYCLES), MIN_TX_EXECUTION_CYCLES, + 1 << 12, // DEFAULT_CORE_TRACE_FRAGMENT_SIZE = 4096 false, false, ) diff --git a/crates/miden-tx/src/host/account_delta_tracker.rs b/crates/miden-tx/src/host/account_delta_tracker.rs index f62e7996e8..ac58375844 100644 --- a/crates/miden-tx/src/host/account_delta_tracker.rs +++ b/crates/miden-tx/src/host/account_delta_tracker.rs @@ -5,7 +5,7 @@ use miden_protocol::account::{ AccountVaultDelta, PartialAccount, }; -use miden_protocol::{Felt, FieldElement, ZERO}; +use miden_protocol::{Felt, ONE, ZERO}; use crate::host::storage_delta_tracker::StorageDeltaTracker; @@ -50,12 +50,12 @@ impl AccountDeltaTracker { /// Returns true if the nonce delta is non-zero. pub fn was_nonce_incremented(&self) -> bool { - self.nonce_delta != Felt::ZERO + self.nonce_delta != ZERO } /// Increments the nonce delta by one. pub fn increment_nonce(&mut self) { - self.nonce_delta += Felt::ONE; + self.nonce_delta += ONE; } /// Returns a reference to the vault delta. diff --git a/crates/miden-tx/src/host/kernel_process.rs b/crates/miden-tx/src/host/kernel_process.rs index 50dbb83840..7e7c533094 100644 --- a/crates/miden-tx/src/host/kernel_process.rs +++ b/crates/miden-tx/src/host/kernel_process.rs @@ -67,14 +67,17 @@ impl<'a> TransactionKernelProcess for ProcessState<'a> { self.get_mem_value(self.ctx(), ACCOUNT_STACK_TOP_PTR).ok_or_else(|| { TransactionKernelError::other("account stack top ptr should be initialized") })?; - let account_stack_top_ptr = u32::try_from(account_stack_top_ptr).map_err(|_| { - TransactionKernelError::other("account stack top ptr should fit into a u32") - })?; + let account_stack_top_ptr: u32 = + account_stack_top_ptr.as_int().try_into().map_err(|_| { + TransactionKernelError::other("account stack top ptr should fit into a u32") + })?; let active_account_ptr = self .get_mem_value(self.ctx(), account_stack_top_ptr) .ok_or_else(|| TransactionKernelError::other("account id should be initialized"))?; - u32::try_from(active_account_ptr) + active_account_ptr + .as_int() + .try_into() .map_err(|_| TransactionKernelError::other("active account ptr should fit into a u32")) } @@ -143,7 +146,7 @@ impl<'a> TransactionKernelProcess for ProcessState<'a> { None => return Ok(None), }; // convert note address into u32 - let note_address = u32::try_from(note_address_felt).map_err(|_| { + let note_address: u32 = note_address_felt.as_int().try_into().map_err(|_| { TransactionKernelError::other(format!( "failed to convert {note_address_felt} into a memory address (u32)" )) @@ -166,7 +169,7 @@ impl<'a> TransactionKernelProcess for ProcessState<'a> { /// Returns the vault root at the provided pointer. fn get_vault_root(&self, vault_root_ptr: Felt) -> Result { - let vault_root_ptr = u32::try_from(vault_root_ptr).map_err(|_err| { + let vault_root_ptr: u32 = vault_root_ptr.as_int().try_into().map_err(|_err| { TransactionKernelError::other(format!( "vault root ptr should fit into a u32, but was {vault_root_ptr}" )) @@ -188,7 +191,7 @@ impl<'a> TransactionKernelProcess for ProcessState<'a> { &self, slot_ptr: Felt, ) -> Result<(StorageSlotId, StorageSlotType, Word), TransactionKernelError> { - let slot_ptr = u32::try_from(slot_ptr).map_err(|_err| { + let slot_ptr: u32 = slot_ptr.as_int().try_into().map_err(|_err| { TransactionKernelError::other(format!( "slot ptr should fit into a u32, but was {slot_ptr}" )) @@ -222,7 +225,7 @@ impl<'a> TransactionKernelProcess for ProcessState<'a> { })?; let slot_type = slot_metadata[ACCT_STORAGE_SLOT_TYPE_OFFSET as usize]; - let slot_type = u8::try_from(slot_type).map_err(|err| { + let slot_type: u8 = slot_type.as_int().try_into().map_err(|err| { TransactionKernelError::other(format!("failed to convert {slot_type} into u8: {err}")) })?; let slot_type = StorageSlotType::try_from(slot_type).map_err(|err| { diff --git a/crates/miden-tx/src/host/link_map.rs b/crates/miden-tx/src/host/link_map.rs index 5024c86dfd..95f620ddae 100644 --- a/crates/miden-tx/src/host/link_map.rs +++ b/crates/miden-tx/src/host/link_map.rs @@ -30,7 +30,7 @@ impl<'process> LinkMap<'process> { /// Creates a new link map from the provided map_ptr in the provided process. pub fn new(map_ptr: Felt, mem: &'process MemoryViewer<'process>) -> Self { - let map_ptr: u32 = map_ptr.try_into().expect("map_ptr must be a valid u32"); + let map_ptr: u32 = map_ptr.as_int().try_into().expect("map_ptr must be a valid u32"); Self { map_ptr, mem } } @@ -94,7 +94,7 @@ impl<'process> LinkMap<'process> { if head_ptr == ZERO { None } else { - Some(u32::try_from(head_ptr).expect("head ptr should be a valid ptr")) + Some(head_ptr.as_int().try_into().expect("head ptr should be a valid ptr")) } }) } @@ -142,15 +142,17 @@ impl<'process> LinkMap<'process> { self.mem.get_kernel_mem_word(entry_ptr).expect("entry pointer should be valid"); let map_ptr = entry_metadata[0]; - let map_ptr = map_ptr.try_into().expect("entry_ptr should point to a u32 map_ptr"); + let map_ptr = map_ptr.as_int().try_into().expect("entry_ptr should point to a u32 map_ptr"); let prev_entry_ptr = entry_metadata[1]; let prev_entry_ptr = prev_entry_ptr + .as_int() .try_into() .expect("entry_ptr should point to a u32 prev_entry_ptr"); let next_entry_ptr = entry_metadata[2]; let next_entry_ptr = next_entry_ptr + .as_int() .try_into() .expect("entry_ptr should point to a u32 next_entry_ptr"); diff --git a/crates/miden-tx/src/prover/mod.rs b/crates/miden-tx/src/prover/mod.rs index 60d13b4c52..c7f26b29a9 100644 --- a/crates/miden-tx/src/prover/mod.rs +++ b/crates/miden-tx/src/prover/mod.rs @@ -16,7 +16,9 @@ use miden_protocol::transaction::{ TransactionOutputs, }; pub use miden_prover::ProvingOptions; -use miden_prover::{ExecutionProof, Word, prove}; +#[cfg(not(target_arch = "wasm32"))] +use miden_prover::prove_sync; +use miden_prover::{ExecutionProof, HashFunction, Word}; use super::TransactionProverError; use crate::host::{AccountProcedureIndexMap, ScriptMastForestStore}; @@ -45,6 +47,150 @@ impl LocalTransactionProver { } } + /// Async version of prove that uses the async processor API. + /// This avoids Tokio runtime nesting issues when called from async contexts. + pub async fn prove_async( + &self, + tx_inputs: impl Into, + ) -> Result { + let tx_inputs = tx_inputs.into(); + let (stack_inputs, advice_inputs) = TransactionKernel::prepare_inputs(&tx_inputs); + + self.mast_store.load_account_code(tx_inputs.account().code()); + for account_code in tx_inputs.foreign_account_code() { + self.mast_store.load_account_code(account_code); + } + + let script_mast_store = ScriptMastForestStore::new( + tx_inputs.tx_script(), + tx_inputs.input_notes().iter().map(|n| n.note().script()), + ); + + let account_procedure_index_map = AccountProcedureIndexMap::new( + tx_inputs.foreign_account_code().iter().chain([tx_inputs.account().code()]), + ); + + let (partial_account, ref_block, _, input_notes, _) = tx_inputs.into_parts(); + let mut host = TransactionProverHost::new( + &partial_account, + input_notes, + self.mast_store.as_ref(), + script_mast_store, + account_procedure_index_map, + ); + + let advice_inputs = advice_inputs.into_advice_inputs(); + + // Call the async prover instead of sync + let (stack_outputs, proof) = self + .prove_inner_async(stack_inputs, advice_inputs.clone(), &mut host) + .await + .map_err(TransactionProverError::TransactionProgramExecutionFailed)?; + + // Extract transaction outputs and process transaction data. + let (pre_fee_account_delta, input_notes, output_notes) = host.into_parts(); + let tx_outputs = + TransactionKernel::from_transaction_parts(&stack_outputs, &advice_inputs, output_notes) + .map_err(TransactionProverError::TransactionOutputConstructionFailed)?; + + self.build_proven_transaction( + &input_notes, + tx_outputs, + pre_fee_account_delta, + partial_account, + ref_block.block_num(), + ref_block.commitment(), + proof, + ) + } + + /// Inner async prover that replicates miden_prover::prove but uses async processor. + async fn prove_inner_async( + &self, + stack_inputs: miden_prover::StackInputs, + advice_inputs: miden_prover::AdviceInputs, + host: &mut impl miden_prover::AsyncHost, + ) -> Result<(miden_prover::StackOutputs, ExecutionProof), miden_prover::ExecutionError> { + use miden_air::ProcessorAir; + use miden_processor::fast::FastProcessor; + use miden_processor::parallel::build_trace; + use miden_prover::math::Felt; + + const DEFAULT_FRAGMENT_SIZE: usize = 1 << 16; + + let program = &TransactionKernel::main(); + + // Reverse stack inputs + let stack_inputs_reversed: Vec = stack_inputs.iter().copied().rev().collect(); + + let processor = if self.proof_options.execution_options().enable_debugging() { + FastProcessor::new_debug(&stack_inputs_reversed, advice_inputs.clone()) + } else { + FastProcessor::new_with_advice_inputs(&stack_inputs_reversed, advice_inputs.clone()) + }; + + // Use async execute_for_trace instead of sync version + let (execution_output, trace_generation_context) = + processor.execute_for_trace(program, host, DEFAULT_FRAGMENT_SIZE).await?; + + let trace = build_trace( + execution_output, + trace_generation_context, + program.hash(), + program.kernel().clone(), + ); + + let stack_outputs = trace.stack_outputs().clone(); + let precompile_requests = trace.precompile_requests().to_vec(); + let hash_fn = self.proof_options.hash_fn(); + + // Convert trace to row-major format + let trace_matrix = miden_prover::execution_trace_to_row_major(&trace); + + // Build public values + let public_values = trace.to_public_values(); + + // Create AIR with aux trace builders + let air = ProcessorAir::with_aux_builder(trace.aux_trace_builders().clone()); + + // Generate STARK proof using unified miden-prover + let proof_bytes = match hash_fn { + HashFunction::Blake3_256 => { + let config = miden_air::config::create_blake3_256_config(); + let proof = + miden_crypto::stark::prove(&config, &air, &trace_matrix, &public_values); + bincode::serialize(&proof).expect("Failed to serialize proof") + }, + HashFunction::Keccak => { + let config = miden_air::config::create_keccak_config(); + let proof = + miden_crypto::stark::prove(&config, &air, &trace_matrix, &public_values); + bincode::serialize(&proof).expect("Failed to serialize proof") + }, + HashFunction::Rpo256 => { + let config = miden_air::config::create_rpo_config(); + let proof = + miden_crypto::stark::prove(&config, &air, &trace_matrix, &public_values); + bincode::serialize(&proof).expect("Failed to serialize proof") + }, + HashFunction::Poseidon2 => { + let config = miden_air::config::create_poseidon2_config(); + let proof = + miden_crypto::stark::prove(&config, &air, &trace_matrix, &public_values); + bincode::serialize(&proof).expect("Failed to serialize proof") + }, + HashFunction::Rpx256 => { + let config = miden_air::config::create_rpx_config(); + let proof = + miden_crypto::stark::prove(&config, &air, &trace_matrix, &public_values); + bincode::serialize(&proof).expect("Failed to serialize proof") + }, + }; + + let proof = ExecutionProof::new(proof_bytes, hash_fn, precompile_requests); + Ok((stack_outputs, proof)) + } + fn build_proven_transaction( &self, input_notes: &InputNotes, @@ -94,6 +240,7 @@ impl LocalTransactionProver { builder.build().map_err(TransactionProverError::ProvenTransactionBuildFailed) } + #[cfg(not(target_arch = "wasm32"))] pub fn prove( &self, tx_inputs: impl Into, @@ -126,7 +273,8 @@ impl LocalTransactionProver { let advice_inputs = advice_inputs.into_advice_inputs(); - let (stack_outputs, proof) = prove( + // On non-wasm32, use prove_sync(). This code path is gated by the function-level cfg. + let (stack_outputs, proof) = prove_sync( &TransactionKernel::main(), stack_inputs, advice_inputs.clone(), @@ -181,7 +329,7 @@ impl LocalTransactionProver { partial_account, ref_block.block_num(), ref_block.commitment(), - ExecutionProof::new_dummy(), + ExecutionProof::new(Vec::new(), HashFunction::Blake3_256, Vec::new()), ) } } diff --git a/crates/miden-tx/src/prover/prover_host.rs b/crates/miden-tx/src/prover/prover_host.rs index de31f51da4..043352df5e 100644 --- a/crates/miden-tx/src/prover/prover_host.rs +++ b/crates/miden-tx/src/prover/prover_host.rs @@ -3,6 +3,7 @@ use alloc::vec::Vec; use miden_processor::{ AdviceMutation, + AsyncHost, BaseHost, EventError, MastForest, @@ -190,3 +191,25 @@ where result.map_err(EventError::from) } } + +// ASYNC HOST IMPLEMENTATION +// ================================================================================================ + +impl AsyncHost for TransactionProverHost<'_, STORE> +where + STORE: MastForestStore, +{ + fn get_mast_forest( + &self, + node_digest: &Word, + ) -> impl miden_processor::FutureMaybeSend>> { + core::future::ready(SyncHost::get_mast_forest(self, node_digest)) + } + + fn on_event( + &mut self, + process: &ProcessState<'_>, + ) -> impl miden_processor::FutureMaybeSend, EventError>> { + core::future::ready(SyncHost::on_event(self, process)) + } +} diff --git a/deny.toml b/deny.toml index 3679142018..b680b8602e 100644 --- a/deny.toml +++ b/deny.toml @@ -22,6 +22,7 @@ allow = [ "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", + "CC0-1.0", "ISC", "MIT", "Unicode-3.0", @@ -62,11 +63,17 @@ skip-tree = [ # Allow syn v1.x and v2.x - our derive macros need v1.x while ecosystem uses v2.x { name = "syn", version = "=1.0.109" }, { name = "syn", version = "=2.0.111" }, + # Allow itertools v0.12/v0.13/v0.14 - Plonky3 and miden-vm use different versions + { name = "itertools", version = "=0.12.*" }, + { name = "itertools", version = "=0.13.*" }, + # Allow spin v0.9.x - legacy version used by some dependencies + { name = "spin", version = "=0.9.*" }, ] wildcards = "allow" # Sources configuration [sources] +allow-git = ["https://github.com/0xPolygonMiden/miden-vm"] allow-registry = ["https://github.com/rust-lang/crates.io-index"] unknown-git = "deny" unknown-registry = "deny"