From 53203d28070f0e3e5765713731538869adf9344b Mon Sep 17 00:00:00 2001 From: Hrishikesh Jain Date: Tue, 6 Oct 2026 17:21:51 +0530 Subject: [PATCH 1/2] feat(wasm-utxo): add Zcash NU7 consensus branch id Zcash testnet activated NU7 at block 4,465,026 (ZIP-259), introducing consensus branch id 0x77190ad9. Per ZIP-2003, version 4 transactions become invalid once NU7 activates; only v5 (ZIP-225) and v6 (ZIP-229) remain valid. `NetworkUpgrade` stopped at Nu6_3, so `branch_id_for_height` resolved post-NU7 testnet heights to the NU6.3 branch id, and `new_at_height` went on to build a version 4 transaction regardless. Those signed and queued normally, then failed every broadcast with "transaction version 4 not supported by the network upgrade Nu7" and retried indefinitely (observed in sendq: 5 stuck TZEC sends, one retried ~750 times over ~7h). Adds the Nu7 entry and rejects a v4 build at or after NU7 activation, so the failure surfaces at build time instead of after signing. v6 (Ironwood) builds are unaffected and remain the valid path. NU7 has no assigned mainnet activation height yet (TBD in ZIP-259), so `UpgradeParams::mainnet_activation_height` becomes `Option`: an upgrade with no height on a network is never active there, leaving mainnet on NU6.3. The zebra parity test compares the field as an `Option`, so it starts failing the moment zebra publishes a height rather than silently drifting. Bumps the zebra-chain dev-dependency 11.2 -> 14.0: 11.2 carries Nu7 only as a test-only placeholder (0xfffffffe), so the parity tests can only check the real constants against 14. Adjusts the v6 zebra-oracle test for 14's API, which exposes ironwood actions as its own orchard release's `Action` type. Refs: SPT-483 --- packages/wasm-utxo/Cargo.lock | 1097 +++++++++++++---- packages/wasm-utxo/Cargo.toml | 8 +- packages/wasm-utxo/README.md | 3 +- .../src/fixed_script_wallet/bitgo_psbt/mod.rs | 75 +- .../bitgo_psbt/zcash_psbt.rs | 67 +- packages/wasm-utxo/src/zcash/mod.rs | 104 +- 6 files changed, 1028 insertions(+), 326 deletions(-) diff --git a/packages/wasm-utxo/Cargo.lock b/packages/wasm-utxo/Cargo.lock index c32bbeeab54..696105339fa 100644 --- a/packages/wasm-utxo/Cargo.lock +++ b/packages/wasm-utxo/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addchain" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5665045de74fda906c0abfaec40cf2551f88c34dccea869f3fe950dde7209764" +dependencies = [ + "num-bigint 0.4.6", + "num-integer", + "num-traits", +] + [[package]] name = "aead" version = "0.5.2" @@ -12,6 +23,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "aead" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" +dependencies = [ + "crypto-common 0.2.2", + "inout 0.2.2", +] + [[package]] name = "aes" version = "0.8.4" @@ -19,8 +40,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", - "cpufeatures", + "cipher 0.4.4", + "cpufeatures 0.2.17", +] + +[[package]] +name = "aes" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f0f96ce78e38c3dc6d8948aa8163d06385be74000f3c7a95bf1eef35d3ea32" +dependencies = [ + "cipher 0.5.2", + "cpubits", + "cpufeatures 0.3.1", ] [[package]] @@ -141,7 +173,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -156,6 +188,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base16ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" + [[package]] name = "base58ck" version = "0.1.0" @@ -192,37 +230,34 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "bellman" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afceed28bac7f9f5a508bca8aeeff51cdfa4770c0b967ac55c621e2ddfd6171" +checksum = "973b16549796a1274a63e00159a03250e66e8263e2ac6344b1c9fdfe9b7a8325" dependencies = [ "bitvec", "blake2s_simd", "byteorder", "crossbeam-channel", - "ff", - "group", - "lazy_static 1.5.0", + "ff 0.14.0", + "group 0.14.0", "log", "num_cpus", - "pairing", - "rand_core", + "rand_core 0.10.1", "rayon", "subtle", ] [[package]] name = "bip32" -version = "0.6.0-pre.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143f5327f23168716be068f8e1014ba2ea16a6c91e8777bc8927da7b51e1df1f" +checksum = "0271a2fe2a6f05231419e878b5f50152a5a6dbcc60c18855d924892ecc85a33a" dependencies = [ "bs58", - "hmac 0.13.0-pre.4", - "rand_core", - "ripemd 0.2.0-pre.4", - "secp256k1", - "sha2 0.11.0-pre.4", + "hmac 0.13.0", + "ripemd 0.2.0", + "secp256k1 0.33.1", + "sha2 0.11.0", "subtle", "zeroize", ] @@ -241,7 +276,7 @@ dependencies = [ "blake2", "hex-conservative 0.2.2", "hex_lit", - "secp256k1", + "secp256k1 0.29.1", ] [[package]] @@ -348,9 +383,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-rc.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ "hybrid-array", ] @@ -361,11 +396,23 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" dependencies = [ - "ff", - "group", + "ff 0.13.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "bls12_381" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18f887f26229478dcd0e0d063566b51c68fb55a38fba21799c5f3371a74ec61f" +dependencies = [ + "ff 0.14.0", + "group 0.14.0", "pairing", - "rand_core", + "rand_core 0.10.1", "subtle", + "zeroize", ] [[package]] @@ -418,7 +465,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "cbc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2dc9ee5f88d11e0beb842c88b33c8a5cf0d1329c4b19494af42b07dbfe8896" +dependencies = [ + "cipher 0.5.2", ] [[package]] @@ -444,8 +500,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", - "cpufeatures", + "cipher 0.4.4", + "cpufeatures 0.2.17", +] + +[[package]] +name = "chacha20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cipher 0.5.2", + "cpufeatures 0.3.1", ] [[package]] @@ -454,13 +521,25 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", + "aead 0.5.2", + "chacha20 0.9.1", + "cipher 0.4.4", + "poly1305 0.8.0", "zeroize", ] +[[package]] +name = "chacha20poly1305" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" +dependencies = [ + "aead 0.6.1", + "chacha20 0.10.2", + "cipher 0.5.2", + "poly1305 0.9.1", +] + [[package]] name = "chrono" version = "0.4.42" @@ -480,10 +559,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common 0.1.6", - "inout", + "inout 0.1.4", "zeroize", ] +[[package]] +name = "cipher" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" +dependencies = [ + "block-buffer 0.12.1", + "crypto-common 0.2.2", + "inout 0.2.2", +] + [[package]] name = "clap" version = "4.5.53" @@ -515,7 +605,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -524,6 +614,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "cobs" version = "0.3.0" @@ -574,6 +670,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-random" version = "0.1.18" @@ -641,6 +743,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4df6f98652d30167eaeea34d77b730e07c8caba6df17bd4551842b9b8da01deb" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -650,6 +758,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -697,7 +814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -714,23 +831,32 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] +[[package]] +name = "ctutils" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03bb0e1cc970d482d121d9a1744999169b69a07470b3d644a7894e53fcaf4574" +dependencies = [ + "cmov", +] + [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.3.1", "curve25519-dalek-derive", - "digest 0.10.7", + "digest 0.11.3", "fiat-crypto", "rustc_version", "serde", @@ -746,7 +872,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -770,7 +896,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.111", ] [[package]] @@ -781,7 +907,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -790,7 +916,17 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", + "zeroize", +] + +[[package]] +name = "der" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" +dependencies = [ + "const-oid 0.10.2", "pem-rfc7468", "zeroize", ] @@ -813,7 +949,7 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -829,13 +965,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.9" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.11.0-rc.3", - "crypto-common 0.2.0-rc.1", - "subtle", + "block-buffer 0.12.1", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -910,36 +1046,36 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.10", "elliptic-curve", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ - "pkcs8", - "serde", - "signature", + "pkcs8 0.11.0", + "serdect", + "signature 3.0.0", ] [[package]] name = "ed25519-zebra" -version = "4.2.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775765289f7c6336c18d3d66127527820dd45ffd9eb3b6b8ee4708590e6c20f5" +checksum = "aa764ad1bb0a84aaed1575b6d426ce927f610225bd9aeee88d02e08a6fea8215" dependencies = [ "curve25519-dalek", "ed25519", "hashbrown 0.16.1", - "pkcs8", - "rand_core", + "pkcs8 0.11.0", + "rand_core 0.10.1", "serde", - "sha2 0.10.9", + "sha2 0.11.0", "subtle", "zeroize", ] @@ -956,14 +1092,14 @@ version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", + "base16ct 0.2.0", "crypto-bigint", "digest 0.10.7", - "ff", + "ff 0.13.1", "generic-array", - "group", - "pkcs8", - "rand_core", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -1039,15 +1175,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "bitvec", - "rand_core", + "rand_core 0.6.4", "subtle", ] +[[package]] +name = "ff" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" +dependencies = [ + "bitvec", + "ff_derive", + "rand_core 0.10.1", + "subtle", +] + +[[package]] +name = "ff_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241afe8c15ffa21933eaefe8a563af36fd9fc98a3e8a044e8f7db52eb1fae3d8" +dependencies = [ + "addchain", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" @@ -1062,7 +1225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.6", "rustc-hex", "static_assertions", ] @@ -1091,10 +1254,24 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26c4b37de5ae15812a764c958297cfc50f5c010438f60c6ce75d11b802abd404" dependencies = [ - "cbc", - "cipher", + "cbc 0.1.2", + "cipher 0.4.4", + "libm", + "num-bigint 0.4.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "fpe" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5045d51a6a5e85e0a18d909eedd270c4d82ad634fee57ba707692fb3b1add5a7" +dependencies = [ + "cbc 0.2.1", + "cipher 0.5.2", "libm", - "num-bigint", + "num-bigint 0.5.1", "num-integer", "num-traits", ] @@ -1107,9 +1284,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -1122,9 +1299,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -1132,15 +1309,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -1149,32 +1326,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-timer" @@ -1184,9 +1361,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -1196,7 +1373,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -1232,10 +1408,22 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", +] + [[package]] name = "getset" version = "0.1.7" @@ -1244,7 +1432,7 @@ checksum = "6cf442baaabe4213ce7d1239afc26c039180b6456da2cededa316ae2c8a77a77" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -1253,15 +1441,43 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "groth16" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb1e0bde2dbacd81474ae216c5dd4901307bd1c75fd26ed49590e88048c8442" +dependencies = [ + "bellman", + "byteorder", + "ff 0.14.0", + "group 0.14.0", + "pairing", + "rand 0.10.3", + "rand_core 0.10.1", + "rayon", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" +dependencies = [ + "ff 0.14.0", "memuse", - "rand_core", + "rand_core 0.10.1", "subtle", ] @@ -1273,14 +1489,33 @@ checksum = "fb2a697cad929f706b7987fe804ad57d43622cd37463ba7e4d662a926fdcfea3" dependencies = [ "arrayvec", "bitvec", - "ff", - "group", - "halo2_poseidon", - "halo2_proofs", + "ff 0.13.1", + "group 0.13.0", + "halo2_poseidon 0.1.0", + "halo2_proofs 0.3.2", "lazy_static 1.5.0", - "pasta_curves", - "rand", - "sinsemilla", + "pasta_curves 0.5.1", + "rand 0.8.6", + "sinsemilla 0.1.0", + "subtle", + "uint 0.9.5", +] + +[[package]] +name = "halo2_gadgets" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8862c7f2d99964760016516103fcc621352e77a505b22b0fc25140f09e4b8bb0" +dependencies = [ + "arrayvec", + "bitvec", + "ff 0.14.0", + "group 0.14.0", + "halo2_poseidon 0.2.0", + "halo2_proofs 0.4.0", + "pasta_curves 0.6.0", + "rand 0.10.3", + "sinsemilla 0.2.0", "subtle", "uint 0.9.5", ] @@ -1298,9 +1533,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa3da60b81f02f9b33ebc6252d766f843291fb4d2247a07ae73d20b791fc56f" dependencies = [ "bitvec", - "ff", - "group", - "pasta_curves", + "ff 0.13.1", + "group 0.13.0", + "pasta_curves 0.5.1", +] + +[[package]] +name = "halo2_poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "800f76fa421515e2729192e3863bb0a58f30fe17a9a165ea5e778a157adeb579" +dependencies = [ + "bitvec", + "ff 0.14.0", + "group 0.14.0", + "pasta_curves 0.6.0", ] [[package]] @@ -1310,13 +1557,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05713f117155643ce10975e0bee44a274bcda2f4bb5ef29a999ad67c1fa8d4d3" dependencies = [ "blake2b_simd", - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "halo2_legacy_pdqsort", "indexmap 1.9.3", "maybe-rayon", - "pasta_curves", - "rand_core", + "pasta_curves 0.5.1", + "rand_core 0.6.4", + "tracing", +] + +[[package]] +name = "halo2_proofs" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5af2a9457f494f862cd07b81c2e98a19f50b06a2057b7569450d7c26b167d1c" +dependencies = [ + "blake2b_simd", + "ff 0.14.0", + "group 0.14.0", + "halo2_legacy_pdqsort", + "indexmap 2.12.1", + "maybe-rayon", + "pasta_curves 0.6.0", + "rand 0.10.3", + "rand_core 0.10.1", "tracing", ] @@ -1409,11 +1674,11 @@ dependencies = [ [[package]] name = "hmac" -version = "0.13.0-pre.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.11.0-pre.9", + "digest 0.11.3", ] [[package]] @@ -1424,9 +1689,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hybrid-array" -version = "0.2.3" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" dependencies = [ "typenum", ] @@ -1478,7 +1743,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -1490,6 +1755,15 @@ dependencies = [ "either", ] +[[package]] +name = "incrementalmerkletree" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b0c166f7f34e02988f84a7bed22be9707b1569acc6aeb3afaf34152d0e0400" +dependencies = [ + "either", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1522,6 +1796,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "hybrid-array", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1571,11 +1854,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8499f7a74008aafbecb2a2e608a3e13e4dd3e84df198b604451efe93f2de6e61" dependencies = [ "bitvec", - "bls12_381", - "ff", - "group", - "rand_core", + "bls12_381 0.8.0", + "ff 0.13.1", + "group 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "jubjub" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fdd9a071f72385ed8b17d819f273d73c3887a93d34d2ac1419fca5b25dbbd2" +dependencies = [ + "bitvec", + "bls12_381 0.9.0", + "ff 0.14.0", + "group 0.14.0", + "rand_core 0.10.1", "subtle", + "zeroize", ] [[package]] @@ -1693,13 +1991,19 @@ dependencies = [ "hex-conservative 1.0.1", ] +[[package]] +name = "mset" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c4d16a3d2b0e89ec6e7d509cf791545fcb48cbc8fc2fb2e96a492defda9140" + [[package]] name = "musig2" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c5ffeab912897e7577287c8f2b4efbc4be24912f77531b45ba4b18c93f8be21" dependencies = [ - "base16ct", + "base16ct 0.2.0", "hmac 0.12.1", "k256", "once_cell", @@ -1743,6 +2047,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.2.0" @@ -1814,34 +2128,71 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cca2ede6a4a77bd729eed3be9303d98a08b217edc85190dcf4dbe004086d5a65" dependencies = [ - "aes", + "aes 0.8.4", "bitvec", "blake2b_simd", "corez", - "ff", - "fpe", + "ff 0.13.1", + "fpe 0.6.1", "getset", - "group", - "halo2_gadgets", - "halo2_poseidon", - "halo2_proofs", + "group 0.13.0", + "halo2_gadgets 0.5.0", + "halo2_poseidon 0.1.0", + "halo2_proofs 0.3.2", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.8.2", "lazy_static 1.5.0", "memuse", "nonempty", - "pasta_curves", - "rand", - "rand_core", - "reddsa", + "pasta_curves 0.5.1", + "rand 0.8.6", + "rand_core 0.6.4", + "reddsa 0.5.1", "serde", - "sinsemilla", + "sinsemilla 0.1.0", "subtle", "tracing", "visibility", - "zcash_note_encryption", + "zcash_note_encryption 0.4.1", "zcash_spec", - "zip32", + "zip32 0.2.1", +] + +[[package]] +name = "orchard" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae7ceb7b5387bd76cf3c0712f57708795c925cecf097036cedb60b5c3706e8f" +dependencies = [ + "aes 0.9.3", + "bitvec", + "blake2b_simd", + "corez", + "ff 0.14.0", + "fpe 0.7.0", + "getset", + "group 0.14.0", + "halo2_gadgets 0.6.0", + "halo2_poseidon 0.2.0", + "halo2_proofs 0.4.0", + "hex", + "incrementalmerkletree 0.9.0", + "lazy_static 1.5.0", + "memuse", + "nonempty", + "pasta_curves 0.6.0", + "rand 0.10.3", + "rand_core 0.10.1", + "reddsa 0.6.1", + "serde", + "sinsemilla 0.2.0", + "subtle", + "tracing", + "visibility", + "zcash_note_encryption 0.5.1", + "zcash_spec", + "zeroize", + "zip32 0.3.0", ] [[package]] @@ -1865,11 +2216,11 @@ dependencies = [ [[package]] name = "pairing" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +checksum = "33f6413397336802d16a342e69a5bd9c8b8cc2fa9fc9298044cd3443f77f1010" dependencies = [ - "group", + "group 0.14.0", ] [[package]] @@ -1897,7 +2248,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -1907,14 +2258,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ "blake2b_simd", - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "lazy_static 1.5.0", - "rand", + "rand 0.8.6", "static_assertions", "subtle", ] +[[package]] +name = "pasta_curves" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ec2f82051d06ea52d7ec6a47546c592fc52392b6040e503e05a764dd10dd1de" +dependencies = [ + "blake2b_simd", + "ff 0.14.0", + "group 0.14.0", + "lazy_static 1.5.0", + "rand 0.10.3", + "static_assertions", + "subtle", + "zeroize", +] + [[package]] name = "pastey" version = "0.1.1" @@ -1929,9 +2296,9 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pem-rfc7468" -version = "0.7.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" dependencies = [ "base64ct", ] @@ -1966,7 +2333,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -1996,19 +2363,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "pkcs8" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "spki 0.7.3", +] [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ - "der", - "spki", + "der 0.8.2", + "spki 0.8.1", ] [[package]] @@ -2017,9 +2388,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", +] + +[[package]] +name = "poly1305" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" +dependencies = [ + "cpufeatures 0.3.1", + "universal-hash 0.6.1", ] [[package]] @@ -2108,6 +2489,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -2121,8 +2508,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" +dependencies = [ + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] @@ -2132,7 +2539,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -2144,6 +2561,21 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rayon" version = "1.11.0" @@ -2172,26 +2604,44 @@ checksum = "78a5191930e84973293aa5f532b513404460cd2216c1cfb76d08748c15b40b02" dependencies = [ "blake2b_simd", "byteorder", - "group", + "group 0.13.0", "hex", - "jubjub", - "pasta_curves", - "rand_core", + "jubjub 0.10.0", + "pasta_curves 0.5.1", + "rand_core 0.6.4", "serde", "thiserror 1.0.69", "zeroize", ] +[[package]] +name = "reddsa" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a70b6dbd7b3277cbd4d89ee750a30bebab3b9951ee4e166ce15c00975fe410f" +dependencies = [ + "blake2b_simd", + "byteorder", + "group 0.14.0", + "hex", + "jubjub 0.11.1", + "pasta_curves 0.6.0", + "rand_core 0.10.1", + "serde", + "thiserror 2.0.17", + "zeroize", +] + [[package]] name = "redjubjub" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b0ac1bc6bb3696d2c6f52cff8fba57238b81da8c0214ee6cd146eb8fde364e" +checksum = "19ff57b3369b472353110bea305ced2612a1380e2d2079dd26c200ed42064421" dependencies = [ - "rand_core", - "reddsa", + "rand_core 0.10.1", + "reddsa 0.6.1", "serde", - "thiserror 1.0.69", + "thiserror 2.0.17", "zeroize", ] @@ -2234,7 +2684,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -2283,11 +2733,11 @@ dependencies = [ [[package]] name = "ripemd" -version = "0.2.0-pre.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48cf93482ea998ad1302c42739bc73ab3adc574890c373ec89710e219357579" +checksum = "4dd4211456b4172d7e44261920c25acf07367c4f04bb5f5d54fc21b090d9b159" dependencies = [ - "digest 0.11.0-pre.9", + "digest 0.11.3", ] [[package]] @@ -2327,7 +2777,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn", + "syn 2.0.111", "unicode-ident", ] @@ -2392,35 +2842,37 @@ dependencies = [ [[package]] name = "sapling-crypto" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d70756ede56b5e4dd417979777bd87ddb83dfcbd0815dbf8175a9920537f8a0" +checksum = "4a2cbdcfeef20006adf72699cd466f21fe349674277cc05d3fc9b7302db7b182" dependencies = [ - "aes", + "aes 0.9.3", "bellman", "bitvec", "blake2b_simd", "blake2s_simd", - "bls12_381", + "bls12_381 0.9.0", "corez", "document-features", - "ff", - "fpe", + "ff 0.14.0", + "fpe 0.7.0", "getset", - "group", + "groth16", + "group 0.14.0", "hex", - "incrementalmerkletree", - "jubjub", + "incrementalmerkletree 0.9.0", + "jubjub 0.11.1", "lazy_static 1.5.0", "memuse", - "rand", - "rand_core", + "rand 0.10.3", + "rand_core 0.10.1", "redjubjub", "subtle", "tracing", - "zcash_note_encryption", + "zcash_note_encryption 0.5.1", "zcash_spec", - "zip32", + "zeroize", + "zip32 0.3.0", ] [[package]] @@ -2457,7 +2909,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.111", ] [[package]] @@ -2466,10 +2918,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.10", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -2480,7 +2932,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d3b203895e8f18854c828d1cf7e5710683c3abc28d79330fe5ab723ce5b76e1" dependencies = [ - "base16ct", + "base16ct 0.2.0", "k256", "once_cell", "subtle", @@ -2493,7 +2945,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "bitcoin_hashes", - "secp256k1-sys", + "secp256k1-sys 0.10.1", +] + +[[package]] +name = "secp256k1" +version = "0.33.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f404a8dab7a7a5a631e741d8699aa9c8e1d689fc26ccf897c7187565490b69" +dependencies = [ + "rand 0.9.5", + "secp256k1-sys 0.14.1", "serde", ] @@ -2506,6 +2968,15 @@ dependencies = [ "cc", ] +[[package]] +name = "secp256k1-sys" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b2992d4a3cd244539a7d5d0966aadbe5ca7fb868a5d7e38c29499b9e709bbd" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "1.0.27" @@ -2579,7 +3050,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -2590,7 +3061,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -2643,7 +3114,17 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.111", +] + +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct 1.0.0", + "serde", ] [[package]] @@ -2653,7 +3134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -2664,19 +3145,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] [[package]] name = "sha2" -version = "0.11.0-pre.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures", - "digest 0.11.0-pre.9", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] @@ -2687,7 +3168,7 @@ checksum = "359e552886ae54d1642091645980d83f7db465fd9b5b0248e3680713c1773388" dependencies = [ "bitflags", "either", - "incrementalmerkletree", + "incrementalmerkletree 0.8.2", "tracing", ] @@ -2703,17 +3184,34 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" + [[package]] name = "sinsemilla" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d268ae0ea06faafe1662e9967cd4f9022014f5eeb798e0c302c876df8b7af9c" dependencies = [ - "group", - "pasta_curves", + "group 0.13.0", + "pasta_curves 0.5.1", + "subtle", +] + +[[package]] +name = "sinsemilla" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72744738b764bb3bb7bb5dcf71b62d19c2de8a09f850a7388f6088f244037299" +dependencies = [ + "group 0.14.0", + "pasta_curves 0.6.0", "subtle", ] @@ -2736,7 +3234,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.10", +] + +[[package]] +name = "spki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef958a98b9d5da290cfc78946e9f3e61e1e62a18db0d92cac0b83cc161491a9" +dependencies = [ + "base64ct", + "der 0.8.2", ] [[package]] @@ -2769,7 +3277,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -2789,6 +3297,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap" version = "1.0.1" @@ -2834,7 +3353,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -2845,7 +3364,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3002,7 +3521,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3078,6 +3597,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "universal-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" +dependencies = [ + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "utf8parse" version = "0.2.2" @@ -3098,7 +3627,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3172,7 +3701,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.111", "wasm-bindgen-shared", ] @@ -3215,7 +3744,7 @@ checksum = "f579cdd0123ac74b94e1a4a72bd963cf30ebac343f2df347da0b8df24cdebed2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3232,22 +3761,22 @@ dependencies = [ "bech32", "blake2", "crossbeam-epoch", - "ff", + "ff 0.13.1", "getrandom 0.2.16", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.8.2", "js-sys", "miniscript", "musig2", "nonempty", - "num-bigint", - "orchard", - "pasta_curves", + "num-bigint 0.4.6", + "orchard 0.15.0", + "pasta_curves 0.5.1", "pastey", "postcard", - "rand", + "rand 0.8.6", "rstest", - "secp256k1", + "secp256k1 0.29.1", "serde", "serde-wasm-bindgen", "serde_bytes", @@ -3256,7 +3785,7 @@ dependencies = [ "strum", "wasm-bindgen", "wasm-bindgen-test", - "zcash_note_encryption", + "zcash_note_encryption 0.4.1", "zebra-chain", "zeroize", ] @@ -3270,9 +3799,9 @@ dependencies = [ "clap", "colored", "hex", - "num-bigint", + "num-bigint 0.4.6", "ptree", - "rand", + "rand 0.8.6", "serde", "serde_json", "wasm-utxo", @@ -3318,7 +3847,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3329,7 +3858,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3530,12 +4059,12 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core", + "rand_core 0.10.1", "serde", "zeroize", ] @@ -3553,9 +4082,9 @@ dependencies = [ [[package]] name = "zcash_address" -version = "0.13.0" +version = "0.14.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a854b28c07dba372f4410ea8ad62b4bf7d5c2bf8be32fc4b31bc0db6521a975" +checksum = "43e96e21e873c5a12fcd2ee6b04315e23e8ca4488cf4929c0774483dad24a995" dependencies = [ "bech32", "bs58", @@ -3567,9 +4096,9 @@ dependencies = [ [[package]] name = "zcash_encoding" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1440921903cdb86133fb9e2fe800be488015db2939a30bedb413078a1acb0306" +checksum = "b2871fd3c37eaeb635c815a9c97495553bf8237a481b9f8b37eba661764bf937" dependencies = [ "corez", "hex", @@ -3593,39 +4122,50 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77efec759c3798b6e4d829fcc762070d9b229b0f13338c40bf993b7b609c2272" dependencies = [ - "chacha20", - "chacha20poly1305", - "cipher", - "rand_core", + "chacha20 0.9.1", + "chacha20poly1305 0.10.1", + "cipher 0.4.4", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "zcash_note_encryption" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4812d133908ebf1a1c91d2411a109f63a863a152633db1fc7fbb0f774edeae30" +dependencies = [ + "chacha20 0.10.2", + "chacha20poly1305 0.11.0", + "cipher 0.5.2", + "rand_core 0.10.1", "subtle", ] [[package]] name = "zcash_primitives" -version = "0.29.0" +version = "0.31.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdbeccc05bfe63b6dee9e989c6ff5027421741562a4853c36504dd621f6a81b1" +checksum = "9e2f5bf9a1e5a16612cbbab5a112bcec36a3623d8585da0187dcb58a247bc078" dependencies = [ "blake2b_simd", - "block-buffer 0.11.0-rc.3", "corez", - "crypto-common 0.2.0-rc.1", "document-features", "equihash", - "ff", + "ff 0.14.0", "hex", - "incrementalmerkletree", - "jubjub", + "incrementalmerkletree 0.9.0", + "jubjub 0.11.1", "memuse", "nonempty", - "orchard", - "rand_core", + "orchard 0.16.0", + "rand_core 0.10.1", "redjubjub", "sapling-crypto", - "secp256k1", + "secp256k1 0.33.1", "sha2 0.10.9", "zcash_encoding", - "zcash_note_encryption", + "zcash_note_encryption 0.5.1", "zcash_protocol", "zcash_script", "zcash_transparent", @@ -3633,9 +4173,9 @@ dependencies = [ [[package]] name = "zcash_protocol" -version = "0.10.0" +version = "0.11.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2973d210e74ebd81adc50828fbbb284ab6aaa099308097c42c47dc63cf3420fc" +checksum = "98aeb25d9f741670fd63f9dbf76bca87d87c4fd32e1a7469bc4c43c4d0af09f7" dependencies = [ "corez", "document-features", @@ -3646,16 +4186,16 @@ dependencies = [ [[package]] name = "zcash_script" -version = "0.4.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f872800287d118be71bdf6fe8c869c6a6ff6fb0a5762f68fb2af54c97edf0f2" +checksum = "10106859d08a2a4119af8a0fa8db72afe35647768b562f94b7a2124adad41275" dependencies = [ "bip32", "bitflags", "bounded-vec", "hex", "ripemd 0.1.3", - "secp256k1", + "secp256k1 0.33.1", "sha1", "sha2 0.10.9", "thiserror 2.0.17", @@ -3672,9 +4212,9 @@ dependencies = [ [[package]] name = "zcash_transparent" -version = "0.9.0" +version = "0.11.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e0f8c142bed366ed5886dcfa8772ec90b5420cc127e6cdb76b6744c53a287b" +checksum = "eeb255bbf28f7a6ad34e2e94871569ed1f5604d2d3ccac2ef63e0e7ce1a8ed4b" dependencies = [ "bip32", "bs58", @@ -3684,7 +4224,7 @@ dependencies = [ "hex", "nonempty", "ripemd 0.1.3", - "secp256k1", + "secp256k1 0.33.1", "sha2 0.10.9", "subtle", "zcash_address", @@ -3692,14 +4232,14 @@ dependencies = [ "zcash_protocol", "zcash_script", "zcash_spec", - "zip32", + "zip32 0.3.0", ] [[package]] name = "zebra-chain" -version = "11.2.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa8bf71b53ef26313176def7079669e32ae12d9d86173ae14b3efb2b86b0c2f" +checksum = "32bcbe7ea2bdb0396c5de8008a9b25d15a163c8e74aa3d9b104facd66ca193a7" dependencies = [ "bech32", "bitflags", @@ -3716,30 +4256,31 @@ dependencies = [ "ed25519-zebra", "equihash", "futures", - "group", - "halo2_proofs", + "group 0.14.0", + "halo2_proofs 0.4.0", "hex", "humantime", - "incrementalmerkletree", + "incrementalmerkletree 0.9.0", "itertools", - "jubjub", + "jubjub 0.11.1", "lazy_static 1.5.0", + "mset", "num-integer", - "orchard", + "orchard 0.16.0", "primitive-types", - "rand_core", + "rand_core 0.10.1", "rayon", - "reddsa", + "reddsa 0.6.1", "redjubjub", "ripemd 0.1.3", "sapling-crypto", "schemars 1.1.0", - "secp256k1", + "secp256k1 0.33.1", "serde", "serde-big-array", "serde_with", "sha2 0.10.9", - "sinsemilla", + "sinsemilla 0.2.0", "static_assertions", "strum", "tempfile", @@ -3750,7 +4291,7 @@ dependencies = [ "zcash_address", "zcash_encoding", "zcash_history", - "zcash_note_encryption", + "zcash_note_encryption 0.5.1", "zcash_primitives", "zcash_protocol", "zcash_script", @@ -3774,7 +4315,7 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3794,7 +4335,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.111", ] [[package]] @@ -3809,3 +4350,17 @@ dependencies = [ "subtle", "zcash_spec", ] + +[[package]] +name = "zip32" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601ab4bc5f8312fa39f5411e07eb66b538687064c6e936b34eaa78f1e99ebe4d" +dependencies = [ + "bech32", + "blake2b_simd", + "memuse", + "subtle", + "zcash_spec", + "zeroize", +] diff --git a/packages/wasm-utxo/Cargo.toml b/packages/wasm-utxo/Cargo.toml index d8cb986a8f3..e155b0459af 100644 --- a/packages/wasm-utxo/Cargo.toml +++ b/packages/wasm-utxo/Cargo.toml @@ -108,9 +108,11 @@ pasta_curves = "0.5" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] # 11.2 is the first release with the `Transaction::V6` / Ironwood (`ironwood_shielded_data`) -# variant used as the txid oracle in the v6 codec tests. Native-only dev-dependency, so its -# pre-release zcash_*/orchard cohort stays out of the shipped wasm artifact. -zebra-chain = { version = "11.2", default-features = false } +# variant used as the txid oracle in the v6 codec tests; 14.0 is the first with the real NU7 +# constants (branch id 0x77190ad9, testnet height 4465026) rather than a test-only placeholder, +# which the `parity_with_zebra_chain` tests check our NU7 entry against. Native-only +# dev-dependency, so its pre-release zcash_*/orchard cohort stays out of the shipped wasm artifact. +zebra-chain = { version = "14.0", default-features = false } # `NonEmpty` is required by `orchard::Bundle::from_parts`, used only in the ironwood_build golden # test to reconstruct an orchard bundle from on-wire action data. Matches orchard's own version. nonempty = "0.11" diff --git a/packages/wasm-utxo/README.md b/packages/wasm-utxo/README.md index 4084fcfa8de..db20fe66839 100644 --- a/packages/wasm-utxo/README.md +++ b/packages/wasm-utxo/README.md @@ -28,7 +28,8 @@ This project is under active development. Zcash support includes: - **Network Upgrade Awareness**: Automatic consensus branch ID determination based on block height -- **All Network Upgrades**: Support for Overwinter, Sapling, Blossom, Heartwood, Canopy, Nu5, Nu6, and Nu6_1 +- **All Network Upgrades**: Support for Overwinter, Sapling, Blossom, Heartwood, Canopy, Nu5, Nu6, Nu6_1, Nu6_2, Nu6_3, and Nu7 +- **NU7 (ZIP-259)**: Testnet-only so far (activation block 4465026; mainnet height TBD). Version 4 transactions are invalid under NU7 per ZIP-2003, so a v4 build at or after that height is rejected rather than signed and left unbroadcastable - **Height-Based API**: Preferred `createEmpty()` method automatically selects correct consensus rules - **Parity Testing**: Validated against `zebra-chain` for accuracy across all network upgrades diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs index e2d9b705ef3..88928e9deb0 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs @@ -3861,7 +3861,9 @@ mod tests { let keys = RootWalletKeys::new(get_test_wallet_keys("test_zcash_at_height")); // Test with Nu5 activation height (mainnet) - let nu5_height = NetworkUpgrade::Nu5.mainnet_activation_height(); + let nu5_height = NetworkUpgrade::Nu5 + .mainnet_activation_height() + .expect("Nu5 has a mainnet activation height"); let result = BitGoPsbt::new_zcash_at_height( Network::Zcash, &keys, @@ -3875,7 +3877,9 @@ mod tests { let _ = result.unwrap(); // Test with Nu6 activation height - let nu6_height = NetworkUpgrade::Nu6.mainnet_activation_height(); + let nu6_height = NetworkUpgrade::Nu6 + .mainnet_activation_height() + .expect("Nu6 has a mainnet activation height"); let result = BitGoPsbt::new_zcash_at_height( Network::Zcash, &keys, @@ -3888,7 +3892,10 @@ mod tests { assert!(result.is_ok(), "Should succeed for Nu6 height"); // Test with pre-Overwinter height (should fail) - let pre_overwinter_height = NetworkUpgrade::Overwinter.mainnet_activation_height() - 1; + let pre_overwinter_height = NetworkUpgrade::Overwinter + .mainnet_activation_height() + .expect("Overwinter has a mainnet activation height") + - 1; let result = BitGoPsbt::new_zcash_at_height( Network::Zcash, &keys, @@ -3944,6 +3951,68 @@ mod tests { ); } + /// Regression test for SPT-483: before this guard, a testnet build at a post-NU7 height + /// produced a version 4 transaction carrying the NU7 branch id. It signed and queued fine, + /// then every broadcast was rejected with "transaction version 4 not supported by the + /// network upgrade Nu7" and retried forever. Fail at build time instead. + #[test] + fn test_new_zcash_at_height_rejects_v4_after_nu7_on_testnet() { + use crate::fixed_script_wallet::test_utils::get_test_wallet_keys; + use crate::zcash::NetworkUpgrade; + + let keys = RootWalletKeys::new(get_test_wallet_keys("test_zcash_nu7")); + let nu7_height = NetworkUpgrade::Nu7.testnet_activation_height(); + + // The last pre-NU7 block still builds v4 — the cutover is exact, not approximate. + let result = BitGoPsbt::new_zcash_at_height( + Network::ZcashTestnet, + &keys, + nu7_height - 1, + None, + None, + None, + None, + ); + assert!(result.is_ok(), "v4 is still valid on the block before NU7"); + + // At activation and beyond, a v4 build is refused. + for height in [nu7_height, nu7_height + 10_000] { + let err = BitGoPsbt::new_zcash_at_height( + Network::ZcashTestnet, + &keys, + height, + None, + None, + None, + None, + ) + .expect_err("v4 must be refused at or after NU7 activation"); + assert!( + err.contains("NU7") && err.contains("version 4"), + "error should name NU7 and the invalid version, got: {err}" + ); + } + + // Mainnet has no assigned NU7 height yet, so the same height stays buildable there. + assert!( + NetworkUpgrade::Nu7.mainnet_activation_height().is_none(), + "this test assumes NU7 mainnet activation is still unassigned" + ); + let result = BitGoPsbt::new_zcash_at_height( + Network::Zcash, + &keys, + nu7_height, + None, + None, + None, + None, + ); + assert!( + result.is_ok(), + "mainnet is unaffected until NU7 is scheduled" + ); + } + fn test_round_trip_with_format(format: fixtures::TxFormat, network: Network) { let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs index d6197f40b5f..957e8030a02 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs @@ -121,6 +121,12 @@ impl ZcashBitGoPsbt { } /// Create an empty Zcash PSBT with consensus branch ID resolved from `block_height`. + /// + /// Rejects a v4 build at or after NU7 activation: per ZIP-2003 a version 4 transaction is + /// invalid once NU7 activates, and the node only reports that at broadcast ("transaction + /// version 4 not supported by the network upgrade Nu7"), after the transaction has been + /// signed and queued. This path only ever builds v4/Sapling, so at those heights it has no + /// valid output to produce and must fail loudly instead. pub(crate) fn new_at_height( network: crate::Network, wallet_keys: &crate::fixed_script_wallet::RootWalletKeys, @@ -131,14 +137,26 @@ impl ZcashBitGoPsbt { expiry_height: Option, ) -> Result { let is_mainnet = matches!(network, crate::Network::Zcash); + let network_name = if is_mainnet { "mainnet" } else { "testnet" }; let consensus_branch_id = crate::zcash::branch_id_for_height(block_height, is_mainnet) .ok_or_else(|| { format!( - "Block height {} is before Overwinter activation on {}", - block_height, - if is_mainnet { "mainnet" } else { "testnet" } + "Block height {block_height} is before Overwinter activation on {network_name}" ) })?; + + if version.unwrap_or(4) == 4 { + if let Some(nu7) = crate::zcash::NetworkUpgrade::Nu7.activation_height(is_mainnet) { + if block_height >= nu7 { + return Err(format!( + "Block height {block_height} is at or after NU7 activation ({nu7}) on \ + {network_name}; version 4 transactions are invalid under NU7 (ZIP-2003). \ + Build a v6 (Ironwood) transaction with new_v6_at_height instead" + )); + } + } + } + Ok(Self::new( network, wallet_keys, @@ -704,14 +722,21 @@ impl ZcashBitGoPsbt { expiry_height: Option, ) -> Result { let is_mainnet = matches!(network, crate::Network::Zcash); - let nu6_3 = crate::zcash::NetworkUpgrade::Nu6_3.activation_height(is_mainnet); + let network_name = if is_mainnet { "mainnet" } else { "testnet" }; + // NU6.3 has an assigned height on both networks today. Treat an unassigned one as + // "not activated here yet" rather than silently skipping the check. + let nu6_3 = crate::zcash::NetworkUpgrade::Nu6_3 + .activation_height(is_mainnet) + .ok_or_else(|| { + format!( + "NU6.3 (Ironwood) has no assigned activation height on {network_name}; \ + v6 transactions cannot be built there" + ) + })?; if block_height < nu6_3 { return Err(format!( - "Block height {} is before NU6.3 (Ironwood) activation ({}) on {}; \ - v6 transactions are not valid before then", - block_height, - nu6_3, - if is_mainnet { "mainnet" } else { "testnet" } + "Block height {block_height} is before NU6.3 (Ironwood) activation ({nu6_3}) on \ + {network_name}; v6 transactions are not valid before then" )); } let consensus_branch_id = crate::zcash::branch_id_for_height(block_height, is_mainnet) @@ -2561,17 +2586,27 @@ mod ironwood_v6_tests { use orchard::value::{NoteValue, ValueCommitment}; use orchard::Action as OrchardAction; + // zebra-chain links its own orchard release, a different crate version than ours, so its + // `Action` cannot be fed to our `zcash_note_encryption` directly. Round-trip through the + // canonical byte encoding of each field to rebuild the action against our orchard. let zebra_action = zebra .ironwood_actions() .next() .expect("one ironwood action"); - let cv_bytes: [u8; 32] = zebra_action.cv.into(); - let nf_bytes: [u8; 32] = zebra_action.nullifier.into(); - let rk_bytes: [u8; 32] = zebra_action.rk.into(); - let cmx_bytes: [u8; 32] = zebra_action.cm_x.into(); - let epk_bytes: [u8; 32] = zebra_action.ephemeral_key.into(); - let enc_bytes: [u8; 580] = zebra_action.enc_ciphertext.into(); - let out_bytes: [u8; 80] = zebra_action.out_ciphertext.into(); + let cv_bytes: [u8; 32] = zebra_action.cv_net().to_bytes(); + let nf_bytes: [u8; 32] = zebra_action.nullifier().to_bytes(); + let rk_bytes: [u8; 32] = zebra_action.rk().into(); + let cmx_bytes: [u8; 32] = zebra_action.cmx().to_bytes(); + let encrypted = zebra_action.encrypted_note(); + let epk_bytes: [u8; 32] = encrypted.epk_bytes; + // zebra's newer zcash_note_encryption wraps `enc_ciphertext` in `NoteBytesData`; take the + // inner bytes so they land in our crate version's plain-array field. + let enc_bytes: [u8; 580] = encrypted + .enc_ciphertext + .as_ref() + .try_into() + .expect("enc_ciphertext is 580 bytes"); + let out_bytes: [u8; 80] = encrypted.out_ciphertext; let cv_net = Option::from(ValueCommitment::from_bytes(&cv_bytes)).expect("valid cv_net"); let rk = VerificationKey::::try_from(rk_bytes).expect("valid rk"); diff --git a/packages/wasm-utxo/src/zcash/mod.rs b/packages/wasm-utxo/src/zcash/mod.rs index 806dc3209e7..60c537bd502 100644 --- a/packages/wasm-utxo/src/zcash/mod.rs +++ b/packages/wasm-utxo/src/zcash/mod.rs @@ -32,13 +32,17 @@ pub enum NetworkUpgrade { Nu6_1, Nu6_2, Nu6_3, + Nu7, } /// Parameters for a single network upgrade #[derive(Debug, Clone, Copy)] pub struct UpgradeParams { pub branch_id: u32, - pub mainnet_activation_height: u32, + /// Mainnet activation height, or `None` when the upgrade has no assigned mainnet height + /// yet (NU7 — ZIP-259 lists it as TBD). An upgrade with no height on a network is never + /// active there, so a `None` here keeps mainnet on the previous upgrade's rules. + pub mainnet_activation_height: Option, pub testnet_activation_height: u32, } @@ -55,6 +59,7 @@ impl NetworkUpgrade { NetworkUpgrade::Nu6_1, NetworkUpgrade::Nu6_2, NetworkUpgrade::Nu6_3, + NetworkUpgrade::Nu7, ]; /// Get the parameters for this network upgrade @@ -62,59 +67,68 @@ impl NetworkUpgrade { match self { NetworkUpgrade::Overwinter => UpgradeParams { branch_id: 0x5ba81b19, - mainnet_activation_height: 347500, + mainnet_activation_height: Some(347500), testnet_activation_height: 207500, }, NetworkUpgrade::Sapling => UpgradeParams { branch_id: 0x76b809bb, - mainnet_activation_height: 419200, + mainnet_activation_height: Some(419200), testnet_activation_height: 280000, }, NetworkUpgrade::Blossom => UpgradeParams { branch_id: 0x2bb40e60, - mainnet_activation_height: 653600, + mainnet_activation_height: Some(653600), testnet_activation_height: 584000, }, NetworkUpgrade::Heartwood => UpgradeParams { branch_id: 0xf5b9230b, - mainnet_activation_height: 903000, + mainnet_activation_height: Some(903000), testnet_activation_height: 903800, }, NetworkUpgrade::Canopy => UpgradeParams { branch_id: 0xe9ff75a6, - mainnet_activation_height: 1046400, + mainnet_activation_height: Some(1046400), testnet_activation_height: 1028500, }, NetworkUpgrade::Nu5 => UpgradeParams { branch_id: 0xc2d6d0b4, - mainnet_activation_height: 1687104, + mainnet_activation_height: Some(1687104), testnet_activation_height: 1842420, }, // https://zips.z.cash/zip-0253 NetworkUpgrade::Nu6 => UpgradeParams { branch_id: 0xc8e71055, - mainnet_activation_height: 2726400, + mainnet_activation_height: Some(2726400), testnet_activation_height: 2976000, }, // https://zips.z.cash/zip-0254 NetworkUpgrade::Nu6_1 => UpgradeParams { branch_id: 0x4dec4df0, - mainnet_activation_height: 3146400, + mainnet_activation_height: Some(3146400), testnet_activation_height: 3536500, }, // NU6.2: emergency hard fork re-enabling Orchard with the corrected circuit // after GHSA-ghc3-g8w4-whf9. NetworkUpgrade::Nu6_2 => UpgradeParams { branch_id: 0x5437f330, - mainnet_activation_height: 3364600, + mainnet_activation_height: Some(3364600), testnet_activation_height: 4052000, }, // https://zips.z.cash/zip-0255 NetworkUpgrade::Nu6_3 => UpgradeParams { branch_id: 0x37a5165b, - mainnet_activation_height: 3428143, + mainnet_activation_height: Some(3428143), testnet_activation_height: 4134000, }, + // https://zips.z.cash/zip-0259 — NU7. Per ZIP-2003 version 4 transactions become + // invalid once NU7 activates; only v5 (ZIP-225) and v6 (ZIP-229) stay valid. The + // mainnet activation height is still TBD in ZIP-259, so NU7 is testnet-only here + // and mainnet keeps resolving to NU6.3 until that height is published. + NetworkUpgrade::Nu7 => UpgradeParams { + branch_id: 0x77190ad9, + mainnet_activation_height: None, + testnet_activation_height: 4465026, + }, } } @@ -123,8 +137,8 @@ impl NetworkUpgrade { self.params().branch_id } - /// Get the mainnet activation height - pub const fn mainnet_activation_height(self) -> u32 { + /// Get the mainnet activation height, or `None` if it has not been assigned yet. + pub const fn mainnet_activation_height(self) -> Option { self.params().mainnet_activation_height } @@ -133,12 +147,13 @@ impl NetworkUpgrade { self.params().testnet_activation_height } - /// Get the activation height for the specified network - pub const fn activation_height(self, is_mainnet: bool) -> u32 { + /// Get the activation height for the specified network, or `None` if this upgrade has no + /// assigned activation height there yet. + pub const fn activation_height(self, is_mainnet: bool) -> Option { if is_mainnet { self.mainnet_activation_height() } else { - self.testnet_activation_height() + Some(self.testnet_activation_height()) } } } @@ -146,12 +161,19 @@ impl NetworkUpgrade { /// Get the network upgrade active at a given block height /// /// Returns `None` if the height is before Overwinter activation. +/// +/// An upgrade with no assigned activation height on this network (NU7 on mainnet) is never +/// reported as active. pub fn network_upgrade_at_height(height: u32, is_mainnet: bool) -> Option { // Iterate in reverse chronological order NetworkUpgrade::ALL .iter() .rev() - .find(|&&upgrade| height >= upgrade.activation_height(is_mainnet)) + .find(|&&upgrade| { + upgrade + .activation_height(is_mainnet) + .is_some_and(|h| height >= h) + }) .copied() } @@ -168,13 +190,35 @@ mod tests { #[test] fn test_upgrade_ordering() { - // Verify chronological ordering + // Mainnet: assigned heights must be strictly increasing, and no upgrade may carry a + // height after an earlier one with none — `ALL` is chronological, so a gap followed by + // a height means a mis-ordered entry. + let mut last: Option = None; + let mut seen_unassigned = false; + for &upgrade in NetworkUpgrade::ALL { + match upgrade.mainnet_activation_height() { + Some(height) => { + assert!( + !seen_unassigned, + "{:?} has a mainnet activation height after an earlier upgrade with none", + upgrade + ); + if let Some(prev) = last { + assert!(prev < height, "{:?} is out of order on mainnet", upgrade); + } + last = Some(height); + } + None => seen_unassigned = true, + } + } + + // Testnet: every upgrade has an assigned height, so ordering is unconditional. for i in 1..NetworkUpgrade::ALL.len() { let prev = NetworkUpgrade::ALL[i - 1]; let curr = NetworkUpgrade::ALL[i]; assert!( - prev.mainnet_activation_height() < curr.mainnet_activation_height(), - "{:?} should activate before {:?} on mainnet", + prev.testnet_activation_height() < curr.testnet_activation_height(), + "{:?} should activate before {:?} on testnet", prev, curr ); @@ -205,6 +249,7 @@ mod tests { NetworkUpgrade::Nu6_1 => ZebraNetworkUpgrade::Nu6_1, NetworkUpgrade::Nu6_2 => ZebraNetworkUpgrade::Nu6_2, NetworkUpgrade::Nu6_3 => ZebraNetworkUpgrade::Nu6_3, + NetworkUpgrade::Nu7 => ZebraNetworkUpgrade::Nu7, } } @@ -224,8 +269,7 @@ mod tests { ZebraNetworkUpgrade::Nu6_1 => Some(NetworkUpgrade::Nu6_1), ZebraNetworkUpgrade::Nu6_2 => Some(NetworkUpgrade::Nu6_2), ZebraNetworkUpgrade::Nu6_3 => Some(NetworkUpgrade::Nu6_3), - #[cfg(any(test, feature = "zebra-test"))] - ZebraNetworkUpgrade::Nu7 => None, + ZebraNetworkUpgrade::Nu7 => Some(NetworkUpgrade::Nu7), #[cfg(zcash_unstable = "zfuture")] ZebraNetworkUpgrade::ZFuture => None, } @@ -240,11 +284,6 @@ mod tests { continue; } - // Skip test-only upgrades - #[cfg(any(test, feature = "zebra-test"))] - if matches!(zebra_upgrade, ZebraNetworkUpgrade::Nu7) { - continue; - } #[cfg(zcash_unstable = "zfuture")] if matches!(zebra_upgrade, ZebraNetworkUpgrade::ZFuture) { continue; @@ -301,16 +340,17 @@ mod tests { fn test_mainnet_heights_match_zebra() { let network = ZebraNetwork::Mainnet; for &upgrade in NetworkUpgrade::ALL { - let zebra_upgrade = to_zebra_upgrade(upgrade); - let expected = zebra_upgrade + let expected = to_zebra_upgrade(upgrade) .activation_height(&network) - .map(|h| h.0) - .expect("upgrade should have mainnet activation height"); + .map(|h| h.0); + // Compared as `Option`, so an upgrade whose mainnet height is unassigned (NU7 — + // TBD in ZIP-259) must stay unassigned here, and this test starts failing the + // moment zebra publishes one. assert_eq!( upgrade.mainnet_activation_height(), expected, - "{:?} mainnet activation height mismatch: ours={}, zebra={}", + "{:?} mainnet activation height mismatch: ours={:?}, zebra={:?}", upgrade, upgrade.mainnet_activation_height(), expected From 2b3b3108b3e16556f35ec07b157151a969b64336 Mon Sep 17 00:00:00 2001 From: Hrishikesh Jain Date: Tue, 6 Oct 2026 17:43:27 +0530 Subject: [PATCH 2/2] fix(wasm-utxo): keep halo2 multicore on under orchard-proving The zebra-chain 11.2 -> 14 bump broke `cargo clippy --all-features`: halo2_proofs 0.3.2 does not compile with `multicore` off, and nothing was turning it on any more. orchard takes halo2 with default features disabled, so `multicore` never came from our own dependency edge. It was supplied by accident: zebra-chain 11.2 resolved to the same orchard 0.15 we use, and cargo unified its feature set with ours. zebra-chain 14 moved to orchard 0.16, so the two graphs no longer unify and our halo2 was left without rayon. Declare halo2_proofs as an optional dependency and have the `orchard-proving` feature enable `halo2_proofs/multicore` explicitly, so the proving build states the requirement itself instead of relying on a dev-dependency's resolution. Refs: SPT-483 --- packages/wasm-utxo/Cargo.lock | 1 + packages/wasm-utxo/Cargo.toml | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/wasm-utxo/Cargo.lock b/packages/wasm-utxo/Cargo.lock index 696105339fa..dcb111325f1 100644 --- a/packages/wasm-utxo/Cargo.lock +++ b/packages/wasm-utxo/Cargo.lock @@ -3763,6 +3763,7 @@ dependencies = [ "crossbeam-epoch", "ff 0.13.1", "getrandom 0.2.16", + "halo2_proofs 0.3.2", "hex", "incrementalmerkletree 0.8.2", "js-sys", diff --git a/packages/wasm-utxo/Cargo.toml b/packages/wasm-utxo/Cargo.toml index e155b0459af..764d2c9f9d3 100644 --- a/packages/wasm-utxo/Cargo.toml +++ b/packages/wasm-utxo/Cargo.toml @@ -28,7 +28,12 @@ inspect = ["dep:num-bigint", "dep:serde_json", "dep:hex"] # circuit synthesis + proving-key generation), so it's opt-in and off by default — the shipped # WASM build (browser consumers) must not link the circuit. Standalone tooling (the CLI) enables # it explicitly. -orchard-proving = ["orchard/circuit"] +# `halo2_proofs/multicore` is enabled explicitly: orchard takes halo2 with default features off, +# and halo2 0.3.2's rayon-free (`multicore`-off) configuration does not compile. Previously this +# came in by accident — zebra-chain 11.2 pulled the same orchard release we use, and its feature +# set unified onto ours. zebra-chain 14 moved to a newer orchard, so our halo2 is no longer +# unified with zebra's and has to ask for the feature itself. +orchard-proving = ["orchard/circuit", "dep:halo2_proofs", "halo2_proofs/multicore"] [dependencies] wasm-bindgen = "0.2" @@ -59,6 +64,9 @@ orchard = { version = "0.15", default-features = false, features = ["std"] } # `IronwoodDomain`. Version pinned to match orchard 0.15's own dependency so the `Domain` impl and # this crate's `NoteEncryption` agree on wire types. zcash_note_encryption = "0.4" +# Not used directly — declared only so `orchard-proving` can turn on halo2's `multicore` +# feature (see that feature's comment). Version must match what orchard 0.15 resolves to. +halo2_proofs = { version = "0.3.2", optional = true } # Scrub the copies of the user's secret key made while deriving the client-managed `ovk`, so the # "the ovk never leaves this call" guarantee also covers what is left behind in freed memory. zeroize = "1.8"