From 5b4e2528a3fc1db257b102345cd09305d20dda35 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Tue, 4 Nov 2025 20:51:51 -0700 Subject: [PATCH 001/263] Post-release update of `cargo vet` metadata. --- supply-chain/imports.lock | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 1d5d8b180f..2209481028 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1,18 +1,6 @@ # cargo-vet imports lock -[[unpublished.pczt]] -version = "0.5.0" -audited_as = "0.4.0" - -[[unpublished.zcash_client_backend]] -version = "0.21.0" -audited_as = "0.20.0" - -[[unpublished.zcash_client_sqlite]] -version = "0.19.0" -audited_as = "0.18.9" - [[publisher.bumpalo]] version = "3.16.0" when = "2024-04-08" @@ -97,11 +85,11 @@ user-login = "nuttycom" user-name = "Kris Nuttycombe" [[publisher.pczt]] -version = "0.4.0" -when = "2025-09-25" -user-id = 6289 -user-login = "str4d" -user-name = "Jack Grigg" +version = "0.5.0" +when = "2025-11-05" +user-id = 169181 +user-login = "nuttycom" +user-name = "Kris Nuttycombe" [[publisher.sapling-crypto]] version = "0.5.0" @@ -453,15 +441,15 @@ user-login = "nuttycom" user-name = "Kris Nuttycombe" [[publisher.zcash_client_backend]] -version = "0.20.0" -when = "2025-09-25" -user-id = 6289 -user-login = "str4d" -user-name = "Jack Grigg" +version = "0.21.0" +when = "2025-11-05" +user-id = 169181 +user-login = "nuttycom" +user-name = "Kris Nuttycombe" [[publisher.zcash_client_sqlite]] -version = "0.18.9" -when = "2025-10-23" +version = "0.19.0" +when = "2025-11-05" user-id = 169181 user-login = "nuttycom" user-name = "Kris Nuttycombe" From 3639a08c14e3cc1ad441fc6fa8193a4ae6cc9bfe Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 6 Nov 2025 14:09:34 +0100 Subject: [PATCH 002/263] refactor(zcash_encoding): expose a reverse-hex decoder --- Cargo.lock | 1746 ++++++++++++------------- components/zcash_encoding/Cargo.toml | 1 + components/zcash_encoding/src/lib.rs | 12 + components/zcash_protocol/Cargo.toml | 1 + components/zcash_protocol/src/txid.rs | 6 +- 5 files changed, 834 insertions(+), 932 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c80e6c2e4..ffd9eeb314 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,21 +1,19 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "addr2line" -version = "0.21.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" @@ -41,12 +39,12 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.15", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -54,9 +52,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -72,9 +70,9 @@ dependencies = [ [[package]] name = "ambassador" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b27ba24e4d8a188489d5a03c7fabc167a60809a383cdb4d15feb37479cd2a48" +checksum = "e68de4cdc6006162265d0957edb4a860fe4e711b1dc17a5746fd95f952f08285" dependencies = [ "itertools 0.10.5", "proc-macro2", @@ -84,21 +82,23 @@ dependencies = [ [[package]] name = "amplify" -version = "4.6.0" +version = "4.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e711289a6cb28171b4f0e6c8019c69ff9476050508dc082167575d458ff74d0" +checksum = "3f7fb4ac7c881e54a8e7015e399b6112a2a5bc958b6c89ac510840ff20273b31" dependencies = [ "amplify_derive", "amplify_num", "ascii", + "getrandom 0.2.16", + "getrandom 0.3.4", "wasm-bindgen", ] [[package]] name = "amplify_derive" -version = "4.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759dcbfaf94d838367a86d493ec34ccc8aa6fe365cb7880d6bf89006de24d9c1" +checksum = "2a6309e6b8d89b36b9f959b7a8fa093583b94922a0f6438a24fb08936de4d428" dependencies = [ "amplify_syn", "proc-macro2", @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "amplify_num" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c009c5c4de814911b177e2ea59e4930bb918978ed3cce4900d846a6ceb0838" +checksum = "99bcb75a2982047f733547042fc3968c0f460dfcf7d90b90dea3b2744580e9ad" dependencies = [ "wasm-bindgen", ] @@ -126,12 +126,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -149,27 +143,27 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "arti-client" @@ -179,7 +173,7 @@ checksum = "0a79ca5ce63b36033a5ccbfbcc7f919cbd93db61708543aa5e2e4917856205e7" dependencies = [ "async-trait", "cfg-if", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "educe", @@ -194,7 +188,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", "time", "tor-async-utils", "tor-basic-utils", @@ -238,7 +232,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -249,7 +243,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", "synstructure", ] @@ -261,7 +255,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -272,29 +266,26 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.11" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" dependencies = [ - "flate2", + "compression-codecs", + "compression-core", "futures-core", "futures-io", - "memchr", "pin-project-lite", - "xz2", - "zstd", - "zstd-safe", ] [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -333,9 +324,9 @@ checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "atomic" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" dependencies = [ "bytemuck", ] @@ -348,23 +339,23 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-link 0.2.1", ] [[package]] @@ -431,7 +422,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2", "rand 0.8.5", - "sha2 0.10.8", + "sha2 0.10.9", "unicode-normalization", "zeroize", ] @@ -454,18 +445,18 @@ dependencies = [ [[package]] name = "bit-set" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" @@ -475,9 +466,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bitvec" @@ -493,9 +484,9 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" dependencies = [ "arrayref", "arrayvec", @@ -504,9 +495,9 @@ dependencies = [ [[package]] name = "blake2s_simd" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" +checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" dependencies = [ "arrayref", "arrayvec", @@ -521,7 +512,7 @@ checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -561,7 +552,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09dc0086e469182132244e9b8d313a0742e1132da43a08c24b9dd3c18e0faf3a" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -570,26 +561,26 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.8", + "sha2 0.10.9", "tinyvec", ] [[package]] name = "bstr" -version = "1.11.3" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", - "regex-automata 0.4.9", + "regex-automata", "serde", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "by_address" @@ -599,9 +590,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.16.3" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -638,10 +629,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.2.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -649,9 +641,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" @@ -679,15 +671,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -730,18 +721,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstyle", "clap_lex", @@ -749,15 +740,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "coarsetime" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b3839cf01bb7960114be3ccf2340f541b6d0c81f8690b007b2b39f750f7e5d" +checksum = "91849686042de1b41cd81490edc83afbcb0abe5a9b6f2c4114f23ce8cca1bcf4" dependencies = [ "libc", "wasix", @@ -766,9 +757,31 @@ dependencies = [ [[package]] name = "cobs" -version = "0.2.3" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.17", +] + +[[package]] +name = "compression-codecs" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" +dependencies = [ + "compression-core", + "flate2", + "liblzma", + "zstd", + "zstd-safe", +] + +[[package]] +name = "compression-core" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "concurrent-queue" @@ -787,9 +800,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "convert_case" @@ -811,9 +824,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core2" @@ -826,27 +839,27 @@ dependencies = [ [[package]] name = "cpp_demangle" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" dependencies = [ "cfg-if", ] [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -941,9 +954,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -960,25 +973,24 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" @@ -1045,14 +1057,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "daggy" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91a9304e55e9d601a39ae4deaba85406d5c0980e106f65afcf0460e9af1e7602" +checksum = "70def8d72740e44d9f676d8dab2c933a236663d86dd24319b57a2bed4d694774" dependencies = [ "petgraph", ] @@ -1069,12 +1081,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -1093,16 +1105,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -1118,20 +1130,20 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core 0.20.10", + "darling_core 0.21.3", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "debugid" @@ -1144,9 +1156,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -1177,42 +1189,14 @@ dependencies = [ "serde", ] -[[package]] -name = "derive-deftly" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f9bc3564f74be6c35d49a7efee54380d7946ccc631323067f33fabb9246027" -dependencies = [ - "derive-deftly-macros 0.14.2", - "heck", -] - [[package]] name = "derive-deftly" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d308ebe4b10924331bd079044b418da7b227d724d3e2408567a47ad7c3da2a0" dependencies = [ - "derive-deftly-macros 1.3.0", - "heck", -] - -[[package]] -name = "derive-deftly-macros" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b84d32b18d9a256d81e4fec2e4cfd0ab6dde5e5ff49be1713ae0adbd0060c2" -dependencies = [ + "derive-deftly-macros", "heck", - "indexmap 2.12.0", - "itertools 0.13.0", - "proc-macro-crate", - "proc-macro2", - "quote", - "sha3", - "strum 0.26.3", - "syn 2.0.100", - "void", ] [[package]] @@ -1228,8 +1212,8 @@ dependencies = [ "proc-macro2", "quote", "sha3", - "strum 0.27.2", - "syn 2.0.100", + "strum", + "syn 2.0.109", "void", ] @@ -1282,7 +1266,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", "unicode-xid", ] @@ -1315,16 +1299,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" dependencies = [ - "dirs-sys 0.5.0", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys 0.4.1", + "dirs-sys", ] [[package]] @@ -1333,19 +1308,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys 0.5.0", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users 0.4.5", - "windows-sys 0.48.0", + "dirs-sys", ] [[package]] @@ -1356,41 +1319,41 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.0", - "windows-sys 0.60.2", + "redox_users", + "windows-sys 0.61.2", ] [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "document-features" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ "litrs", ] [[package]] name = "downcast-rs" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8a8b81cacc08888170eef4d13b775126db426d0b348bee9d18c2c1eaf123cf" +checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "dynosaur" @@ -1409,7 +1372,7 @@ checksum = "0b0713d5c1d52e774c5cd7bb8b043d7c0fc4f921abfb678556140bfbe6ab2364" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -1447,7 +1410,7 @@ dependencies = [ "merlin", "rand_core 0.6.4", "serde", - "sha2 0.10.8", + "sha2 0.10.9", "subtle", "zeroize", ] @@ -1466,9 +1429,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" @@ -1511,7 +1474,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -1523,7 +1486,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -1549,7 +1512,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -1565,9 +1528,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -1576,14 +1539,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -1613,15 +1576,15 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "bitvec", "rand_core 0.6.4", @@ -1640,25 +1603,31 @@ version = "0.10.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" dependencies = [ - "atomic 0.6.0", + "atomic 0.6.1", "serde", - "toml 0.8.19", + "toml 0.8.23", "uncased", "version_check", ] [[package]] name = "filetime" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "findshlibs" version = "0.10.2" @@ -1682,15 +1651,15 @@ dependencies = [ [[package]] name = "fixedbitset" -version = "0.4.2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.0.30" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -1735,11 +1704,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a157b06319bb4868718fd20177a0d3373d465e429d89cd0ee493d9f5918902" dependencies = [ "derive_builder_fork_arti", - "dirs 6.0.0", + "dirs", "libc", "pwd-grp", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", "walkdir", ] @@ -1761,9 +1730,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1792,9 +1761,9 @@ checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1815,7 +1784,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -1825,7 +1794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.25", + "rustls 0.23.35", "rustls-pki-types", ] @@ -1861,9 +1830,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1872,13 +1841,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1888,9 +1859,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1902,14 +1875,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob-match" @@ -1951,9 +1924,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -1970,11 +1943,13 @@ dependencies = [ [[package]] name = "half" -version = "2.2.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ + "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -2017,14 +1992,15 @@ dependencies = [ [[package]] name = "halo2_proofs" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b867a8d9bbb85fca76fff60652b5cd19b853a1c4d0665cb89bee68b18d2caf0" +checksum = "019561b5f3be60731e7b72f3f7878c5badb4174362d860b03d3cf64cb47f90db" dependencies = [ "blake2b_simd", "ff", "group", "halo2_legacy_pdqsort", + "indexmap 1.9.3", "maybe-rayon", "pasta_curves", "rand_core 0.6.4", @@ -2039,9 +2015,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "foldhash", ] @@ -2058,7 +2034,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -2069,9 +2045,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -2108,11 +2084,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2123,9 +2099,9 @@ checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2" [[package]] name = "http" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -2144,12 +2120,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -2169,9 +2145,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "humantime-serde" @@ -2194,13 +2170,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2", "http", "http-body", @@ -2208,6 +2185,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -2215,9 +2193,9 @@ dependencies = [ [[package]] name = "hyper-timeout" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ "hyper", "hyper-util", @@ -2228,19 +2206,20 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "bytes", "futures-channel", + "futures-core", "futures-util", "http", "http-body", "hyper", "libc", "pin-project-lite", - "socket2 0.5.9", + "socket2", "tokio", "tower-service", "tracing", @@ -2248,16 +2227,17 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core 0.62.2", ] [[package]] @@ -2344,7 +2324,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "inotify-sys", "libc", ] @@ -2360,28 +2340,31 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ "generic-array", ] [[package]] name = "inventory" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +dependencies = [ + "rustversion", +] [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2413,25 +2396,27 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2451,27 +2436,27 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] [[package]] name = "known-folders" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4397c789f2709d23cfcb703b316e0766a8d4b17db2d47b0ab096ef6047cae1d8" +checksum = "d463f34ca3c400fde3a054da0e0b8c6ffa21e4590922f3e18281bb5eeef4cbdc" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "kqueue" -version = "1.0.8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", @@ -2502,19 +2487,39 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "liblzma" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c36d08cad03a3fbe2c4e7bb3a9e84c57e4ee4135ed0b065cade3d98480c648" +dependencies = [ + "liblzma-sys", +] + +[[package]] +name = "liblzma-sys" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b9596486f6d60c3bbe644c0e1be1aa6ccc472ad630fe8927b456973d7cb736" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "libm" -version = "0.2.8" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "libc", "redox_syscall", ] @@ -2530,12 +2535,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -2544,44 +2543,32 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litrs" -version = "0.4.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.21" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "lzma-sys" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" -dependencies = [ - "cc", - "libc", - "pkg-config", -] +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -2596,15 +2583,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] @@ -2635,21 +2622,20 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler", + "adler2", + "simd-adler32", ] [[package]] name = "minreq" -version = "2.12.0" +version = "2.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763d142cdff44aaadd9268bebddb156ef6c65a0e13486bb81673cf2d8739f9b0" +checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" dependencies = [ - "log", - "once_cell", "rustls 0.21.12", "rustls-webpki 0.101.7", "webpki-roots 0.25.4", @@ -2657,32 +2643,21 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "mio" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" [[package]] name = "nix" @@ -2719,20 +2694,19 @@ checksum = "549e471b99ccaf2f89101bec68f4d244457d5a95a9c3d0672e9564124397741d" [[package]] name = "notify" -version = "8.0.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.0", - "filetime", + "bitflags 2.10.0", "inotify", "kqueue", "libc", "log", - "mio 1.0.3", + "mio", "notify-types", "walkdir", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2752,19 +2726,18 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "overload", - "winapi", + "windows-sys 0.61.2", ] [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -2772,11 +2745,10 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "82c79c15c05d4bf82b6f5ef163104cc81a760d8e874d38ac50ab67c8877b647b" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", @@ -2835,9 +2807,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ "hermit-abi", "libc", @@ -2845,23 +2817,24 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -2870,7 +2843,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", ] [[package]] @@ -2885,18 +2858,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oneshot-fused-workaround" @@ -2909,9 +2882,9 @@ dependencies = [ [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "opaque-debug" @@ -2979,12 +2952,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "p256" version = "0.13.2" @@ -2994,19 +2961,19 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] name = "p384" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -3020,7 +2987,7 @@ dependencies = [ "elliptic-curve", "primeorder", "rand_core 0.6.4", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -3034,15 +3001,15 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -3050,15 +3017,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -3125,7 +3092,7 @@ dependencies = [ "secp256k1", "serde", "serde_with", - "sha2 0.10.8", + "sha2 0.10.9", "shardtree", "zcash_note_encryption", "zcash_primitives", @@ -3147,15 +3114,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "petgraph" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ "fixedbitset", "indexmap 2.12.0", @@ -3192,7 +3159,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -3206,29 +3173,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -3259,15 +3226,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -3278,15 +3245,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -3314,14 +3281,14 @@ dependencies = [ "parking_lot", "pin-project", "static_assertions", - "thiserror 1.0.63", + "thiserror 1.0.69", ] [[package]] name = "postcard" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" dependencies = [ "cobs", "embedded-io 0.4.0", @@ -3355,23 +3322,26 @@ dependencies = [ "spin 0.10.0", "symbolic-demangle", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -3395,23 +3365,22 @@ dependencies = [ [[package]] name = "priority-queue" -version = "2.1.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714c75db297bc88a63783ffc6ab9f830698a6705aa0201416931759ef4c8183d" +checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ - "autocfg", "equivalent", "indexmap 2.12.0", + "serde", ] [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "toml_edit 0.23.7", ] [[package]] @@ -3433,7 +3402,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -3447,19 +3416,19 @@ dependencies = [ [[package]] name = "proptest" -version = "1.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.9.0", + "bitflags 2.10.0", "lazy_static", "num-traits", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax 0.8.5", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -3491,7 +3460,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.100", + "syn 2.0.109", "tempfile", ] @@ -3505,7 +3474,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -3519,14 +3488,14 @@ dependencies = [ [[package]] name = "pwd-grp" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94fdf3867b7f2889a736f0022ea9386766280d2cca4bdbe41629ada9e4f3b8f" +checksum = "0e2023f41b5fcb7c30eb5300a5733edfaa9e0e0d502d51b586f65633fd39e40c" dependencies = [ - "derive-deftly 0.14.2", + "derive-deftly", "libc", "paste", - "thiserror 1.0.63", + "thiserror 2.0.17", ] [[package]] @@ -3546,9 +3515,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -3612,7 +3581,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -3656,9 +3625,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -3666,9 +3635,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3697,7 +3666,7 @@ dependencies = [ "pasta_curves", "rand_core 0.6.4", "serde", - "thiserror 1.0.63", + "thiserror 1.0.69", "zeroize", ] @@ -3709,84 +3678,78 @@ checksum = "89b0ac1bc6bb3696d2c6f52cff8fba57238b81da8c0214ee6cd146eb8fde364e" dependencies = [ "rand_core 0.6.4", "reddsa", - "thiserror 1.0.63", + "thiserror 1.0.69", "zeroize", ] [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", - "thiserror 1.0.63", + "thiserror 2.0.17", ] [[package]] -name = "redox_users" -version = "0.5.0" +name = "ref-cast" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ - "getrandom 0.2.15", - "libredox", - "thiserror 2.0.12", + "ref-cast-impl", ] [[package]] -name = "regex" -version = "1.11.1" +name = "ref-cast-impl" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "proc-macro2", + "quote", + "syn 2.0.109", ] [[package]] -name = "regex-automata" -version = "0.1.10" +name = "regex" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ - "regex-syntax 0.6.29", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "retry-error" @@ -3806,9 +3769,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.50" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" dependencies = [ "bytemuck", ] @@ -3821,7 +3784,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -3847,9 +3810,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" dependencies = [ "const-oid", "digest 0.10.7", @@ -3859,7 +3822,7 @@ dependencies = [ "pkcs1", "pkcs8", "rand_core 0.6.4", - "sha2 0.10.8", + "sha2 0.10.9", "signature", "spki", "subtle", @@ -3872,7 +3835,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -3884,9 +3847,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "35affe401787a9bd846712274d97654355d21b2a2c092a3139aabe31e9022282" dependencies = [ "arrayvec", "num-traits", @@ -3895,15 +3858,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -3917,30 +3880,17 @@ dependencies = [ "nom", ] -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.9.0", - "errno", - "libc", - "linux-raw-sys 0.4.13", - "windows-sys 0.52.0", -] - [[package]] name = "rustix" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.60.2", + "linux-raw-sys", + "windows-sys 0.61.2", ] [[package]] @@ -3957,24 +3907,27 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.1", + "rustls-webpki 0.103.8", "subtle", "zeroize", ] [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" @@ -3988,9 +3941,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.1" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "ring", "rustls-pki-types", @@ -3999,15 +3952,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -4017,9 +3970,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "safelog" @@ -4031,7 +3984,7 @@ dependencies = [ "educe", "either", "fluid-let", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -4086,6 +4039,30 @@ dependencies = [ "zip32", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "schemerz" version = "0.2.0" @@ -4095,7 +4072,7 @@ dependencies = [ "daggy", "indexmap 1.9.3", "log", - "thiserror 1.0.63", + "thiserror 1.0.69", "uuid", ] @@ -4170,9 +4147,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" @@ -4211,34 +4188,37 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "serde_ignored" -version = "0.1.10" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf" +checksum = "115dffd5f3853e06e746965a20dcbae6ee747ae30b543d91b0e089668bb07798" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", + "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -4254,17 +4234,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", "indexmap 2.12.0", - "serde", - "serde_derive", + "schemars 0.9.0", + "schemars 1.1.0", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -4272,21 +4253,21 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" dependencies = [ - "darling 0.20.10", + "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -4295,9 +4276,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -4341,7 +4322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e95dcd06bc1bb3f86ed9db1e1832a70125f32daae071ef37dcb7701b7d4fe" dependencies = [ "assert_matches", - "bitflags 2.9.0", + "bitflags 2.10.0", "either", "incrementalmerkletree", "incrementalmerkletree-testing", @@ -4351,12 +4332,12 @@ dependencies = [ [[package]] name = "shellexpand" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" dependencies = [ "bstr", - "dirs 5.0.1", + "dirs", "os_str_bytes", ] @@ -4368,9 +4349,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -4385,6 +4366,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "sinsemilla" version = "0.1.0" @@ -4404,12 +4391,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slotmap" @@ -4430,25 +4414,15 @@ dependencies = [ "paste", "serde", "slotmap", - "thiserror 2.0.12", + "thiserror 2.0.17", "void", ] [[package]] name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.9" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" @@ -4503,14 +4477,14 @@ checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" dependencies = [ "base64ct", "pem-rfc7468", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] name = "ssh-key" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca9b366a80cf18bb6406f4cf4d10aebfb46140a8c0c33f666a144c5c76ecbafc" +checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" dependencies = [ "num-bigint-dig", "p256", @@ -4519,7 +4493,7 @@ dependencies = [ "rand_core 0.6.4", "rsa", "sec1", - "sha2 0.10.8", + "sha2 0.10.9", "signature", "ssh-cipher", "ssh-encoding", @@ -4529,9 +4503,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -4557,35 +4531,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - [[package]] name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.2", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.100", + "strum_macros", ] [[package]] @@ -4597,7 +4549,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -4608,9 +4560,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.13.3" +version = "12.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13a4dfe4bbeef59c1f32fc7524ae7c95b9e1de5e79a43ce1604e181081d71b0c" +checksum = "d03f433c9befeea460a01d750e698aa86caf86dcfbd77d552885cd6c89d52f50" dependencies = [ "debugid", "memmap2", @@ -4620,9 +4572,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.13.3" +version = "12.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cf6a95abff97de4d7ff3473f33cacd38f1ddccad5c1feab435d6760300e3b6" +checksum = "13d359ef6192db1760a34321ec4f089245ede4342c27e59be99642f12a859de8" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -4642,9 +4594,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" dependencies = [ "proc-macro2", "quote", @@ -4659,13 +4611,13 @@ checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -4690,71 +4642,71 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "cfg-if", "fastrand", - "rustix 0.38.34", - "windows-sys 0.52.0", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.63", + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -4773,9 +4725,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -4783,11 +4735,12 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", + "serde_core", "zerovec", ] @@ -4803,9 +4756,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -4818,40 +4771,38 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", "libc", - "mio 0.8.11", - "num_cpus", + "mio", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.9", + "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.25", + "rustls 0.23.35", "tokio", ] @@ -4868,9 +4819,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -4882,14 +4833,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned 0.6.8", - "toml_datetime 0.6.8", - "toml_edit 0.22.22", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -4904,14 +4855,14 @@ dependencies = [ "toml_datetime 0.7.3", "toml_parser", "toml_writer", - "winnow 0.7.13", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] @@ -4927,26 +4878,28 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap 2.12.0", - "toml_datetime 0.6.8", - "winnow 0.5.40", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow", ] [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ "indexmap 2.12.0", - "serde", - "serde_spanned 0.6.8", - "toml_datetime 0.6.8", - "winnow 0.6.20", + "toml_datetime 0.7.3", + "toml_parser", + "winnow", ] [[package]] @@ -4955,9 +4908,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ - "winnow 0.7.13", + "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "toml_writer" version = "1.0.4" @@ -4982,7 +4941,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "socket2 0.6.1", + "socket2", "sync_wrapper", "tokio", "tokio-rustls", @@ -4991,7 +4950,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "webpki-roots 1.0.3", + "webpki-roots 1.0.4", ] [[package]] @@ -5003,7 +4962,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -5028,7 +4987,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.100", + "syn 2.0.109", "tempfile", "tonic-build", ] @@ -5039,13 +4998,13 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cad5e568ad4e025a68aa0395a146247609dd5b6d8c2141255f5e4f367e7fda8a" dependencies = [ - "derive-deftly 1.3.0", + "derive-deftly", "educe", "futures", "oneshot-fused-workaround", "pin-project", "postage", - "thiserror 2.0.12", + "thiserror 2.0.17", "void", ] @@ -5065,7 +5024,7 @@ dependencies = [ "serde", "slab", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -5075,12 +5034,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fc7fb465ba671ee1486d8bd1e0a8f546887c2ce034004c4c9b03a6227e1c381" dependencies = [ "bytes", - "derive-deftly 1.3.0", + "derive-deftly", "digest 0.10.7", "educe", "getrandom 0.3.4", "safelog", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-error", "tor-llcrypto", "zeroize", @@ -5093,17 +5052,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79ba1b43f22fab2daee3e0c902f1455b3aed8e086b2d83d8c60b36523b173d25" dependencies = [ "amplify", - "bitflags 2.9.0", + "bitflags 2.10.0", "bytes", "caret", - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "educe", "itertools 0.14.0", "paste", "rand 0.9.2", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-cert", @@ -5126,7 +5085,7 @@ dependencies = [ "derive_builder_fork_arti", "derive_more", "digest 0.10.7", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-bytes", "tor-checkable", "tor-llcrypto", @@ -5149,7 +5108,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -5176,7 +5135,7 @@ checksum = "7c9839e9bb302f17447c350e290bb107084aca86c640882a91522f2059f6a686" dependencies = [ "humantime", "signature", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-llcrypto", ] @@ -5189,7 +5148,7 @@ dependencies = [ "amplify", "async-trait", "cfg-if", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "downcast-rs", @@ -5205,7 +5164,7 @@ dependencies = [ "retry-error", "safelog", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -5237,7 +5196,7 @@ checksum = "cb15df773842025010d885fbe862062ebaa342b799f9716273eaf733b92f2f45" dependencies = [ "amplify", "cfg-if", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "educe", "either", @@ -5252,8 +5211,8 @@ dependencies = [ "serde", "serde-value", "serde_ignored", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "toml 0.9.8", "tor-basic-utils", "tor-error", @@ -5271,7 +5230,7 @@ dependencies = [ "directories", "serde", "shellexpand", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-error", "tor-general-addr", ] @@ -5284,7 +5243,7 @@ checksum = "c1690438c1fc778fc7c89c132e529365b1430d6afe03aeecbc2508324807bf0b" dependencies = [ "digest 0.10.7", "hex", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-llcrypto", ] @@ -5304,7 +5263,7 @@ dependencies = [ "httpdate", "itertools 0.14.0", "memchr", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-circmgr", "tor-error", "tor-linkspec", @@ -5368,8 +5327,8 @@ dependencies = [ "serde_json", "signature", "static_assertions", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "time", "tor-async-utils", "tor-basic-utils", @@ -5402,8 +5361,8 @@ dependencies = [ "paste", "retry-error", "static_assertions", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "tracing", "void", ] @@ -5415,7 +5374,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c42cb5b5aec0584db2fba4a88c4e08fb09535ef61e4ef5674315a89e69ec31a2" dependencies = [ "derive_more", - "thiserror 2.0.12", + "thiserror 2.0.17", "void", ] @@ -5427,7 +5386,7 @@ checksum = "0585a83a4c56b4f31f6fa2965e2f9c490c9f4d29fba2fedb5a9ee71009f793c0" dependencies = [ "amplify", "base64ct", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "dyn-clone", @@ -5443,8 +5402,8 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -5469,7 +5428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9ee6e0dbec9ba11c3d046181a42dd4759e108de38e2b5927689edbdc458a51" dependencies = [ "data-encoding", - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "digest 0.10.7", "hex", @@ -5481,7 +5440,7 @@ dependencies = [ "serde", "signature", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-error", @@ -5497,7 +5456,7 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa30066b80ade55a1b88a82b5320dfc50d1724918ad614ded8ecb4820c32062" dependencies = [ - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "downcast-rs", "paste", @@ -5505,7 +5464,7 @@ dependencies = [ "rsa", "signature", "ssh-key", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-bytes", "tor-cert", "tor-checkable", @@ -5522,7 +5481,7 @@ dependencies = [ "amplify", "arrayvec", "cfg-if", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "downcast-rs", @@ -5537,7 +5496,7 @@ dependencies = [ "serde", "signature", "ssh-key", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-config", @@ -5562,7 +5521,7 @@ dependencies = [ "base64ct", "by_address", "caret", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "hex", @@ -5570,8 +5529,8 @@ dependencies = [ "safelog", "serde", "serde_with", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-config", @@ -5591,7 +5550,7 @@ dependencies = [ "ctr", "curve25519-dalek", "der-parser", - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "digest 0.10.7", "ed25519-dalek", @@ -5608,11 +5567,11 @@ dependencies = [ "safelog", "serde", "sha1", - "sha2 0.10.8", + "sha2 0.10.9", "sha3", "signature", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-error", "tor-memquota", "visibility", @@ -5628,7 +5587,7 @@ checksum = "845d65304be6a614198027c4b2d1b35aaf073335c26df619d17e5f4027f2657f" dependencies = [ "futures", "humantime", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-error", "tor-rtcompat", "tracing", @@ -5642,7 +5601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef375c3442a4ea74f0b6bf91a3eed660d55301b2e2f59b366aba4849b2321a6f" dependencies = [ "cfg-if", - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "dyn-clone", "educe", @@ -5654,7 +5613,7 @@ dependencies = [ "slotmap-careful", "static_assertions", "sysinfo", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -5672,7 +5631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "638b4e6507e3786488859d3c463fa73addbad4f788806c6972603727e527672e" dependencies = [ "async-trait", - "bitflags 2.9.0", + "bitflags 2.10.0", "derive_more", "futures", "humantime", @@ -5680,8 +5639,8 @@ dependencies = [ "num_enum", "rand 0.9.2", "serde", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "tor-basic-utils", "tor-error", "tor-linkspec", @@ -5701,9 +5660,9 @@ checksum = "1dbc32d89e7ea2e2799168d0c453061647a727e39fc66f52e1bcb4c38c8dc433" dependencies = [ "amplify", "base64ct", - "bitflags 2.9.0", + "bitflags 2.10.0", "cipher", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "digest 0.10.7", @@ -5718,9 +5677,9 @@ dependencies = [ "serde_with", "signature", "smallvec", - "strum 0.27.2", + "strum", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", "time", "tinystr", "tor-basic-utils", @@ -5742,7 +5701,7 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59e41aea027686b05f21e0ad75aa2c0c9681a87f2f3130b6d6f7a7a8c06edd7b" dependencies = [ - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "filetime", "fs-mistrust", @@ -5754,7 +5713,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", "time", "tor-async-utils", "tor-basic-utils", @@ -5778,7 +5737,7 @@ dependencies = [ "cipher", "coarsetime", "criterion-cycles-per-byte", - "derive-deftly 1.3.0", + "derive-deftly", "derive_builder_fork_arti", "derive_more", "digest 0.10.7", @@ -5801,7 +5760,7 @@ dependencies = [ "static_assertions", "subtle", "sync_wrapper", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-util", "tor-async-utils", @@ -5836,7 +5795,7 @@ dependencies = [ "caret", "paste", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-bytes", ] @@ -5874,8 +5833,8 @@ dependencies = [ "paste", "pin-project", "rustls-pki-types", - "rustls-webpki 0.103.1", - "thiserror 2.0.12", + "rustls-webpki 0.103.8", + "thiserror 2.0.17", "tokio", "tokio-util", "tor-error", @@ -5893,7 +5852,7 @@ dependencies = [ "amplify", "assert_matches", "async-trait", - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "educe", "futures", @@ -5903,8 +5862,8 @@ dependencies = [ "pin-project", "priority-queue", "slotmap-careful", - "strum 0.27.2", - "thiserror 2.0.12", + "strum", + "thiserror 2.0.17", "tor-error", "tor-general-addr", "tor-rtcompat", @@ -5921,11 +5880,11 @@ checksum = "0dbb9b68d9cf8e07eeafbca91ac11b7d9c4be1e674cb59830edfbac153333e7f" dependencies = [ "amplify", "caret", - "derive-deftly 1.3.0", + "derive-deftly", "educe", "safelog", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-bytes", "tor-error", ] @@ -5936,10 +5895,10 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48139f001dd6f409325b7c190ebcea1033b27f09042543946ab7aa4ad286257b" dependencies = [ - "derive-deftly 1.3.0", + "derive-deftly", "derive_more", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", "tor-memquota", ] @@ -5993,7 +5952,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -6019,14 +5978,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -6053,7 +6012,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -6064,7 +6023,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -6085,9 +6044,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "uint" @@ -6118,15 +6077,15 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-normalization" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" dependencies = [ "tinyvec", ] @@ -6167,19 +6126,21 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] name = "uuid" -version = "1.8.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.3.4", + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vcpkg" @@ -6189,9 +6150,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "visibility" @@ -6201,7 +6162,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -6262,9 +6223,9 @@ checksum = "a7b6d5a78adc3e8f198e9cd730f219a695431467f7ec29dcfc63ade885feebe1" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] @@ -6290,9 +6251,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" @@ -6314,34 +6275,22 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", "once_cell", - "proc-macro2", - "quote", - "syn 2.0.100", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6349,22 +6298,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.100", - "wasm-bindgen-backend", + "syn 2.0.109", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm_sync" @@ -6385,9 +6337,9 @@ checksum = "323f4da9523e9a669e1eaf9c6e763892769b1d38c623913647bfdc1532fe4549" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -6401,9 +6353,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] @@ -6415,7 +6367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ "env_home", - "rustix 1.1.2", + "rustix", "winsafe", ] @@ -6437,11 +6389,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -6474,24 +6426,28 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.1.3", - "windows-result", - "windows-strings", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -6513,7 +6469,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -6524,7 +6480,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -6558,6 +6514,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-strings" version = "0.4.2" @@ -6568,12 +6533,12 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-targets 0.48.5", + "windows-link 0.2.1", ] [[package]] @@ -6585,15 +6550,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" @@ -6604,18 +6560,12 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" 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", + "windows-link 0.2.1", ] [[package]] @@ -6660,12 +6610,6 @@ 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" @@ -6678,12 +6622,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -6696,12 +6634,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6726,12 +6658,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -6744,12 +6670,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -6762,12 +6682,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -6780,12 +6694,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -6800,28 +6708,13 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.20" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" - [[package]] name = "winsafe" version = "0.0.19" @@ -6861,15 +6754,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" -[[package]] -name = "xz2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" -dependencies = [ - "lzma-sys", -] - [[package]] name = "zcash" version = "0.1.0" @@ -6953,7 +6837,7 @@ dependencies = [ "tower", "tracing", "trait-variant", - "webpki-roots 1.0.3", + "webpki-roots 1.0.4", "which", "zcash_address", "zcash_encoding", @@ -6996,7 +6880,7 @@ dependencies = [ "shardtree", "static_assertions", "subtle", - "thiserror 1.0.63", + "thiserror 1.0.69", "time", "tokio", "tracing", @@ -7020,7 +6904,7 @@ dependencies = [ "ambassador", "assert_matches", "bip32", - "bitflags 2.9.0", + "bitflags 2.10.0", "bls12_381", "bs58", "byteorder", @@ -7074,6 +6958,7 @@ name = "zcash_encoding" version = "0.3.0" dependencies = [ "core2", + "hex", "nonempty", ] @@ -7191,7 +7076,7 @@ dependencies = [ "ripemd 0.1.3", "sapling-crypto", "secp256k1", - "sha2 0.10.8", + "sha2 0.10.9", "subtle", "tracing", "zcash_address", @@ -7238,6 +7123,7 @@ dependencies = [ "incrementalmerkletree-testing", "memuse", "proptest", + "zcash_encoding", ] [[package]] @@ -7247,14 +7133,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bed6cf5b2b4361105d4ea06b2752f0c8af4641756c7fbc9858a80af186c234f" dependencies = [ "bip32", - "bitflags 2.9.0", + "bitflags 2.10.0", "bounded-vec", "hex", "ripemd 0.1.3", "secp256k1", "sha1", - "sha2 0.10.8", - "thiserror 2.0.12", + "sha2 0.10.9", + "thiserror 2.0.17", ] [[package]] @@ -7280,7 +7166,7 @@ dependencies = [ "proptest", "ripemd 0.1.3", "secp256k1", - "sha2 0.10.8", + "sha2 0.10.9", "subtle", "zcash_address", "zcash_encoding", @@ -7292,22 +7178,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] @@ -7318,9 +7204,9 @@ checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] @@ -7333,24 +7219,26 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.109", ] [[package]] name = "zerovec" -version = "0.11.1" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e62113720e311984f461c56b00457ae9981c0bc7859d22306cc2ae2f95571c" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ + "serde", "zerofrom", ] [[package]] name = "zip32" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ff9ea444cdbce820211f91e6aa3d3a56bde7202d3c0961b7c38f793abf5637" +checksum = "b64bf5186a8916f7a48f2a98ef599bf9c099e2458b36b819e393db1c0e768c4b" dependencies = [ + "bech32", "blake2b_simd", "memuse", "subtle", @@ -7371,27 +7259,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.1.0" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/components/zcash_encoding/Cargo.toml b/components/zcash_encoding/Cargo.toml index caa88dfe13..4ba7fcfb1a 100644 --- a/components/zcash_encoding/Cargo.toml +++ b/components/zcash_encoding/Cargo.toml @@ -17,6 +17,7 @@ keywords = ["zcash"] [dependencies] core2.workspace = true +hex.workspace = true nonempty.workspace = true [features] diff --git a/components/zcash_encoding/src/lib.rs b/components/zcash_encoding/src/lib.rs index 4e611e25a6..7077b381e0 100644 --- a/components/zcash_encoding/src/lib.rs +++ b/components/zcash_encoding/src/lib.rs @@ -300,6 +300,18 @@ impl Optional { } } +/// Decodes a reversed-hex string into a byte array. +/// +/// This handles the legacy format from Bitcoin Core's `uint256::GetHex`, which reverses +/// bytes before hex encoding. `zcashd` applied this to all 32-byte JSON-RPC values +/// (transaction IDs, block hashes, Sprout field elements, etc.), though non-32-byte +/// hex values are not reversed. +pub fn decode_reverse_hex(bytes: &[u8; 32]) -> alloc::string::String { + let mut reversed = *bytes; + reversed.reverse(); + hex::encode(reversed) +} + #[cfg(test)] mod tests { use super::*; diff --git a/components/zcash_protocol/Cargo.toml b/components/zcash_protocol/Cargo.toml index 22761e0959..1f2c763b8c 100644 --- a/components/zcash_protocol/Cargo.toml +++ b/components/zcash_protocol/Cargo.toml @@ -29,6 +29,7 @@ memuse = { workspace = true, optional = true } document-features = { workspace = true, optional = true } # - Encodings +zcash_encoding.workspace = true core2.workspace = true hex.workspace = true diff --git a/components/zcash_protocol/src/txid.rs b/components/zcash_protocol/src/txid.rs index ddbbfefd9f..54fa34e21f 100644 --- a/components/zcash_protocol/src/txid.rs +++ b/components/zcash_protocol/src/txid.rs @@ -2,6 +2,8 @@ use alloc::string::ToString; use core::fmt; use core2::io::{self, Read, Write}; +use zcash_encoding::decode_reverse_hex; + #[cfg(feature = "std")] use memuse::DynamicUsage; @@ -29,9 +31,7 @@ impl fmt::Debug for TxId { impl fmt::Display for TxId { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut data = self.0; - data.reverse(); - formatter.write_str(&hex::encode(data)) + formatter.write_str(&decode_reverse_hex(&self.0)) } } From 7dc33d78580380199453d4dc9f17b9b6da79d766 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 6 Nov 2025 14:50:54 +0100 Subject: [PATCH 003/263] feat(zcash_protocol): Adding TxId::from_reverse_hex --- components/zcash_protocol/src/txid.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/components/zcash_protocol/src/txid.rs b/components/zcash_protocol/src/txid.rs index 54fa34e21f..a52e1bfc8e 100644 --- a/components/zcash_protocol/src/txid.rs +++ b/components/zcash_protocol/src/txid.rs @@ -48,6 +48,17 @@ impl From for [u8; 32] { } impl TxId { + /// Creates a TxId from a reverse hex string + /// + /// See `zcash_encoding::decode_reverse_hex` for more context. + pub const fn from_reverse_hex(hex_str: &str) -> RpcResult { + let mut bytes = [0; 32]; + hex::decode_to_slice(hex_str, &mut bytes) + .map_err(|_| RpcError::ParseError("Invalid hex string".to_string()))?; + bytes.reverse(); + Ok(TxId(bytes)) + } + /// Wraps the given byte array as a TxId value pub const fn from_bytes(bytes: [u8; 32]) -> Self { TxId(bytes) From 5337df6943cf209e0075f4efdc6569ddb9d4965a Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 6 Nov 2025 15:12:36 +0100 Subject: [PATCH 004/263] refactor: adding namespace to method --- components/zcash_encoding/src/lib.rs | 15 +++++++++------ components/zcash_protocol/src/txid.rs | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/components/zcash_encoding/src/lib.rs b/components/zcash_encoding/src/lib.rs index 7077b381e0..e43f291c63 100644 --- a/components/zcash_encoding/src/lib.rs +++ b/components/zcash_encoding/src/lib.rs @@ -300,16 +300,19 @@ impl Optional { } } -/// Decodes a reversed-hex string into a byte array. -/// /// This handles the legacy format from Bitcoin Core's `uint256::GetHex`, which reverses /// bytes before hex encoding. `zcashd` applied this to all 32-byte JSON-RPC values /// (transaction IDs, block hashes, Sprout field elements, etc.), though non-32-byte /// hex values are not reversed. -pub fn decode_reverse_hex(bytes: &[u8; 32]) -> alloc::string::String { - let mut reversed = *bytes; - reversed.reverse(); - hex::encode(reversed) +pub struct ReverseHex; + +impl ReverseHex { + /// Decodes a reversed-hex string into a byte array. + pub fn decode(bytes: &[u8; 32]) -> alloc::string::String { + let mut reversed = *bytes; + reversed.reverse(); + hex::encode(reversed) + } } #[cfg(test)] diff --git a/components/zcash_protocol/src/txid.rs b/components/zcash_protocol/src/txid.rs index a52e1bfc8e..bc804b4fe3 100644 --- a/components/zcash_protocol/src/txid.rs +++ b/components/zcash_protocol/src/txid.rs @@ -2,7 +2,7 @@ use alloc::string::ToString; use core::fmt; use core2::io::{self, Read, Write}; -use zcash_encoding::decode_reverse_hex; +use zcash_encoding::ReverseHex; #[cfg(feature = "std")] use memuse::DynamicUsage; @@ -31,7 +31,7 @@ impl fmt::Debug for TxId { impl fmt::Display for TxId { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str(&decode_reverse_hex(&self.0)) + formatter.write_str(&ReverseHex::decode(&self.0)) } } From a6144b71bc6a758a9004db567d36f103d5c25055 Mon Sep 17 00:00:00 2001 From: replicationlag Date: Sun, 9 Nov 2025 01:00:47 -0500 Subject: [PATCH 005/263] Prevent usage of unrecognized required params in test payment generation --- components/zip321/src/lib.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/components/zip321/src/lib.rs b/components/zip321/src/lib.rs index c59695b5e3..3f1e77bcd9 100644 --- a/components/zip321/src/lib.rs +++ b/components/zip321/src/lib.rs @@ -810,13 +810,17 @@ pub mod testing { other_params in btree_map(VALID_PARAMNAME, any::(), 0..3), ) -> Payment { let memo = memo.filter(|_| recipient_address.can_receive_memo()); + let other_params = other_params + .into_iter() + .filter(|(name, _)| !name.starts_with("req-")) + .collect(); Payment { recipient_address, amount, memo, label, message, - other_params: other_params.into_iter().collect(), + other_params, } } } @@ -1109,6 +1113,12 @@ mod tests { let invalid_11 = "zcash:?address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU&amount=123."; let i11r = TransactionRequest::from_uri(invalid_11); assert!(i11r.is_err()); + + // invalid: unrecognized required parameters are not allowed + let invalid_12 = + "zcash:?address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU&amount=123.45&req-unknown=x"; + let i12r = TransactionRequest::from_uri(invalid_12); + assert!(i12r.is_err()); } proptest! { From cf39300ffa47aca9f2dec1f55727d17a5301f2fe Mon Sep 17 00:00:00 2001 From: Ryan Quinn Ford Date: Mon, 10 Nov 2025 09:11:57 +0100 Subject: [PATCH 006/263] fix: adding decoder and proptest --- Cargo.lock | 1745 +++++++++++++------------ components/zcash_encoding/Cargo.toml | 3 + components/zcash_encoding/src/lib.rs | 27 +- components/zcash_protocol/src/txid.rs | 13 +- 4 files changed, 959 insertions(+), 829 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffd9eeb314..91ab47adcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,19 +1,21 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "addr2line" -version = "0.25.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] [[package]] -name = "adler2" -version = "2.0.1" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" @@ -39,12 +41,12 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.12" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.3.4", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -52,9 +54,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -70,9 +72,9 @@ dependencies = [ [[package]] name = "ambassador" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68de4cdc6006162265d0957edb4a860fe4e711b1dc17a5746fd95f952f08285" +checksum = "6b27ba24e4d8a188489d5a03c7fabc167a60809a383cdb4d15feb37479cd2a48" dependencies = [ "itertools 0.10.5", "proc-macro2", @@ -82,23 +84,21 @@ dependencies = [ [[package]] name = "amplify" -version = "4.9.0" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f7fb4ac7c881e54a8e7015e399b6112a2a5bc958b6c89ac510840ff20273b31" +checksum = "9e711289a6cb28171b4f0e6c8019c69ff9476050508dc082167575d458ff74d0" dependencies = [ "amplify_derive", "amplify_num", "ascii", - "getrandom 0.2.16", - "getrandom 0.3.4", "wasm-bindgen", ] [[package]] name = "amplify_derive" -version = "4.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a6309e6b8d89b36b9f959b7a8fa093583b94922a0f6438a24fb08936de4d428" +checksum = "759dcbfaf94d838367a86d493ec34ccc8aa6fe365cb7880d6bf89006de24d9c1" dependencies = [ "amplify_syn", "proc-macro2", @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "amplify_num" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99bcb75a2982047f733547042fc3968c0f460dfcf7d90b90dea3b2744580e9ad" +checksum = "04c009c5c4de814911b177e2ea59e4930bb918978ed3cce4900d846a6ceb0838" dependencies = [ "wasm-bindgen", ] @@ -126,6 +126,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -143,27 +149,27 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "arrayref" -version = "0.3.9" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "arti-client" @@ -173,7 +179,7 @@ checksum = "0a79ca5ce63b36033a5ccbfbcc7f919cbd93db61708543aa5e2e4917856205e7" dependencies = [ "async-trait", "cfg-if", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "educe", @@ -188,7 +194,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.17", + "thiserror 2.0.12", "time", "tor-async-utils", "tor-basic-utils", @@ -232,7 +238,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror 2.0.17", + "thiserror 2.0.12", ] [[package]] @@ -243,7 +249,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", "synstructure", ] @@ -255,7 +261,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -266,26 +272,29 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.32" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" +checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" dependencies = [ - "compression-codecs", - "compression-core", + "flate2", "futures-core", "futures-io", + "memchr", "pin-project-lite", + "xz2", + "zstd", + "zstd-safe", ] [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -324,9 +333,9 @@ checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "atomic" -version = "0.6.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" dependencies = [ "bytemuck", ] @@ -339,23 +348,23 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.76" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", + "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", - "windows-link 0.2.1", ] [[package]] @@ -422,7 +431,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2", "rand 0.8.5", - "sha2 0.10.9", + "sha2 0.10.8", "unicode-normalization", "zeroize", ] @@ -445,18 +454,18 @@ dependencies = [ [[package]] name = "bit-set" -version = "0.8.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.8.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" @@ -466,9 +475,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "bitvec" @@ -484,9 +493,9 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", @@ -495,9 +504,9 @@ dependencies = [ [[package]] name = "blake2s_simd" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec", @@ -512,7 +521,7 @@ checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -552,7 +561,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09dc0086e469182132244e9b8d313a0742e1132da43a08c24b9dd3c18e0faf3a" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.12", ] [[package]] @@ -561,26 +570,26 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.9", + "sha2 0.10.8", "tinyvec", ] [[package]] name = "bstr" -version = "1.12.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", - "regex-automata", + "regex-automata 0.4.9", "serde", ] [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "by_address" @@ -590,9 +599,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" [[package]] name = "byteorder" @@ -629,11 +638,10 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.44" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ - "find-msvc-tools", "jobserver", "libc", "shlex", @@ -641,9 +649,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" @@ -671,14 +679,15 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ + "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-link 0.2.1", + "windows-targets 0.52.6", ] [[package]] @@ -721,18 +730,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.51" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.51" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstyle", "clap_lex", @@ -740,15 +749,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "coarsetime" -version = "0.1.36" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91849686042de1b41cd81490edc83afbcb0abe5a9b6f2c4114f23ce8cca1bcf4" +checksum = "13b3839cf01bb7960114be3ccf2340f541b6d0c81f8690b007b2b39f750f7e5d" dependencies = [ "libc", "wasix", @@ -757,31 +766,9 @@ dependencies = [ [[package]] name = "cobs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" -dependencies = [ - "thiserror 2.0.17", -] - -[[package]] -name = "compression-codecs" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" -dependencies = [ - "compression-core", - "flate2", - "liblzma", - "zstd", - "zstd-safe", -] - -[[package]] -name = "compression-core" -version = "0.4.29" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "concurrent-queue" @@ -800,9 +787,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "convert_case" @@ -824,9 +811,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.7" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -839,27 +826,27 @@ dependencies = [ [[package]] name = "cpp_demangle" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" +checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" dependencies = [ "cfg-if", ] [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -954,9 +941,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -973,24 +960,25 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.12" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ + "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" @@ -1057,14 +1045,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "daggy" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70def8d72740e44d9f676d8dab2c933a236663d86dd24319b57a2bed4d694774" +checksum = "91a9304e55e9d601a39ae4deaba85406d5c0980e106f65afcf0460e9af1e7602" dependencies = [ "petgraph", ] @@ -1081,12 +1069,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -1105,16 +1093,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -1130,20 +1118,20 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.21.3", + "darling_core 0.20.10", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "data-encoding" -version = "2.9.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "debugid" @@ -1156,9 +1144,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -1189,14 +1177,42 @@ dependencies = [ "serde", ] +[[package]] +name = "derive-deftly" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f9bc3564f74be6c35d49a7efee54380d7946ccc631323067f33fabb9246027" +dependencies = [ + "derive-deftly-macros 0.14.2", + "heck", +] + [[package]] name = "derive-deftly" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d308ebe4b10924331bd079044b418da7b227d724d3e2408567a47ad7c3da2a0" dependencies = [ - "derive-deftly-macros", + "derive-deftly-macros 1.3.0", + "heck", +] + +[[package]] +name = "derive-deftly-macros" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b84d32b18d9a256d81e4fec2e4cfd0ab6dde5e5ff49be1713ae0adbd0060c2" +dependencies = [ "heck", + "indexmap 2.12.0", + "itertools 0.13.0", + "proc-macro-crate", + "proc-macro2", + "quote", + "sha3", + "strum 0.26.3", + "syn 2.0.100", + "void", ] [[package]] @@ -1212,8 +1228,8 @@ dependencies = [ "proc-macro2", "quote", "sha3", - "strum", - "syn 2.0.109", + "strum 0.27.2", + "syn 2.0.100", "void", ] @@ -1266,7 +1282,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", "unicode-xid", ] @@ -1299,7 +1315,16 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" dependencies = [ - "dirs-sys", + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", ] [[package]] @@ -1308,7 +1333,19 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys", + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.5", + "windows-sys 0.48.0", ] [[package]] @@ -1319,41 +1356,41 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users", - "windows-sys 0.61.2", + "redox_users 0.5.0", + "windows-sys 0.60.2", ] [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "document-features" -version = "0.2.12" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" dependencies = [ "litrs", ] [[package]] name = "downcast-rs" -version = "2.0.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" +checksum = "ea8a8b81cacc08888170eef4d13b775126db426d0b348bee9d18c2c1eaf123cf" [[package]] name = "dyn-clone" -version = "1.0.20" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "dynosaur" @@ -1372,7 +1409,7 @@ checksum = "0b0713d5c1d52e774c5cd7bb8b043d7c0fc4f921abfb678556140bfbe6ab2364" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -1410,7 +1447,7 @@ dependencies = [ "merlin", "rand_core 0.6.4", "serde", - "sha2 0.10.9", + "sha2 0.10.8", "subtle", "zeroize", ] @@ -1429,9 +1466,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1474,7 +1511,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -1486,7 +1523,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -1512,7 +1549,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -1528,9 +1565,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" @@ -1539,14 +1576,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] name = "event-listener" -version = "5.4.1" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1576,15 +1613,15 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "ff" -version = "0.13.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "bitvec", "rand_core 0.6.4", @@ -1603,31 +1640,25 @@ version = "0.10.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" dependencies = [ - "atomic 0.6.1", + "atomic 0.6.0", "serde", - "toml 0.8.23", + "toml 0.8.19", "uncased", "version_check", ] [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] -[[package]] -name = "find-msvc-tools" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" - [[package]] name = "findshlibs" version = "0.10.2" @@ -1651,15 +1682,15 @@ dependencies = [ [[package]] name = "fixedbitset" -version = "0.5.7" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.5" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1704,11 +1735,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a157b06319bb4868718fd20177a0d3373d465e429d89cd0ee493d9f5918902" dependencies = [ "derive_builder_fork_arti", - "dirs", + "dirs 6.0.0", "libc", "pwd-grp", "serde", - "thiserror 2.0.17", + "thiserror 2.0.12", "walkdir", ] @@ -1730,9 +1761,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1761,9 +1792,9 @@ checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1784,7 +1815,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -1794,7 +1825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.35", + "rustls 0.23.25", "rustls-pki-types", ] @@ -1830,9 +1861,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1841,15 +1872,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -1859,11 +1888,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi", "wasip2", - "wasm-bindgen", ] [[package]] @@ -1875,14 +1902,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "gimli" -version = "0.32.3" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob-match" @@ -1924,9 +1951,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.12" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ "atomic-waker", "bytes", @@ -1943,13 +1970,11 @@ dependencies = [ [[package]] name = "half" -version = "2.7.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" dependencies = [ - "cfg-if", "crunchy", - "zerocopy", ] [[package]] @@ -1992,15 +2017,14 @@ dependencies = [ [[package]] name = "halo2_proofs" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "019561b5f3be60731e7b72f3f7878c5badb4174362d860b03d3cf64cb47f90db" +checksum = "7b867a8d9bbb85fca76fff60652b5cd19b853a1c4d0665cb89bee68b18d2caf0" dependencies = [ "blake2b_simd", "ff", "group", "halo2_legacy_pdqsort", - "indexmap 1.9.3", "maybe-rayon", "pasta_curves", "rand_core 0.6.4", @@ -2015,9 +2039,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "foldhash", ] @@ -2034,7 +2058,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.15.2", ] [[package]] @@ -2045,9 +2069,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -2084,11 +2108,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.12" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2099,9 +2123,9 @@ checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2" [[package]] name = "http" -version = "1.3.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -2120,12 +2144,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http", "http-body", "pin-project-lite", @@ -2145,9 +2169,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "humantime-serde" @@ -2170,14 +2194,13 @@ dependencies = [ [[package]] name = "hyper" -version = "1.7.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ - "atomic-waker", "bytes", "futures-channel", - "futures-core", + "futures-util", "h2", "http", "http-body", @@ -2185,7 +2208,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -2193,9 +2215,9 @@ dependencies = [ [[package]] name = "hyper-timeout" -version = "0.5.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ "hyper", "hyper-util", @@ -2206,20 +2228,19 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.17" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", "hyper", "libc", "pin-project-lite", - "socket2", + "socket2 0.5.9", "tokio", "tower-service", "tracing", @@ -2227,17 +2248,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", - "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.52.0", ] [[package]] @@ -2324,7 +2344,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", "inotify-sys", "libc", ] @@ -2340,31 +2360,28 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ "generic-array", ] [[package]] name = "inventory" -version = "0.3.21" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" -dependencies = [ - "rustversion", -] +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" [[package]] name = "is-terminal" -version = "0.4.17" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2396,27 +2413,25 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ - "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ - "once_cell", "wasm-bindgen", ] @@ -2436,27 +2451,27 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] [[package]] name = "known-folders" -version = "1.4.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d463f34ca3c400fde3a054da0e0b8c6ffa21e4590922f3e18281bb5eeef4cbdc" +checksum = "4397c789f2709d23cfcb703b316e0766a8d4b17db2d47b0ab096ef6047cae1d8" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] name = "kqueue" -version = "1.1.1" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" dependencies = [ "kqueue-sys", "libc", @@ -2487,39 +2502,19 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" -[[package]] -name = "liblzma" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c36d08cad03a3fbe2c4e7bb3a9e84c57e4ee4135ed0b065cade3d98480c648" -dependencies = [ - "liblzma-sys", -] - -[[package]] -name = "liblzma-sys" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b9596486f6d60c3bbe644c0e1be1aa6ccc472ad630fe8927b456973d7cb736" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "libm" -version = "0.2.15" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", "libc", "redox_syscall", ] @@ -2535,6 +2530,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -2543,32 +2544,44 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litrs" -version = "1.0.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" -version = "0.4.14" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.28" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] [[package]] name = "matchers" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -2583,15 +2596,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.9" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] @@ -2622,20 +2635,21 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.9" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ - "adler2", - "simd-adler32", + "adler", ] [[package]] name = "minreq" -version = "2.14.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" +checksum = "763d142cdff44aaadd9268bebddb156ef6c65a0e13486bb81673cf2d8739f9b0" dependencies = [ + "log", + "once_cell", "rustls 0.21.12", "rustls-webpki 0.101.7", "webpki-roots 0.25.4", @@ -2643,21 +2657,32 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.0" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "mio" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] name = "multimap" -version = "0.10.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "nix" @@ -2694,19 +2719,20 @@ checksum = "549e471b99ccaf2f89101bec68f4d244457d5a95a9c3d0672e9564124397741d" [[package]] name = "notify" -version = "8.2.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" +checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", + "filetime", "inotify", "kqueue", "libc", "log", - "mio", + "mio 1.0.3", "notify-types", "walkdir", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -2726,18 +2752,19 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.50.3" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "windows-sys 0.61.2", + "overload", + "winapi", ] [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ "num-integer", "num-traits", @@ -2745,10 +2772,11 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c79c15c05d4bf82b6f5ef163104cc81a760d8e874d38ac50ab67c8877b647b" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" dependencies = [ + "byteorder", "lazy_static", "libm", "num-integer", @@ -2807,9 +2835,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.17.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", @@ -2817,24 +2845,23 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.5" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ "num_enum_derive", - "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.5" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -2843,7 +2870,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", ] [[package]] @@ -2858,18 +2885,18 @@ dependencies = [ [[package]] name = "object" -version = "0.37.3" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.21.3" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oneshot-fused-workaround" @@ -2882,9 +2909,9 @@ dependencies = [ [[package]] name = "oorandom" -version = "11.1.5" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "opaque-debug" @@ -2952,6 +2979,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "p256" version = "0.13.2" @@ -2961,19 +2994,19 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.9", + "sha2 0.10.8", ] [[package]] name = "p384" -version = "0.13.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.9", + "sha2 0.10.8", ] [[package]] @@ -2987,7 +3020,7 @@ dependencies = [ "elliptic-curve", "primeorder", "rand_core 0.6.4", - "sha2 0.10.9", + "sha2 0.10.8", ] [[package]] @@ -3001,15 +3034,15 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -3017,15 +3050,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.12" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-targets 0.52.6", ] [[package]] @@ -3092,7 +3125,7 @@ dependencies = [ "secp256k1", "serde", "serde_with", - "sha2 0.10.9", + "sha2 0.10.8", "shardtree", "zcash_note_encryption", "zcash_primitives", @@ -3114,15 +3147,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" -version = "0.7.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap 2.12.0", @@ -3159,7 +3192,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -3173,29 +3206,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3226,15 +3259,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plotters" -version = "0.3.7" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -3245,15 +3278,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.7" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.7" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] @@ -3281,14 +3314,14 @@ dependencies = [ "parking_lot", "pin-project", "static_assertions", - "thiserror 1.0.69", + "thiserror 1.0.63", ] [[package]] name = "postcard" -version = "1.1.3" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" dependencies = [ "cobs", "embedded-io 0.4.0", @@ -3322,26 +3355,23 @@ dependencies = [ "spin 0.10.0", "symbolic-demangle", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.12", ] [[package]] name = "ppv-lite86" -version = "0.2.21" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.37" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -3365,22 +3395,23 @@ dependencies = [ [[package]] name = "priority-queue" -version = "2.7.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" +checksum = "714c75db297bc88a63783ffc6ab9f830698a6705aa0201416931759ef4c8183d" dependencies = [ + "autocfg", "equivalent", "indexmap 2.12.0", - "serde", ] [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "toml_edit 0.23.7", + "once_cell", + "toml_edit 0.19.15", ] [[package]] @@ -3402,7 +3433,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -3416,19 +3447,19 @@ dependencies = [ [[package]] name = "proptest" -version = "1.6.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.10.0", + "bitflags 2.9.0", "lazy_static", "num-traits", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", @@ -3460,7 +3491,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.109", + "syn 2.0.100", "tempfile", ] @@ -3474,7 +3505,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -3488,14 +3519,14 @@ dependencies = [ [[package]] name = "pwd-grp" -version = "1.0.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e2023f41b5fcb7c30eb5300a5733edfaa9e0e0d502d51b586f65633fd39e40c" +checksum = "b94fdf3867b7f2889a736f0022ea9386766280d2cca4bdbe41629ada9e4f3b8f" dependencies = [ - "derive-deftly", + "derive-deftly 0.14.2", "libc", "paste", - "thiserror 2.0.17", + "thiserror 1.0.63", ] [[package]] @@ -3515,9 +3546,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3581,7 +3612,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.15", ] [[package]] @@ -3625,9 +3656,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.11.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3635,9 +3666,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.13.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3666,7 +3697,7 @@ dependencies = [ "pasta_curves", "rand_core 0.6.4", "serde", - "thiserror 1.0.69", + "thiserror 1.0.63", "zeroize", ] @@ -3678,78 +3709,84 @@ checksum = "89b0ac1bc6bb3696d2c6f52cff8fba57238b81da8c0214ee6cd146eb8fde364e" dependencies = [ "rand_core 0.6.4", "reddsa", - "thiserror 1.0.69", + "thiserror 1.0.63", "zeroize", ] [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", ] [[package]] name = "redox_users" -version = "0.5.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.15", "libredox", - "thiserror 2.0.17", + "thiserror 1.0.63", ] [[package]] -name = "ref-cast" -version = "1.0.25" +name = "redox_users" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "ref-cast-impl", + "getrandom 0.2.15", + "libredox", + "thiserror 2.0.12", ] [[package]] -name = "ref-cast-impl" -version = "1.0.25" +name = "regex" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.109", + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] -name = "regex" -version = "1.12.2" +name = "regex-automata" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "retry-error" @@ -3769,9 +3806,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.52" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" dependencies = [ "bytemuck", ] @@ -3784,7 +3821,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.15", "libc", "untrusted", "windows-sys 0.52.0", @@ -3810,9 +3847,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.8" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ "const-oid", "digest 0.10.7", @@ -3822,7 +3859,7 @@ dependencies = [ "pkcs1", "pkcs8", "rand_core 0.6.4", - "sha2 0.10.9", + "sha2 0.10.8", "signature", "spki", "subtle", @@ -3835,7 +3872,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -3847,9 +3884,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.39.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35affe401787a9bd846712274d97654355d21b2a2c092a3139aabe31e9022282" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "num-traits", @@ -3858,15 +3895,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] @@ -3880,17 +3917,30 @@ dependencies = [ "nom", ] +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", +] + [[package]] name = "rustix" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.61.2", + "linux-raw-sys 0.11.0", + "windows-sys 0.60.2", ] [[package]] @@ -3907,27 +3957,24 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.8", + "rustls-webpki 0.103.1", "subtle", "zeroize", ] [[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" -dependencies = [ - "zeroize", -] +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] name = "rustls-webpki" @@ -3941,9 +3988,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ "ring", "rustls-pki-types", @@ -3952,15 +3999,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" dependencies = [ "fnv", "quick-error", @@ -3970,9 +4017,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safelog" @@ -3984,7 +4031,7 @@ dependencies = [ "educe", "either", "fluid-let", - "thiserror 2.0.17", + "thiserror 2.0.12", ] [[package]] @@ -4039,30 +4086,6 @@ dependencies = [ "zip32", ] -[[package]] -name = "schemars" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "schemars" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - [[package]] name = "schemerz" version = "0.2.0" @@ -4072,7 +4095,7 @@ dependencies = [ "daggy", "indexmap 1.9.3", "log", - "thiserror 1.0.69", + "thiserror 1.0.63", "uuid", ] @@ -4147,9 +4170,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" @@ -4188,37 +4211,34 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "serde_ignored" -version = "0.1.14" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115dffd5f3853e06e746965a20dcbae6ee747ae30b543d91b0e089668bb07798" +checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf" dependencies = [ "serde", - "serde_core", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", - "memchr", "ryu", "serde", - "serde_core", ] [[package]] name = "serde_spanned" -version = "0.6.9" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -4234,18 +4254,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.15.1" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" +checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", "indexmap 2.12.0", - "schemars 0.9.0", - "schemars 1.1.0", - "serde_core", + "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -4253,21 +4272,21 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.15.1" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" +checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" dependencies = [ - "darling 0.21.3", + "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", @@ -4276,9 +4295,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.9" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -4322,7 +4341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e95dcd06bc1bb3f86ed9db1e1832a70125f32daae071ef37dcb7701b7d4fe" dependencies = [ "assert_matches", - "bitflags 2.10.0", + "bitflags 2.9.0", "either", "incrementalmerkletree", "incrementalmerkletree-testing", @@ -4332,12 +4351,12 @@ dependencies = [ [[package]] name = "shellexpand" -version = "3.1.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" dependencies = [ "bstr", - "dirs", + "dirs 5.0.1", "os_str_bytes", ] @@ -4349,9 +4368,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -4366,12 +4385,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "sinsemilla" version = "0.1.0" @@ -4391,9 +4404,12 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "slotmap" @@ -4414,15 +4430,25 @@ dependencies = [ "paste", "serde", "slotmap", - "thiserror 2.0.17", + "thiserror 2.0.12", "void", ] [[package]] name = "smallvec" -version = "1.15.1" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] [[package]] name = "socket2" @@ -4477,14 +4503,14 @@ checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" dependencies = [ "base64ct", "pem-rfc7468", - "sha2 0.10.9", + "sha2 0.10.8", ] [[package]] name = "ssh-key" -version = "0.6.7" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" +checksum = "ca9b366a80cf18bb6406f4cf4d10aebfb46140a8c0c33f666a144c5c76ecbafc" dependencies = [ "num-bigint-dig", "p256", @@ -4493,7 +4519,7 @@ dependencies = [ "rand_core 0.6.4", "rsa", "sec1", - "sha2 0.10.9", + "sha2 0.10.8", "signature", "ssh-cipher", "ssh-encoding", @@ -4503,9 +4529,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "static_assertions" @@ -4531,13 +4557,35 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + [[package]] name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros", + "strum_macros 0.27.2", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", ] [[package]] @@ -4549,7 +4597,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -4560,9 +4608,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.16.3" +version = "12.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03f433c9befeea460a01d750e698aa86caf86dcfbd77d552885cd6c89d52f50" +checksum = "13a4dfe4bbeef59c1f32fc7524ae7c95b9e1de5e79a43ce1604e181081d71b0c" dependencies = [ "debugid", "memmap2", @@ -4572,9 +4620,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.16.3" +version = "12.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d359ef6192db1760a34321ec4f089245ede4342c27e59be99642f12a859de8" +checksum = "98cf6a95abff97de4d7ff3473f33cacd38f1ddccad5c1feab435d6760300e3b6" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -4594,9 +4642,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.109" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -4611,13 +4659,13 @@ checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "synstructure" -version = "0.13.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -4642,71 +4690,71 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ + "cfg-if", "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix", - "windows-sys 0.61.2", + "rustix 0.38.34", + "windows-sys 0.52.0", ] [[package]] name = "thiserror" -version = "1.0.69" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "thiserror-impl 1.0.69", + "thiserror-impl 1.0.63", ] [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.12", ] [[package]] name = "thiserror-impl" -version = "1.0.69" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", + "once_cell", ] [[package]] name = "time" -version = "0.3.37" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -4725,9 +4773,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -4735,12 +4783,11 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", - "serde_core", "zerovec", ] @@ -4756,9 +4803,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4771,38 +4818,40 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ + "backtrace", "bytes", "libc", - "mio", + "mio 0.8.11", + "num_cpus", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.9", "tokio-macros", - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.35", + "rustls 0.23.25", "tokio", ] @@ -4819,9 +4868,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", @@ -4833,14 +4882,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", + "serde_spanned 0.6.8", + "toml_datetime 0.6.8", + "toml_edit 0.22.22", ] [[package]] @@ -4855,14 +4904,14 @@ dependencies = [ "toml_datetime 0.7.3", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.13", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4878,28 +4927,26 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.12.0", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow", + "toml_datetime 0.6.8", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.23.7" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.12.0", - "toml_datetime 0.7.3", - "toml_parser", - "winnow", + "serde", + "serde_spanned 0.6.8", + "toml_datetime 0.6.8", + "winnow 0.6.20", ] [[package]] @@ -4908,15 +4955,9 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ - "winnow", + "winnow 0.7.13", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" version = "1.0.4" @@ -4941,7 +4982,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "socket2", + "socket2 0.6.1", "sync_wrapper", "tokio", "tokio-rustls", @@ -4950,7 +4991,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "webpki-roots 1.0.4", + "webpki-roots 1.0.3", ] [[package]] @@ -4962,7 +5003,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -4987,7 +5028,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.109", + "syn 2.0.100", "tempfile", "tonic-build", ] @@ -4998,13 +5039,13 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cad5e568ad4e025a68aa0395a146247609dd5b6d8c2141255f5e4f367e7fda8a" dependencies = [ - "derive-deftly", + "derive-deftly 1.3.0", "educe", "futures", "oneshot-fused-workaround", "pin-project", "postage", - "thiserror 2.0.17", + "thiserror 2.0.12", "void", ] @@ -5024,7 +5065,7 @@ dependencies = [ "serde", "slab", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.12", ] [[package]] @@ -5034,12 +5075,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fc7fb465ba671ee1486d8bd1e0a8f546887c2ce034004c4c9b03a6227e1c381" dependencies = [ "bytes", - "derive-deftly", + "derive-deftly 1.3.0", "digest 0.10.7", "educe", "getrandom 0.3.4", "safelog", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-error", "tor-llcrypto", "zeroize", @@ -5052,17 +5093,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79ba1b43f22fab2daee3e0c902f1455b3aed8e086b2d83d8c60b36523b173d25" dependencies = [ "amplify", - "bitflags 2.10.0", + "bitflags 2.9.0", "bytes", "caret", - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "educe", "itertools 0.14.0", "paste", "rand 0.9.2", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-basic-utils", "tor-bytes", "tor-cert", @@ -5085,7 +5126,7 @@ dependencies = [ "derive_builder_fork_arti", "derive_more", "digest 0.10.7", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-bytes", "tor-checkable", "tor-llcrypto", @@ -5108,7 +5149,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -5135,7 +5176,7 @@ checksum = "7c9839e9bb302f17447c350e290bb107084aca86c640882a91522f2059f6a686" dependencies = [ "humantime", "signature", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-llcrypto", ] @@ -5148,7 +5189,7 @@ dependencies = [ "amplify", "async-trait", "cfg-if", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "downcast-rs", @@ -5164,7 +5205,7 @@ dependencies = [ "retry-error", "safelog", "serde", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -5196,7 +5237,7 @@ checksum = "cb15df773842025010d885fbe862062ebaa342b799f9716273eaf733b92f2f45" dependencies = [ "amplify", "cfg-if", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "educe", "either", @@ -5211,8 +5252,8 @@ dependencies = [ "serde", "serde-value", "serde_ignored", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "toml 0.9.8", "tor-basic-utils", "tor-error", @@ -5230,7 +5271,7 @@ dependencies = [ "directories", "serde", "shellexpand", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-error", "tor-general-addr", ] @@ -5243,7 +5284,7 @@ checksum = "c1690438c1fc778fc7c89c132e529365b1430d6afe03aeecbc2508324807bf0b" dependencies = [ "digest 0.10.7", "hex", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-llcrypto", ] @@ -5263,7 +5304,7 @@ dependencies = [ "httpdate", "itertools 0.14.0", "memchr", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-circmgr", "tor-error", "tor-linkspec", @@ -5327,8 +5368,8 @@ dependencies = [ "serde_json", "signature", "static_assertions", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "time", "tor-async-utils", "tor-basic-utils", @@ -5361,8 +5402,8 @@ dependencies = [ "paste", "retry-error", "static_assertions", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "tracing", "void", ] @@ -5374,7 +5415,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c42cb5b5aec0584db2fba4a88c4e08fb09535ef61e4ef5674315a89e69ec31a2" dependencies = [ "derive_more", - "thiserror 2.0.17", + "thiserror 2.0.12", "void", ] @@ -5386,7 +5427,7 @@ checksum = "0585a83a4c56b4f31f6fa2965e2f9c490c9f4d29fba2fedb5a9ee71009f793c0" dependencies = [ "amplify", "base64ct", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "dyn-clone", @@ -5402,8 +5443,8 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -5428,7 +5469,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9ee6e0dbec9ba11c3d046181a42dd4759e108de38e2b5927689edbdc458a51" dependencies = [ "data-encoding", - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "digest 0.10.7", "hex", @@ -5440,7 +5481,7 @@ dependencies = [ "serde", "signature", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-basic-utils", "tor-bytes", "tor-error", @@ -5456,7 +5497,7 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa30066b80ade55a1b88a82b5320dfc50d1724918ad614ded8ecb4820c32062" dependencies = [ - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "downcast-rs", "paste", @@ -5464,7 +5505,7 @@ dependencies = [ "rsa", "signature", "ssh-key", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-bytes", "tor-cert", "tor-checkable", @@ -5481,7 +5522,7 @@ dependencies = [ "amplify", "arrayvec", "cfg-if", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "downcast-rs", @@ -5496,7 +5537,7 @@ dependencies = [ "serde", "signature", "ssh-key", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-basic-utils", "tor-bytes", "tor-config", @@ -5521,7 +5562,7 @@ dependencies = [ "base64ct", "by_address", "caret", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "hex", @@ -5529,8 +5570,8 @@ dependencies = [ "safelog", "serde", "serde_with", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "tor-basic-utils", "tor-bytes", "tor-config", @@ -5550,7 +5591,7 @@ dependencies = [ "ctr", "curve25519-dalek", "der-parser", - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "digest 0.10.7", "ed25519-dalek", @@ -5567,11 +5608,11 @@ dependencies = [ "safelog", "serde", "sha1", - "sha2 0.10.9", + "sha2 0.10.8", "sha3", "signature", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-error", "tor-memquota", "visibility", @@ -5587,7 +5628,7 @@ checksum = "845d65304be6a614198027c4b2d1b35aaf073335c26df619d17e5f4027f2657f" dependencies = [ "futures", "humantime", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-error", "tor-rtcompat", "tracing", @@ -5601,7 +5642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef375c3442a4ea74f0b6bf91a3eed660d55301b2e2f59b366aba4849b2321a6f" dependencies = [ "cfg-if", - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "dyn-clone", "educe", @@ -5613,7 +5654,7 @@ dependencies = [ "slotmap-careful", "static_assertions", "sysinfo", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -5631,7 +5672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "638b4e6507e3786488859d3c463fa73addbad4f788806c6972603727e527672e" dependencies = [ "async-trait", - "bitflags 2.10.0", + "bitflags 2.9.0", "derive_more", "futures", "humantime", @@ -5639,8 +5680,8 @@ dependencies = [ "num_enum", "rand 0.9.2", "serde", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "tor-basic-utils", "tor-error", "tor-linkspec", @@ -5660,9 +5701,9 @@ checksum = "1dbc32d89e7ea2e2799168d0c453061647a727e39fc66f52e1bcb4c38c8dc433" dependencies = [ "amplify", "base64ct", - "bitflags 2.10.0", + "bitflags 2.9.0", "cipher", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "digest 0.10.7", @@ -5677,9 +5718,9 @@ dependencies = [ "serde_with", "signature", "smallvec", - "strum", + "strum 0.27.2", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.12", "time", "tinystr", "tor-basic-utils", @@ -5701,7 +5742,7 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59e41aea027686b05f21e0ad75aa2c0c9681a87f2f3130b6d6f7a7a8c06edd7b" dependencies = [ - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "filetime", "fs-mistrust", @@ -5713,7 +5754,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.12", "time", "tor-async-utils", "tor-basic-utils", @@ -5737,7 +5778,7 @@ dependencies = [ "cipher", "coarsetime", "criterion-cycles-per-byte", - "derive-deftly", + "derive-deftly 1.3.0", "derive_builder_fork_arti", "derive_more", "digest 0.10.7", @@ -5760,7 +5801,7 @@ dependencies = [ "static_assertions", "subtle", "sync_wrapper", - "thiserror 2.0.17", + "thiserror 2.0.12", "tokio", "tokio-util", "tor-async-utils", @@ -5795,7 +5836,7 @@ dependencies = [ "caret", "paste", "serde_with", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-bytes", ] @@ -5833,8 +5874,8 @@ dependencies = [ "paste", "pin-project", "rustls-pki-types", - "rustls-webpki 0.103.8", - "thiserror 2.0.17", + "rustls-webpki 0.103.1", + "thiserror 2.0.12", "tokio", "tokio-util", "tor-error", @@ -5852,7 +5893,7 @@ dependencies = [ "amplify", "assert_matches", "async-trait", - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "educe", "futures", @@ -5862,8 +5903,8 @@ dependencies = [ "pin-project", "priority-queue", "slotmap-careful", - "strum", - "thiserror 2.0.17", + "strum 0.27.2", + "thiserror 2.0.12", "tor-error", "tor-general-addr", "tor-rtcompat", @@ -5880,11 +5921,11 @@ checksum = "0dbb9b68d9cf8e07eeafbca91ac11b7d9c4be1e674cb59830edfbac153333e7f" dependencies = [ "amplify", "caret", - "derive-deftly", + "derive-deftly 1.3.0", "educe", "safelog", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-bytes", "tor-error", ] @@ -5895,10 +5936,10 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48139f001dd6f409325b7c190ebcea1033b27f09042543946ab7aa4ad286257b" dependencies = [ - "derive-deftly", + "derive-deftly 1.3.0", "derive_more", "serde", - "thiserror 2.0.17", + "thiserror 2.0.12", "tor-memquota", ] @@ -5952,7 +5993,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -5978,14 +6019,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex-automata", + "regex", "sharded-slab", "smallvec", "thread_local", @@ -6012,7 +6053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -6023,7 +6064,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -6044,9 +6085,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.19.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uint" @@ -6077,15 +6118,15 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.25" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -6126,21 +6167,19 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] name = "uuid" -version = "1.18.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom 0.3.4", - "js-sys", + "getrandom 0.2.15", "serde", - "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vcpkg" @@ -6150,9 +6189,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "visibility" @@ -6162,7 +6201,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -6223,9 +6262,9 @@ checksum = "a7b6d5a78adc3e8f198e9cd730f219a695431467f7ec29dcfc63ade885feebe1" [[package]] name = "wait-timeout" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ "libc", ] @@ -6251,9 +6290,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasip2" @@ -6275,22 +6314,34 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", - "once_cell", - "rustversion", "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.100", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6298,25 +6349,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "bumpalo", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", + "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" -dependencies = [ - "unicode-ident", -] +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm_sync" @@ -6337,9 +6385,9 @@ checksum = "323f4da9523e9a669e1eaf9c6e763892769b1d38c623913647bfdc1532fe4549" [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -6353,9 +6401,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] @@ -6367,7 +6415,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ "env_home", - "rustix", + "rustix 1.1.2", "winsafe", ] @@ -6389,11 +6437,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.11" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6426,28 +6474,24 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.61.2" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.62.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", + "windows-link 0.1.3", + "windows-result", + "windows-strings", ] [[package]] @@ -6469,7 +6513,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -6480,7 +6524,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -6514,15 +6558,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -6533,12 +6568,12 @@ dependencies = [ ] [[package]] -name = "windows-strings" -version = "0.5.1" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-link 0.2.1", + "windows-targets 0.48.5", ] [[package]] @@ -6550,6 +6585,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.60.2" @@ -6560,12 +6604,18 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.61.2" +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows-link 0.2.1", + "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]] @@ -6610,6 +6660,12 @@ 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" @@ -6622,6 +6678,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -6634,6 +6696,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6658,6 +6726,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -6670,6 +6744,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -6682,6 +6762,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -6694,6 +6780,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -6708,13 +6800,28 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" + [[package]] name = "winsafe" version = "0.0.19" @@ -6754,6 +6861,15 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "zcash" version = "0.1.0" @@ -6837,7 +6953,7 @@ dependencies = [ "tower", "tracing", "trait-variant", - "webpki-roots 1.0.4", + "webpki-roots 1.0.3", "which", "zcash_address", "zcash_encoding", @@ -6880,7 +6996,7 @@ dependencies = [ "shardtree", "static_assertions", "subtle", - "thiserror 1.0.69", + "thiserror 1.0.63", "time", "tokio", "tracing", @@ -6904,7 +7020,7 @@ dependencies = [ "ambassador", "assert_matches", "bip32", - "bitflags 2.10.0", + "bitflags 2.9.0", "bls12_381", "bs58", "byteorder", @@ -6960,6 +7076,7 @@ dependencies = [ "core2", "hex", "nonempty", + "proptest", ] [[package]] @@ -7076,7 +7193,7 @@ dependencies = [ "ripemd 0.1.3", "sapling-crypto", "secp256k1", - "sha2 0.10.9", + "sha2 0.10.8", "subtle", "tracing", "zcash_address", @@ -7133,14 +7250,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bed6cf5b2b4361105d4ea06b2752f0c8af4641756c7fbc9858a80af186c234f" dependencies = [ "bip32", - "bitflags 2.10.0", + "bitflags 2.9.0", "bounded-vec", "hex", "ripemd 0.1.3", "secp256k1", "sha1", - "sha2 0.10.9", - "thiserror 2.0.17", + "sha2 0.10.8", + "thiserror 2.0.12", ] [[package]] @@ -7166,7 +7283,7 @@ dependencies = [ "proptest", "ripemd 0.1.3", "secp256k1", - "sha2 0.10.9", + "sha2 0.10.8", "subtle", "zcash_address", "zcash_encoding", @@ -7178,22 +7295,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] @@ -7204,9 +7321,9 @@ checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" [[package]] name = "zeroize" -version = "1.8.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -7219,26 +7336,24 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.100", ] [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "94e62113720e311984f461c56b00457ae9981c0bc7859d22306cc2ae2f95571c" dependencies = [ - "serde", "zerofrom", ] [[package]] name = "zip32" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64bf5186a8916f7a48f2a98ef599bf9c099e2458b36b819e393db1c0e768c4b" +checksum = "13ff9ea444cdbce820211f91e6aa3d3a56bde7202d3c0961b7c38f793abf5637" dependencies = [ - "bech32", "blake2b_simd", "memuse", "subtle", @@ -7259,27 +7374,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.4" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" +version = "2.0.10+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" dependencies = [ "cc", "pkg-config", diff --git a/components/zcash_encoding/Cargo.toml b/components/zcash_encoding/Cargo.toml index 4ba7fcfb1a..a657d9a3a9 100644 --- a/components/zcash_encoding/Cargo.toml +++ b/components/zcash_encoding/Cargo.toml @@ -20,6 +20,9 @@ core2.workspace = true hex.workspace = true nonempty.workspace = true +[dev-dependencies] +proptest.workspace = true + [features] default = ["std"] std = ["core2/std"] diff --git a/components/zcash_encoding/src/lib.rs b/components/zcash_encoding/src/lib.rs index e43f291c63..4c3c32ab8b 100644 --- a/components/zcash_encoding/src/lib.rs +++ b/components/zcash_encoding/src/lib.rs @@ -307,18 +307,41 @@ impl Optional { pub struct ReverseHex; impl ReverseHex { - /// Decodes a reversed-hex string into a byte array. - pub fn decode(bytes: &[u8; 32]) -> alloc::string::String { + /// Encodes a byte array by reversing the order of the bytes and then hex encoding + pub fn encode(bytes: &[u8; 32]) -> alloc::string::String { let mut reversed = *bytes; reversed.reverse(); hex::encode(reversed) } + + /// Decodes a reversed-hex string into a byte array by decoding the hex and + /// reversing the order of the bytes. + pub fn decode(hex_str: &str) -> Option<[u8; 32]> { + let mut bytes = [0; 32]; + let res = hex::decode_to_slice(hex_str, &mut bytes); + if res.is_err() { + return None; + } + + bytes.reverse(); + Some(bytes) + } } #[cfg(test)] mod tests { use super::*; use core::fmt::Debug; + use proptest::prelude::*; + + proptest! { + #[test] + fn reverse_hex_roundtrip(bytes in prop::array::uniform32(any::())) { + let encoded = ReverseHex::encode(&bytes); + let decoded = ReverseHex::decode(&encoded); + prop_assert_eq!(decoded, Some(bytes)); + } + } #[test] fn compact_size() { diff --git a/components/zcash_protocol/src/txid.rs b/components/zcash_protocol/src/txid.rs index bc804b4fe3..02769b7fde 100644 --- a/components/zcash_protocol/src/txid.rs +++ b/components/zcash_protocol/src/txid.rs @@ -31,7 +31,7 @@ impl fmt::Debug for TxId { impl fmt::Display for TxId { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str(&ReverseHex::decode(&self.0)) + formatter.write_str(&ReverseHex::encode(&self.0)) } } @@ -48,17 +48,6 @@ impl From for [u8; 32] { } impl TxId { - /// Creates a TxId from a reverse hex string - /// - /// See `zcash_encoding::decode_reverse_hex` for more context. - pub const fn from_reverse_hex(hex_str: &str) -> RpcResult { - let mut bytes = [0; 32]; - hex::decode_to_slice(hex_str, &mut bytes) - .map_err(|_| RpcError::ParseError("Invalid hex string".to_string()))?; - bytes.reverse(); - Ok(TxId(bytes)) - } - /// Wraps the given byte array as a TxId value pub const fn from_bytes(bytes: [u8; 32]) -> Self { TxId(bytes) From b664dbd5693d7fe12dbc8f51d40ed2c42416d571 Mon Sep 17 00:00:00 2001 From: Ryan Quinn Ford Date: Tue, 11 Nov 2025 08:03:24 +0100 Subject: [PATCH 007/263] fix(zcash_encoding): CHANGELOG + rustdoc --- components/zcash_encoding/CHANGELOG.md | 2 ++ components/zcash_encoding/src/lib.rs | 3 +++ 2 files changed, 5 insertions(+) diff --git a/components/zcash_encoding/CHANGELOG.md b/components/zcash_encoding/CHANGELOG.md index 85367fb7f1..61cce2c082 100644 --- a/components/zcash_encoding/CHANGELOG.md +++ b/components/zcash_encoding/CHANGELOG.md @@ -6,6 +6,8 @@ and this library adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `zcash_encoding::ReverseHex::{encode, decode}` ## [0.3.0] - 2025-02-21 ### Changed diff --git a/components/zcash_encoding/src/lib.rs b/components/zcash_encoding/src/lib.rs index 4c3c32ab8b..51d79d16de 100644 --- a/components/zcash_encoding/src/lib.rs +++ b/components/zcash_encoding/src/lib.rs @@ -316,6 +316,9 @@ impl ReverseHex { /// Decodes a reversed-hex string into a byte array by decoding the hex and /// reversing the order of the bytes. + /// + /// Returns `None` if the hex decoding fails or if the output is the wrong + /// size. pub fn decode(hex_str: &str) -> Option<[u8; 32]> { let mut bytes = [0; 32]; let res = hex::decode_to_slice(hex_str, &mut bytes); From 75337cd455016f6f5285a4c07ec5990e602447cd Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Wed, 22 Oct 2025 16:41:58 +1300 Subject: [PATCH 008/263] added TestBuilder::with_standard_sapling_account, style nit DSF -> Dsf --- zcash_client_backend/src/data_api/testing.rs | 23 +- .../src/data_api/testing/pool.rs | 405 +++++++----------- 2 files changed, 182 insertions(+), 246 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index eaa5c9289d..4f4486d0ed 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -1468,6 +1468,27 @@ impl TestBuilder<(), ()> { gap_limits: None, } } + + /// Equip the builder with the provided [`DataStoreFactory`] and [`TestCache`], + /// as well as an account that has a birthday at Sapling activation. + /// + /// Shorthand for the following: + /// ```rust,ignore + /// let mut st = TestBuilder::new() + /// .with_data_store_factory(dsf) + /// .with_block_cache(tc) + /// .with_account_from_sapling_activation(BlockHash([0; 32])) + /// .build(); + /// ``` + pub fn with_standard_sapling_account( + self, + dsf: Dsf, + tc: Tc, + ) -> TestBuilder { + self.with_data_store_factory(dsf) + .with_block_cache(tc) + .with_account_from_sapling_activation(BlockHash([0; 32])) + } } impl Default for TestBuilder<(), ()> { @@ -1478,7 +1499,7 @@ impl Default for TestBuilder<(), ()> { impl TestBuilder<(), A> { /// Adds a block cache to the test environment. - pub fn with_block_cache(self, cache: C) -> TestBuilder { + pub fn with_block_cache(self, cache: C) -> TestBuilder { TestBuilder { rng: self.rng, network: self.network, diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 908c66375a..acbe57a447 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -2,11 +2,11 @@ use std::{ cmp::Eq, convert::Infallible, hash::Hash, - num::{NonZeroU8, NonZeroU32, NonZeroU64, NonZeroUsize}, + num::{NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}, }; use assert_matches::assert_matches; -use incrementalmerkletree::{Level, Position, frontier::Frontier}; +use incrementalmerkletree::{frontier::Frontier, Level, Position}; use rand::{Rng, RngCore}; use secrecy::Secret; use shardtree::error::ShardTreeError; @@ -16,40 +16,42 @@ use zcash_keys::{address::Address, keys::UnifiedSpendingKey}; use zcash_primitives::{ block::BlockHash, transaction::{ - Transaction, fees::zip317::{FeeRule as Zip317FeeRule, MARGINAL_FEE, MINIMUM_FEE}, + Transaction, }, }; use zcash_protocol::{ - ShieldedProtocol, consensus::{self, BlockHeight, NetworkUpgrade, Parameters}, local_consensus::LocalNetwork, memo::{Memo, MemoBytes}, value::Zatoshis, + ShieldedProtocol, }; use zip32::Scope; use zip321::{Payment, TransactionRequest}; use crate::{ data_api::{ - self, Account as _, AccountBirthday, BoundedU8, DecryptedTransaction, InputSource, - MaxSpendMode, NoteFilter, Ratio, TargetValue, WalletCommitmentTrees, WalletRead, - WalletSummary, WalletTest, WalletWrite, + self, chain::{self, ChainState, CommitmentTreeRoot, ScanSummary}, error::Error, testing::{ - AddressType, CacheInsertionResult, CachedBlock, FakeCompactOutput, InitialChainState, - TestBuilder, single_output_change_strategy, + single_output_change_strategy, AddressType, CacheInsertionResult, CachedBlock, + FakeCompactOutput, InitialChainState, TestBuilder, }, wallet::{ - ConfirmationsPolicy, TargetHeight, TransferErrT, decrypt_and_store_transaction, - input_selection::GreedyInputSelector, + decrypt_and_store_transaction, input_selection::GreedyInputSelector, + ConfirmationsPolicy, TargetHeight, TransferErrT, }, + Account as _, AccountBirthday, BoundedU8, DecryptedTransaction, InputSource, MaxSpendMode, + NoteFilter, Ratio, TargetValue, WalletCommitmentTrees, WalletRead, WalletSummary, + WalletTest, WalletWrite, }, decrypt_transaction, fees::{ - self, DustOutputPolicy, SplitPolicy, StandardFeeRule, + self, standard::{self, SingleOutputChangeStrategy}, + DustOutputPolicy, SplitPolicy, StandardFeeRule, }, scanning::ScanError, wallet::{Note, NoteId, OvkPolicy, ReceivedNote}, @@ -72,7 +74,7 @@ use { keys::{NonHardenedChildIndex, TransparentKeyScope}, }, zcash_primitives::transaction::fees::zip317, - zcash_protocol::{TxId, value::ZatBalance}, + zcash_protocol::{value::ZatBalance, TxId}, }; #[cfg(feature = "orchard")] @@ -202,9 +204,7 @@ pub fn send_single_step_proposed_transfer( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -388,9 +388,7 @@ pub fn zip_315_confirmations_test_steps( input_trust: InputTrust, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -489,9 +487,7 @@ pub fn spend_max_spendable_single_step_proposed_transfer( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -655,9 +651,7 @@ pub fn spend_everything_single_step_proposed_transfer( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -811,9 +805,7 @@ pub fn fails_to_send_max_spendable_to_transparent_with_memo( - ds_factory: DSF, +pub fn spend_everything_multi_step_single_note_proposed_transfer( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { - use crate::data_api::{MaxSpendMode, OutputOfSentTx, testing::transparent::GapLimits}; + use crate::data_api::{testing::transparent::GapLimits, MaxSpendMode, OutputOfSentTx}; let gap_limits = GapLimits::new(10, 5, 3); let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .with_gap_limits(gap_limits) .build(); @@ -1140,7 +1126,7 @@ pub fn spend_everything_multi_step_single_note_proposed_transfer, value| { + let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); st.scan_cached_blocks(h, 1); @@ -1295,20 +1281,18 @@ pub fn spend_everything_multi_step_single_note_proposed_transfer( - ds_factory: DSF, +pub fn spend_everything_multi_step_many_notes_proposed_transfer( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { - use crate::data_api::{OutputOfSentTx, testing::transparent::GapLimits}; + use crate::data_api::{testing::transparent::GapLimits, OutputOfSentTx}; let gap_limits = GapLimits::new(10, 5, 3); let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .with_gap_limits(gap_limits) .build(); @@ -1316,7 +1300,7 @@ pub fn spend_everything_multi_step_many_notes_proposed_transfer, value| { + let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); st.scan_cached_blocks(h, 1); @@ -1468,21 +1452,19 @@ pub fn spend_everything_multi_step_many_notes_proposed_transfer( - ds_factory: DSF, + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { - use crate::data_api::{MaxSpendMode, OutputOfSentTx, testing::transparent::GapLimits}; + use crate::data_api::{testing::transparent::GapLimits, MaxSpendMode, OutputOfSentTx}; let gap_limits = GapLimits::new(10, 5, 3); let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .with_gap_limits(gap_limits) .build(); @@ -1490,7 +1472,7 @@ pub fn spend_everything_multi_step_with_marginal_notes_proposed_transfer< let account_id = account.id(); let dfvk = T::test_account_fvk(&st); - let add_funds = |st: &mut TestState<_, DSF::DataStore, _>, value| { + let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); st.scan_cached_blocks(h, 1); @@ -1647,9 +1629,7 @@ pub fn send_with_multiple_change_outputs( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -1827,24 +1807,21 @@ pub fn send_with_multiple_change_outputs( } #[cfg(feature = "transparent-inputs")] -pub fn send_multi_step_proposed_transfer( - ds_factory: DSF, +pub fn send_multi_step_proposed_transfer( + ds_factory: Dsf, cache: impl TestCache, - is_reached_gap_limit: impl Fn(&::Error, DSF::AccountId, u32) -> bool, + is_reached_gap_limit: impl Fn(&::Error, Dsf::AccountId, u32) -> bool, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, { use crate::{ - data_api::{OutputOfSentTx, TransactionStatus, testing::transparent::GapLimits}, + data_api::{testing::transparent::GapLimits, OutputOfSentTx, TransactionStatus}, wallet::{Exposure, TransparentAddressSource}, }; let gap_limits = GapLimits::new(10, 5, 3); let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .with_gap_limits(gap_limits) .build(); @@ -1853,7 +1830,7 @@ pub fn send_multi_step_proposed_transfer( let dfvk = T::test_account_fvk(&st); let tex_addr = Address::Tex([0x4; 20]); - let add_funds = |st: &mut TestState<_, DSF::DataStore, _>, value| { + let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); st.scan_cached_blocks(h, 1); @@ -1871,7 +1848,7 @@ pub fn send_multi_step_proposed_transfer( let value = Zatoshis::const_from_u64(100000); let transfer_amount = Zatoshis::const_from_u64(50000); - let run_test = |st: &mut TestState<_, DSF::DataStore, _>, expected_index, prior_balance| { + let run_test = |st: &mut TestState<_, Dsf::DataStore, _>, expected_index, prior_balance| { // Add funds to the wallet. add_funds(st, value); let initial_balance: Option = prior_balance + value; @@ -2127,7 +2104,7 @@ pub fn send_multi_step_proposed_transfer( "new_known_addrs must have known_addrs as its prefix" ); - let reservation_should_succeed = |st: &mut TestState<_, DSF::DataStore, _>, n: u32| { + let reservation_should_succeed = |st: &mut TestState<_, Dsf::DataStore, _>, n: u32| { let reserved = st .wallet_mut() .reserve_next_n_ephemeral_addresses(account_id, n.try_into().unwrap()) @@ -2136,7 +2113,7 @@ pub fn send_multi_step_proposed_transfer( reserved }; let reservation_should_fail = - |st: &mut TestState<_, DSF::DataStore, _>, n: u32, expected_bad_index| { + |st: &mut TestState<_, Dsf::DataStore, _>, n: u32, expected_bad_index| { assert_matches!(st .wallet_mut() .reserve_next_n_ephemeral_addresses(account_id, n.try_into().unwrap()), @@ -2195,9 +2172,7 @@ pub fn spend_all_funds_single_step_proposed_transfer( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -2360,20 +2335,18 @@ pub fn spend_all_funds_single_step_proposed_transfer( /// - all funds are spent /// - Fees are the least possible: in this case 15000 for tr0 and 10000 Zats for tr1 #[cfg(feature = "transparent-inputs")] -pub fn spend_all_funds_multi_step_proposed_transfer( - ds_factory: DSF, +pub fn spend_all_funds_multi_step_proposed_transfer( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { - use crate::data_api::{OutputOfSentTx, testing::transparent::GapLimits}; + use crate::data_api::{testing::transparent::GapLimits, OutputOfSentTx}; let gap_limits = GapLimits::new(10, 5, 3); let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .with_gap_limits(gap_limits) .build(); @@ -2523,23 +2496,21 @@ pub fn spend_all_funds_multi_step_proposed_transfer( } #[cfg(feature = "transparent-inputs")] -pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( - ds_factory: DSF, +pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, + Dsf: DataStoreFactory, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); let dfvk = T::test_account_fvk(&st); - let add_funds = |st: &mut TestState<_, DSF::DataStore, _>, value| { + let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); st.scan_cached_blocks(h, 1); @@ -2609,12 +2580,11 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( - ds_factory: DSF, +pub fn create_to_address_fails_on_incorrect_usk( + ds_factory: Dsf, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, ()) .build(); let dfvk = T::test_account_fvk(&st); let to = T::fvk_default_address(&dfvk); @@ -2623,7 +2593,7 @@ pub fn create_to_address_fails_on_incorrect_usk::new(); + let input_selector = GreedyInputSelector::::new(); let change_strategy = single_output_change_strategy(StandardFeeRule::Zip317, None, T::SHIELDED_PROTOCOL); @@ -2647,14 +2617,13 @@ pub fn create_to_address_fails_on_incorrect_usk(ds_factory: DSF) +pub fn proposal_fails_with_no_blocks(ds_factory: Dsf) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, ()) .build(); let account_id = st.test_account().unwrap().id(); @@ -2685,9 +2654,7 @@ pub fn spend_fails_on_unverified_notes( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -2879,9 +2846,7 @@ pub fn spend_fails_on_locked_notes( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3021,16 +2986,14 @@ pub fn spend_fails_on_locked_notes( ); } -pub fn ovk_policy_prevents_recovery_from_chain( - ds_factory: DSF, +pub fn ovk_policy_prevents_recovery_from_chain( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, + Dsf: DataStoreFactory, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3055,14 +3018,14 @@ pub fn ovk_policy_prevents_recovery_from_chain( let fee_rule = StandardFeeRule::Zip317; #[allow(clippy::type_complexity)] - let send_and_recover_with_policy = |st: &mut TestState<_, DSF::DataStore, _>, + let send_and_recover_with_policy = |st: &mut TestState<_, Dsf::DataStore, _>, ovk_policy| -> Result< Option<(Note, Address, MemoBytes)>, TransferErrT< - DSF::DataStore, - GreedyInputSelector, - SingleOutputChangeStrategy, + Dsf::DataStore, + GreedyInputSelector, + SingleOutputChangeStrategy, >, > { let proposal = st.propose_standard_transfer( @@ -3120,9 +3083,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3170,9 +3131,7 @@ pub fn change_note_spends_succeed( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3403,12 +3362,12 @@ where ); } -pub fn external_address_change_spends_detected_in_restore_from_seed( - ds_factory: DSF, +pub fn external_address_change_spends_detected_in_restore_from_seed( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::DataStore: Reset, + Dsf: DataStoreFactory, + ::DataStore: Reset, { let mut st = TestBuilder::new() .with_data_store_factory(ds_factory) @@ -3519,14 +3478,12 @@ pub fn external_address_change_spends_detected_in_restore_from_seed( - ds_factory: DSF, +pub fn zip317_spend( + ds_factory: Dsf, cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3559,7 +3516,7 @@ pub fn zip317_spend( total ); - let input_selector = GreedyInputSelector::::new(); + let input_selector = GreedyInputSelector::::new(); let change_strategy = single_output_change_strategy(StandardFeeRule::Zip317, None, T::SHIELDED_PROTOCOL); @@ -3616,18 +3573,16 @@ pub fn zip317_spend( } #[cfg(feature = "transparent-inputs")] -pub fn shield_transparent(ds_factory: DSF, cache: impl TestCache) +pub fn shield_transparent(ds_factory: Dsf, cache: impl TestCache) where - DSF: DataStoreFactory, - <::DataStore as WalletWrite>::UtxoRef: std::fmt::Debug, + Dsf: DataStoreFactory, + <::DataStore as WalletWrite>::UtxoRef: std::fmt::Debug, { use zcash_keys::keys::UnifiedAddressRequest; use zcash_primitives::transaction::builder::DEFAULT_TX_EXPIRY_DELTA; let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3698,11 +3653,9 @@ where // Verify that a transaction enhancement request for the transaction containing the spent // outpoint does not yet exist. let requests = st.wallet().transaction_data_requests().unwrap(); - assert!( - !requests - .iter() - .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid())) - ); + assert!(!requests + .iter() + .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid()))); // Use `decrypt_and_store_transaction` for the side effect of creating enhancement requests for // the transparent inputs of the transaction. @@ -3716,11 +3669,9 @@ where // Verify that a transaction enhancement request for the received transaction was created let requests = st.wallet().transaction_data_requests().unwrap(); - assert!( - requests - .iter() - .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid())) - ); + assert!(requests + .iter() + .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid()))); // Now advance the chain by 40 blocks; even though a record for the transaction that created // `spent_outpoint` exists in the wallet database, the transaction can't be enhanced because @@ -3747,11 +3698,9 @@ where // Verify that the transaction enhancement request for the invalid txid has been deleted. let requests = st.wallet().transaction_data_requests().unwrap(); - assert!( - !requests - .iter() - .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid())) - ); + assert!(!requests + .iter() + .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid()))); } // FIXME: This requires fixes to the test framework. @@ -3875,14 +3824,12 @@ pub fn birthday_in_anchor_shard( assert_eq!(spendable.len(), 1); } -pub fn checkpoint_gaps( - ds_factory: DSF, +pub fn checkpoint_gaps( + ds_factory: Dsf, cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -3933,7 +3880,7 @@ pub fn checkpoint_gaps( .unwrap(); assert_eq!(spendable.len(), 1); - let input_selector = GreedyInputSelector::::new(); + let input_selector = GreedyInputSelector::::new(); let change_strategy = single_output_change_strategy(StandardFeeRule::Zip317, None, T::SHIELDED_PROTOCOL); @@ -3968,10 +3915,8 @@ pub fn pool_crossing_required( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) // TODO: Allow for Orchard - // activation after Sapling + .with_standard_sapling_account(ds_factory, cache) + // TODO: Allow for Orchard activation after Sapling .build(); let account = st.test_account().cloned().unwrap(); @@ -4060,10 +4005,8 @@ pub fn fully_funded_fully_private( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) // TODO: Allow for Orchard - // activation after Sapling + .with_standard_sapling_account(ds_factory, cache) + // TODO: Allow for Orchard activation after Sapling .build(); let account = st.test_account().cloned().unwrap(); @@ -4248,10 +4189,8 @@ pub fn multi_pool_checkpoint( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) // TODO: Allow for Orchard - // activation after Sapling + .with_standard_sapling_account(ds_factory, cache) + // TODO: Allow for Orchard activation after Sapling .build(); let account = st.test_account().cloned().unwrap(); @@ -4421,10 +4360,8 @@ pub fn multi_pool_checkpoints_with_pruning( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let dfvk = T::test_account_fvk(&st); @@ -4493,9 +4428,7 @@ pub fn invalid_chain_cache_disconnected( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let dfvk = T::test_account_fvk(&st); @@ -4546,15 +4479,13 @@ pub fn invalid_chain_cache_disconnected( ); } -pub fn data_db_truncation(ds_factory: DSF, cache: impl TestCache) +pub fn data_db_truncation(ds_factory: Dsf, cache: impl TestCache) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -4611,23 +4542,21 @@ where ); } -pub fn reorg_to_checkpoint(ds_factory: DSF, cache: C) +pub fn reorg_to_checkpoint(ds_factory: Dsf, cache: C) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, C: TestCache, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); // Create a sequence of blocks to serve as the foundation of our chain state. let p0_fvk = T::random_fvk(st.rng_mut()); - let gen_random_block = |st: &mut TestState, + let gen_random_block = |st: &mut TestState, output_count: usize| { let fake_outputs = std::iter::repeat_with(|| FakeCompactOutput::random(st.rng_mut(), p0_fvk.clone())) @@ -4756,9 +4685,7 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -4807,17 +4734,15 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( ); } -pub fn scan_cached_blocks_finds_received_notes( - ds_factory: DSF, +pub fn scan_cached_blocks_finds_received_notes( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -4857,17 +4782,15 @@ pub fn scan_cached_blocks_finds_received_notes( } // TODO: This test can probably be entirely removed, as the following test duplicates it entirely. -pub fn scan_cached_blocks_finds_change_notes( - ds_factory: DSF, +pub fn scan_cached_blocks_finds_change_notes( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -4903,17 +4826,15 @@ pub fn scan_cached_blocks_finds_change_notes( ); } -pub fn scan_cached_blocks_detects_spends_out_of_order( - ds_factory: DSF, +pub fn scan_cached_blocks_detects_spends_out_of_order( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -4952,18 +4873,16 @@ pub fn scan_cached_blocks_detects_spends_out_of_order( - ds_factory: DSF, +pub fn metadata_queries_exclude_unwanted_notes( + ds_factory: Dsf, cache: TC, ) where - DSF: DataStoreFactory, - ::AccountId: std::fmt::Debug, + Dsf: DataStoreFactory, + ::AccountId: std::fmt::Debug, TC: TestCache, { let mut st = TestBuilder::new() - .with_data_store_factory(ds_factory) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(ds_factory, cache) .build(); let account = st.test_account().cloned().unwrap(); @@ -4981,7 +4900,7 @@ pub fn metadata_queries_exclude_unwanted_notes( st.scan_cached_blocks(h0, 10); let target_height = TargetHeight::from(h0 + 10); - let test_meta = |st: &TestState, query, expected_count| { + let test_meta = |st: &TestState, query, expected_count| { let metadata = st .wallet() .get_account_metadata(account.id(), &query, target_height, &[]) @@ -5040,12 +4959,12 @@ pub fn metadata_queries_exclude_unwanted_notes( } #[cfg(feature = "pczt")] -pub fn pczt_single_step( - ds_factory: DSF, +pub fn pczt_single_step( + ds_factory: Dsf, cache: impl TestCache, ) where - DSF: DataStoreFactory, - ::AccountId: serde::Serialize + serde::de::DeserializeOwned, + Dsf: DataStoreFactory, + ::AccountId: serde::Serialize + serde::de::DeserializeOwned, { use zcash_protocol::consensus::ZIP212_GRACE_PERIOD; @@ -5171,9 +5090,7 @@ pub fn wallet_recovery_computes_fees( cache: impl TestCache, ) { let mut st = TestBuilder::new() - .with_data_store_factory(dsf) - .with_block_cache(cache) - .with_account_from_sapling_activation(BlockHash([0; 32])) + .with_standard_sapling_account(dsf, cache) .build(); let account = st.test_account().cloned().unwrap(); From a3f5457c76d8ef56dea164760365ae71d562d818 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Fri, 24 Oct 2025 12:53:02 +1300 Subject: [PATCH 009/263] Added TestDsl, moved TestBuilder convenience methods there --- zcash_client_backend/src/data_api/testing.rs | 21 -- .../src/data_api/testing/pool.rs | 221 +++++++----------- .../src/data_api/testing/pool/dsl.rs | 84 +++++++ 3 files changed, 162 insertions(+), 164 deletions(-) create mode 100644 zcash_client_backend/src/data_api/testing/pool/dsl.rs diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index 4f4486d0ed..0c4cb097d4 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -1468,27 +1468,6 @@ impl TestBuilder<(), ()> { gap_limits: None, } } - - /// Equip the builder with the provided [`DataStoreFactory`] and [`TestCache`], - /// as well as an account that has a birthday at Sapling activation. - /// - /// Shorthand for the following: - /// ```rust,ignore - /// let mut st = TestBuilder::new() - /// .with_data_store_factory(dsf) - /// .with_block_cache(tc) - /// .with_account_from_sapling_activation(BlockHash([0; 32])) - /// .build(); - /// ``` - pub fn with_standard_sapling_account( - self, - dsf: Dsf, - tc: Tc, - ) -> TestBuilder { - self.with_data_store_factory(dsf) - .with_block_cache(tc) - .with_account_from_sapling_activation(BlockHash([0; 32])) - } } impl Default for TestBuilder<(), ()> { diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index acbe57a447..77d2f8bb9e 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -86,6 +86,9 @@ use { zcash_proofs::prover::LocalTxProver, }; +pub mod dsl; +use dsl::TestDsl; + /// Trait that exposes the pool-specific types and operations necessary to run the /// single-shielded-pool tests on a given pool. /// @@ -203,9 +206,7 @@ pub fn send_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -387,9 +388,7 @@ pub fn zip_315_confirmations_test_steps( cache: impl TestCache, input_trust: InputTrust, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); let starting_balance = Zatoshis::const_from_u64(60_000); @@ -486,9 +485,7 @@ pub fn spend_max_spendable_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -527,11 +524,12 @@ pub fn spend_max_spendable_single_step_proposed_transfer( let send_max_memo = "Test Send Max memo".parse::().unwrap(); + let addy = to.to_zcash_address(st.network()); let proposal = st .propose_send_max_transfer( account.id(), &fee_rule, - to.to_zcash_address(st.network()), + addy, Some(MemoBytes::from(send_max_memo.clone())), MaxSpendMode::MaxSpendable, confirmation_policy, @@ -650,9 +648,7 @@ pub fn spend_everything_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -685,11 +681,12 @@ pub fn spend_everything_single_step_proposed_transfer( let send_max_memo = "Test Send Max memo".parse::().unwrap(); + let addy = to.to_zcash_address(st.network()); let proposal = st .propose_send_max_transfer( account.id(), &fee_rule, - to.to_zcash_address(st.network()), + addy, Some(MemoBytes::from(send_max_memo.clone())), MaxSpendMode::Everything, ConfirmationsPolicy::MIN, @@ -804,9 +801,7 @@ pub fn fails_to_send_max_spendable_to_transparent_with_memo().unwrap(); + let addy = to.to_zcash_address(st.network()); assert_matches!( st.propose_send_max_transfer( account.id(), &fee_rule, - to.to_zcash_address(st.network()), + addy, Some(MemoBytes::from(send_max_memo.clone())), MaxSpendMode::Everything, ConfirmationsPolicy::MIN @@ -870,9 +866,7 @@ pub fn spend_everything_proposal_fails_when_unconfirmed_funds_present().unwrap(); + let addy = to.to_zcash_address(st.network()); assert_matches!( st.propose_send_max_transfer( account.id(), &fee_rule, - to.to_zcash_address(st.network()), + addy, Some(MemoBytes::from(send_max_memo.clone())), MaxSpendMode::Everything, ConfirmationsPolicy::new_symmetrical_unchecked( @@ -950,9 +945,7 @@ pub fn send_max_spendable_proposal_succeeds_when_unconfirmed_funds_present< dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -996,11 +989,12 @@ pub fn send_max_spendable_proposal_succeeds_when_unconfirmed_funds_present< let send_max_memo = "Test Send Max memo".parse::().unwrap(); + let addy = to.to_zcash_address(st.network()); let proposal = st .propose_send_max_transfer( account.id(), &fee_rule, - to.to_zcash_address(st.network()), + addy, Some(MemoBytes::from(send_max_memo.clone())), MaxSpendMode::MaxSpendable, ConfirmationsPolicy::new_symmetrical_unchecked( @@ -1116,10 +1110,8 @@ pub fn spend_everything_multi_step_single_note_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -1820,9 +1809,8 @@ pub fn send_multi_step_proposed_transfer( }; let gap_limits = GapLimits::new(10, 5, 3); - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .with_gap_limits(gap_limits) + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) + .map(|builder| builder.with_gap_limits(gap_limits)) .build(); let account = st.test_account().cloned().unwrap(); @@ -2171,9 +2159,7 @@ pub fn spend_all_funds_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -2344,10 +2330,8 @@ pub fn spend_all_funds_multi_step_proposed_transfer( { use crate::data_api::{testing::transparent::GapLimits, OutputOfSentTx}; - let gap_limits = GapLimits::new(10, 5, 3); - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .with_gap_limits(gap_limits) + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) + .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) .build(); let account = st.test_account().cloned().unwrap(); @@ -2502,9 +2486,7 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( ds_factory: Dsf, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, ()) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build(); let dfvk = T::test_account_fvk(&st); let to = T::fvk_default_address(&dfvk); @@ -2622,9 +2602,7 @@ where Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, ()) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build(); let account_id = st.test_account().unwrap().id(); let dfvk = T::test_account_fvk(&st); @@ -2653,9 +2631,7 @@ pub fn spend_fails_on_unverified_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2845,9 +2821,7 @@ pub fn spend_fails_on_locked_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2992,9 +2966,7 @@ pub fn ovk_policy_prevents_recovery_from_chain( ) where Dsf: DataStoreFactory, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -3082,9 +3054,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -3130,9 +3100,7 @@ pub fn change_note_spends_succeed( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -3482,9 +3450,7 @@ pub fn zip317_spend( ds_factory: Dsf, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -3581,9 +3547,7 @@ where use zcash_keys::keys::UnifiedAddressRequest; use zcash_primitives::transaction::builder::DEFAULT_TX_EXPIRY_DELTA; - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -3828,9 +3792,7 @@ pub fn checkpoint_gaps( ds_factory: Dsf, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -3847,6 +3809,8 @@ pub fn checkpoint_gaps( // belong to us so that we can get a checkpoint in the tree. let not_our_key = T::sk_to_fvk(&T::sk(&[0xf5; 32])); let not_our_value = Zatoshis::const_from_u64(10000); + let sapling_end_size = st.latest_cached_block().unwrap().sapling_end_size(); + let orchard_end_size = st.latest_cached_block().unwrap().orchard_end_size(); st.generate_block_at( account.birthday().height() + 10, BlockHash([0; 32]), @@ -3855,8 +3819,8 @@ pub fn checkpoint_gaps( AddressType::DefaultExternal, not_our_value, )], - st.latest_cached_block().unwrap().sapling_end_size(), - st.latest_cached_block().unwrap().orchard_end_size(), + sapling_end_size, + orchard_end_size, false, ); @@ -3914,10 +3878,8 @@ pub fn pool_crossing_required( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - // TODO: Allow for Orchard activation after Sapling - .build(); + // TODO: Allow for Orchard activation after Sapling + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); @@ -4004,10 +3966,8 @@ pub fn fully_funded_fully_private( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - // TODO: Allow for Orchard activation after Sapling - .build(); + // TODO: Allow for Orchard activation after Sapling + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); @@ -4188,10 +4146,8 @@ pub fn multi_pool_checkpoint( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - // TODO: Allow for Orchard activation after Sapling - .build(); + // TODO: Allow for Orchard activation after Sapling + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let acct_id = account.id(); @@ -4359,10 +4315,8 @@ pub fn multi_pool_checkpoints_with_pruning( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let dfvk = T::test_account_fvk(&st); @@ -4427,9 +4379,7 @@ pub fn invalid_chain_cache_disconnected( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let dfvk = T::test_account_fvk(&st); @@ -4484,9 +4434,7 @@ where Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4548,9 +4496,7 @@ where ::AccountId: std::fmt::Debug, C: TestCache, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); @@ -4684,9 +4630,7 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4741,9 +4685,7 @@ pub fn scan_cached_blocks_finds_received_notes( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4789,9 +4731,7 @@ pub fn scan_cached_blocks_finds_change_notes( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4833,9 +4773,7 @@ pub fn scan_cached_blocks_detects_spends_out_of_order::AccountId: std::fmt::Debug, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4881,9 +4819,7 @@ pub fn metadata_queries_exclude_unwanted_notes( ::AccountId: std::fmt::Debug, TC: TestCache, { - let mut st = TestBuilder::new() - .with_standard_sapling_account(ds_factory, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -5089,9 +5025,7 @@ pub fn wallet_recovery_computes_fees( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestBuilder::new() - .with_standard_sapling_account(dsf, cache) - .build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -5257,7 +5189,10 @@ pub fn receive_two_notes_with_same_value( // `st.generate_next_block` with multiple outputs. let pre_activation_block = CachedBlock::none(st.sapling_activation_height() - 1); - let prior_cached_block = st.latest_cached_block().unwrap_or(&pre_activation_block); + let prior_cached_block = st + .latest_cached_block() + .unwrap_or(&pre_activation_block) + .clone(); let h = prior_cached_block.height() + 1; st.generate_block_at( h, diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs new file mode 100644 index 0000000000..622e715bc5 --- /dev/null +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -0,0 +1,84 @@ +//! A convenient DSL for writing wallet tests. + +use std::ops::{Deref, DerefMut}; + +use zcash_primitives::block::BlockHash; +use zcash_protocol::local_consensus::LocalNetwork; + +use crate::data_api::{ + testing::{DataStoreFactory, TestBuilder, TestCache, TestState}, + WalletTest, +}; + +/// A type-state wrapper struct that provides convenience methods. +pub struct TestDsl { + /// Either a `TestBuilder` or + /// `TestState`. + inner: T, +} + +impl Deref for TestDsl { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for TestDsl { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl From for TestDsl { + fn from(inner: T) -> Self { + Self { inner } + } +} + +impl TestDsl { + /// Perform a state transition that may change the inner type. + pub fn map(self, f: impl FnOnce(T) -> X) -> TestDsl { + f(self.inner).into() + } +} + +/// [`TestDsl`] provides convenience methods for common [`TestBuilder`] scenarios. +impl TestDsl> +where + Dsf: DataStoreFactory, +{ + /// Equip the inner [`TestBuilder`] with the provided [`DataStoreFactory`] + /// and [`TestCache`], as well as an account that has a birthday at Sapling + /// activation. + /// + /// Shorthand for the following: + /// ```rust,ignore + /// let dsl: TestDsl> = TestBuilder::new() + /// .with_data_store_factory(dsf) + /// .with_block_cache(tc) + /// .with_account_from_sapling_activation(BlockHash([0; 32])) + /// .into(); + /// ``` + pub fn with_standard_sapling_account(dsf: Dsf, tc: Cache) -> Self { + TestBuilder::new() + .with_data_store_factory(dsf) + .with_block_cache(tc) + .with_account_from_sapling_activation(BlockHash([0; 32])) + .into() + } + + /// Build the builder, wrapping the resulting [`TestState`] in a [`TestDsl`]. + pub fn build(self) -> TestDsl> { + self.map(TestBuilder::build) + } +} + +/// [`TestDsl`] provides convenience methods for common [`TestState`] operations. +impl TestDsl> +where + DataStore: WalletTest, + Cache: TestCache, +{ +} From 339e6b6489ed77f90075c1742cc589925b963cee Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Tue, 28 Oct 2025 11:24:07 +1300 Subject: [PATCH 010/263] Add funds API refactored TestState::generate_next_block in terms of TestState::generate_next_block_multi TestDsl::add_notes_to now takes a generic iterator of notes --- zcash_client_backend/src/data_api/chain.rs | 5 +- zcash_client_backend/src/data_api/testing.rs | 29 +- .../src/data_api/testing/pool.rs | 589 +++++------------- .../src/data_api/testing/pool/dsl.rs | 309 ++++++++- 4 files changed, 459 insertions(+), 473 deletions(-) diff --git a/zcash_client_backend/src/data_api/chain.rs b/zcash_client_backend/src/data_api/chain.rs index 031d7cf026..5fcbd09eb3 100644 --- a/zcash_client_backend/src/data_api/chain.rs +++ b/zcash_client_backend/src/data_api/chain.rs @@ -569,12 +569,11 @@ impl ChainState { } } -/// Scans at most `limit` blocks from the provided block source for in order to find transactions +/// Scans at most `limit` blocks from the provided block source in order to find transactions /// received by the accounts tracked in the provided wallet database. /// /// This function will return after scanning at most `limit` new blocks, to enable the caller to -/// update their UI with scanning progress. Repeatedly calling this function with `from_height == -/// None` will process sequential ranges of blocks. +/// update their UI with scanning progress. /// /// ## Panics /// diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index 0c4cb097d4..4a850a5573 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -541,35 +541,25 @@ where /// Creates a fake block at the expected next height containing a single output of the /// given value, and inserts it into the cache. + /// + /// This is a proxy for `generate_next_block_multi`. pub fn generate_next_block( &mut self, recipient_fvk: &Fvk, recipient_address_type: AddressType, value: Zatoshis, ) -> (BlockHeight, Cache::InsertResult, Fvk::Nullifier) { - let pre_activation_block = CachedBlock::none(self.sapling_activation_height() - 1); - let prior_cached_block = self.latest_cached_block().unwrap_or(&pre_activation_block); - let height = prior_cached_block.height() + 1; - - let (res, nfs) = self.generate_block_at( - height, - prior_cached_block.chain_state.block_hash(), - &[FakeCompactOutput::new( - recipient_fvk, - recipient_address_type, - value, - )], - prior_cached_block.sapling_end_size, - prior_cached_block.orchard_end_size, - false, - ); + let (height, res, nfs) = self.generate_next_block_multi(&[FakeCompactOutput::new( + recipient_fvk, + recipient_address_type, + value, + )]); (height, res, nfs[0]) } /// Creates a fake block at the expected next height containing multiple outputs /// and inserts it into the cache. - #[allow(dead_code)] pub fn generate_next_block_multi( &mut self, outputs: &[FakeCompactOutput], @@ -591,7 +581,6 @@ where } /// Adds an empty block to the cache, advancing the simulated chain height. - #[allow(dead_code)] // used only for tests that are flagged off by default pub fn generate_empty_block(&mut self) -> (BlockHeight, Cache::InsertResult) { let new_hash = { let mut hash = vec![0; 32]; @@ -2121,9 +2110,10 @@ impl TestFvk for ::orchard::keys::FullViewingKey { /// Configures how a [`TestFvk`] receives a particular output. /// /// Used with [`TestFvk::add_output`] and [`TestFvk::add_logical_action`]. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Default, Debug)] pub enum AddressType { /// The output will be sent to the default address of the full viewing key. + #[default] DefaultExternal, /// The output will be sent to the specified diversified address of the full viewing /// key. @@ -2292,6 +2282,7 @@ fn fake_compact_block( } /// Create a fake CompactBlock at the given height containing only the given transaction. +// TODO: `tx` could be a slice and we could add multiple transactions here fn fake_compact_block_from_tx( height: BlockHeight, prev_hash: BlockHash, diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 77d2f8bb9e..5c9039a8bf 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -2,11 +2,11 @@ use std::{ cmp::Eq, convert::Infallible, hash::Hash, - num::{NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}, + num::{NonZeroU8, NonZeroU32, NonZeroU64, NonZeroUsize}, }; use assert_matches::assert_matches; -use incrementalmerkletree::{frontier::Frontier, Level, Position}; +use incrementalmerkletree::{Level, Position, frontier::Frontier}; use rand::{Rng, RngCore}; use secrecy::Secret; use shardtree::error::ShardTreeError; @@ -16,42 +16,40 @@ use zcash_keys::{address::Address, keys::UnifiedSpendingKey}; use zcash_primitives::{ block::BlockHash, transaction::{ - fees::zip317::{FeeRule as Zip317FeeRule, MARGINAL_FEE, MINIMUM_FEE}, Transaction, + fees::zip317::{FeeRule as Zip317FeeRule, MARGINAL_FEE, MINIMUM_FEE}, }, }; use zcash_protocol::{ + ShieldedProtocol, consensus::{self, BlockHeight, NetworkUpgrade, Parameters}, local_consensus::LocalNetwork, memo::{Memo, MemoBytes}, value::Zatoshis, - ShieldedProtocol, }; use zip32::Scope; use zip321::{Payment, TransactionRequest}; use crate::{ data_api::{ - self, + self, Account as _, AccountBirthday, BoundedU8, DecryptedTransaction, InputSource, + MaxSpendMode, NoteFilter, Ratio, TargetValue, WalletCommitmentTrees, WalletRead, + WalletSummary, WalletTest, WalletWrite, chain::{self, ChainState, CommitmentTreeRoot, ScanSummary}, error::Error, testing::{ - single_output_change_strategy, AddressType, CacheInsertionResult, CachedBlock, - FakeCompactOutput, InitialChainState, TestBuilder, + AddressType, CacheInsertionResult, FakeCompactOutput, InitialChainState, TestBuilder, + single_output_change_strategy, }, wallet::{ - decrypt_and_store_transaction, input_selection::GreedyInputSelector, - ConfirmationsPolicy, TargetHeight, TransferErrT, + ConfirmationsPolicy, TargetHeight, TransferErrT, decrypt_and_store_transaction, + input_selection::GreedyInputSelector, }, - Account as _, AccountBirthday, BoundedU8, DecryptedTransaction, InputSource, MaxSpendMode, - NoteFilter, Ratio, TargetValue, WalletCommitmentTrees, WalletRead, WalletSummary, - WalletTest, WalletWrite, }, decrypt_transaction, fees::{ - self, + self, DustOutputPolicy, SplitPolicy, StandardFeeRule, standard::{self, SingleOutputChangeStrategy}, - DustOutputPolicy, SplitPolicy, StandardFeeRule, }, scanning::ScanError, wallet::{Note, NoteId, OvkPolicy, ReceivedNote}, @@ -74,7 +72,7 @@ use { keys::{NonHardenedChildIndex, TransparentKeyScope}, }, zcash_primitives::transaction::fees::zip317, - zcash_protocol::{value::ZatBalance, TxId}, + zcash_protocol::{TxId, value::ZatBalance}, }; #[cfg(feature = "orchard")] @@ -87,7 +85,7 @@ use { }; pub mod dsl; -use dsl::TestDsl; +use dsl::{TestDsl, TestNoteConfig}; /// Trait that exposes the pool-specific types and operations necessary to run the /// single-shielded-pool tests on a given pool. @@ -206,31 +204,10 @@ pub fn send_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); - - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); // Add funds to the wallet in a single note - let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance - assert_eq!(st.get_total_balance(account.id()), value); - assert_eq!( - st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), - value - ); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + let (h, _, _) = st.add_a_single_note(Zatoshis::const_from_u64(60000)); let to_extsk = T::sk(&[0xf5; 32]); let to: Address = T::sk_default_address(&to_extsk); @@ -251,6 +228,7 @@ pub fn send_single_step_proposed_transfer( ); let input_selector = GreedyInputSelector::new(); + let account = st.get_account(); let proposal = st .propose_transfer( account.id(), @@ -388,9 +366,8 @@ pub fn zip_315_confirmations_test_steps( cache: impl TestCache, input_trust: InputTrust, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); let starting_balance = Zatoshis::const_from_u64(60_000); // Add funds to the wallet in a single note, owned by the internal spending key, @@ -408,17 +385,9 @@ pub fn zip_315_confirmations_test_steps( }; let min_confirmations = u32::from(min_confirmations); - // Generate a block to create the inputs that we will spend. - let (h, r, _) = st.generate_next_block(&dfvk, address_type, starting_balance); + let (_, r, _) = st + .add_a_single_note(TestNoteConfig::from(starting_balance).with_address_type(address_type)); let txid = r.txids()[0]; - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance at 1 confirmation. - assert_eq!(st.get_total_balance(account.id()), starting_balance); - assert_eq!( - st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), - starting_balance - ); // Mark the external input as explicitly trusted, if so requested if input_trust == InputTrust::ExternalTrusted { @@ -438,7 +407,7 @@ pub fn zip_315_confirmations_test_steps( } }; - // Generate `min_confirmations` confirmations by mining blocks + // Generate N confirmations by mining blocks let steps = (1u32..min_confirmations) .map(add_confirmation) .collect::>(); @@ -485,33 +454,21 @@ pub fn spend_max_spendable_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); - - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); - // Add funds to the wallet in a single note + // Add funds to the wallet in two notes over 5 blocks let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); + let h = st + .add_notes([Some(value), None, None, None, Some(value)]) + .block_height(); + // Spendable balance matches total balance + let account = st.test_account().cloned().unwrap(); let confirmation_policy = ConfirmationsPolicy::new_symmetrical( NonZeroU32::new(2).expect("2 is not zero"), #[cfg(feature = "transparent-inputs")] false, ); - st.generate_empty_block(); - st.generate_empty_block(); - st.generate_empty_block(); - - st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - - st.scan_cached_blocks(h, 5); - - // Spendable balance matches total balance - assert_eq!( - st.get_total_balance(account.id()), - Zatoshis::const_from_u64(120_000) - ); assert_eq!( st.get_spendable_balance(account.id(), confirmation_policy), value @@ -648,31 +605,12 @@ pub fn spend_everything_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); // Add funds to the wallet in a single note - let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance - assert_eq!(st.get_total_balance(account.id()), value); - assert_eq!( - st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), - value - ); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + let (h, _, _) = st.add_a_single_note(Zatoshis::const_from_u64(60000)); let to_extsk = T::sk(&[0xf5; 32]); let to: Address = T::sk_default_address(&to_extsk); @@ -801,31 +739,10 @@ pub fn fails_to_send_max_spendable_to_transparent_with_memo(); // Add funds to the wallet in a single note - let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance - assert_eq!(st.get_total_balance(account.id()), value); - assert_eq!( - st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), - value - ); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + st.add_a_single_note(Zatoshis::const_from_u64(60000)); let account = st.test_account().cloned().unwrap(); let (default_addr, _) = account.usk().default_transparent_address(); @@ -866,32 +783,16 @@ pub fn spend_everything_proposal_fails_when_unconfirmed_funds_present(); + st.add_notes([ + Some(Zatoshis::const_from_u64(60000)), + None, + None, + Some(Zatoshis::const_from_u64(123456)), + ]); // Spendable balance doesn't match total balance + let account = st.test_account().cloned().unwrap(); let total_balance = st.get_total_balance(account.id()); let spendable_balance = st.get_spendable_balance( account.id(), @@ -939,38 +840,25 @@ pub fn spend_everything_proposal_fails_when_unconfirmed_funds_present( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); - - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); - - // Add funds to the wallet in a single note - let value = Zatoshis::const_from_u64(60000); - - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - - st.generate_empty_block(); - st.generate_empty_block(); - let later_on_value = Zatoshis::const_from_u64(123456); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, later_on_value); - st.scan_cached_blocks(h1, 4); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let h = st + .add_notes([ + Some(Zatoshis::const_from_u64(60000)), + None, + None, + Some(Zatoshis::const_from_u64(123456)), + ]) + .block_height(); // Spendable balance doesn't match total balance + let account = st.test_account().cloned().unwrap(); let total_balance = st.get_total_balance(account.id()); let spendable_balance = st.get_spendable_balance( account.id(), @@ -1108,35 +996,19 @@ pub fn spend_everything_multi_step_single_note_proposed_transfer::AccountId: std::fmt::Debug, { - use crate::data_api::{testing::transparent::GapLimits, MaxSpendMode, OutputOfSentTx}; + use crate::data_api::{MaxSpendMode, OutputOfSentTx, testing::transparent::GapLimits}; let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) - .build(); + .build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); - let dfvk = T::test_account_fvk(&st); - - let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); - h - }; let value = Zatoshis::const_from_u64(100000); // Add funds to the wallet. - add_funds(&mut st, value); + st.add_a_single_note(value); let initial_balance = value; assert_eq!( st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), @@ -1281,30 +1153,11 @@ pub fn spend_everything_multi_step_many_notes_proposed_transfer::AccountId: std::fmt::Debug, { - use crate::data_api::{testing::transparent::GapLimits, OutputOfSentTx}; + use crate::data_api::{OutputOfSentTx, testing::transparent::GapLimits}; let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) - .build(); - - let account = st.test_account().cloned().unwrap(); - let account_id = account.id(); - let dfvk = T::test_account_fvk(&st); - - let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); - h - }; + .build::(); let number_of_notes = 3u64; let note_value = Zatoshis::const_from_u64(100000); @@ -1312,10 +1165,12 @@ pub fn spend_everything_multi_step_many_notes_proposed_transfer::AccountId: std::fmt::Debug, { - use crate::data_api::{testing::transparent::GapLimits, MaxSpendMode, OutputOfSentTx}; + use crate::data_api::{MaxSpendMode, OutputOfSentTx, testing::transparent::GapLimits}; let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) - .build(); - - let account = st.test_account().cloned().unwrap(); - let account_id = account.id(); - let dfvk = T::test_account_fvk(&st); - - let add_funds = |st: &mut TestState<_, Dsf::DataStore, _>, value| { - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); - h - }; + .build::(); let number_of_notes = 10u64; let note_value = Zatoshis::const_from_u64(100000); @@ -1483,10 +1319,12 @@ pub fn spend_everything_multi_step_with_marginal_notes_proposed_transfer< (note_value * number_of_notes).expect("sum of notes should not fail."); for _ in 0..number_of_notes { - add_funds(&mut st, note_value); - add_funds(&mut st, zip317::MARGINAL_FEE); + st.add_a_single_note(note_value); + st.add_a_single_note(zip317::MARGINAL_FEE); } + let account = st.test_account().cloned().unwrap(); + let account_id = account.id(); assert_eq!( st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), non_marginal_notes_value @@ -1619,31 +1457,14 @@ pub fn send_with_multiple_change_outputs( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(650_0000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance - assert_eq!(st.get_total_balance(account.id()), value); - assert_eq!( - st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), - value - ); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + let (h, _, _) = st.add_a_single_note(value); let to_extsk = T::sk(&[0xf5; 32]); let to: Address = T::sk_default_address(&to_extsk); @@ -1804,14 +1625,14 @@ pub fn send_multi_step_proposed_transfer( Dsf: DataStoreFactory, { use crate::{ - data_api::{testing::transparent::GapLimits, OutputOfSentTx, TransactionStatus}, + data_api::{OutputOfSentTx, TransactionStatus, testing::transparent::GapLimits}, wallet::{Exposure, TransparentAddressSource}, }; let gap_limits = GapLimits::new(10, 5, 3); let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(gap_limits)) - .build(); + .build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2159,31 +1980,14 @@ pub fn spend_all_funds_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance - assert_eq!(st.get_total_balance(account.id()), value); - assert_eq!( - st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), - value - ); - - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + let (h, _, _) = st.add_a_single_note(value); let spend_amount = Zatoshis::const_from_u64(50000); let to_extsk = T::sk(&[0xf5; 32]); @@ -2328,11 +2132,11 @@ pub fn spend_all_funds_multi_step_proposed_transfer( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - use crate::data_api::{testing::transparent::GapLimits, OutputOfSentTx}; + use crate::data_api::{OutputOfSentTx, testing::transparent::GapLimits}; let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) - .build(); + .build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2345,15 +2149,6 @@ pub fn spend_all_funds_multi_step_proposed_transfer( let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); st.scan_cached_blocks(h, 1); - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); - let initial_balance = value; assert_eq!( st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), @@ -2486,7 +2281,7 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2565,7 +2360,7 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( ds_factory: Dsf, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build::(); let dfvk = T::test_account_fvk(&st); let to = T::fvk_default_address(&dfvk); @@ -2602,7 +2397,7 @@ where Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build::(); let account_id = st.test_account().unwrap().id(); let dfvk = T::test_account_fvk(&st); @@ -2631,7 +2426,7 @@ pub fn spend_fails_on_unverified_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2639,15 +2434,7 @@ pub fn spend_fails_on_unverified_notes( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); - - // Spendable balance matches total balance at 1 confirmation. - assert_eq!(st.get_total_balance(account_id), value); - assert_eq!( - st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), - value - ); + st.add_a_single_note(value); // Value is considered pending at 10 confirmations. assert_eq!( @@ -2673,8 +2460,7 @@ pub fn spend_fails_on_unverified_notes( assert_eq!(summary.map(|s| s.progress().scan()), Some(Ratio::new(1, 1))); // Add more funds to the wallet in a second note - let (h2, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h2, 1); + let (h2, _, _) = st.add_a_single_note(value); // Verified balance does not include the second note let total = (value + value).unwrap(); @@ -2821,7 +2607,7 @@ pub fn spend_fails_on_locked_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2831,15 +2617,7 @@ pub fn spend_fails_on_locked_notes( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); - - // Spendable balance matches total balance at 1 confirmation. - assert_eq!(st.get_total_balance(account_id), value); - assert_eq!( - st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), - value - ); + let (h1, _, _) = st.add_a_single_note(value); // Send some of the funds to another address, but don't mine the tx. let extsk2 = T::sk(&[0xf5; 32]); @@ -2966,7 +2744,7 @@ pub fn ovk_policy_prevents_recovery_from_chain( ) where Dsf: DataStoreFactory, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2974,15 +2752,7 @@ pub fn ovk_policy_prevents_recovery_from_chain( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); - - // Spendable balance matches total balance at 1 confirmation. - assert_eq!(st.get_total_balance(account_id), value); - assert_eq!( - st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), - value - ); + let (h1, _, _) = st.add_a_single_note(value); let extsk2 = T::sk(&[0xf5; 32]); let addr2 = T::sk_default_address(&extsk2); @@ -3054,7 +2824,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -3062,15 +2832,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(70000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance at 1 confirmation. - assert_eq!(st.get_total_balance(account_id), value); - assert_eq!( - st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), - value - ); + st.add_a_single_note(value); let fee_rule = StandardFeeRule::Zip317; @@ -3100,25 +2862,15 @@ pub fn change_note_spends_succeed( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); - - let account = st.test_account().cloned().unwrap(); - let account_id = account.id(); - let dfvk = T::test_account_fvk(&st); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); // Add funds to the wallet in a single note owned by the internal spending key let value = Zatoshis::const_from_u64(70000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::Internal, value); - st.scan_cached_blocks(h, 1); - - // Spendable balance matches total balance at 1 confirmation. - assert_eq!(st.get_total_balance(account_id), value); - assert_eq!( - st.get_spendable_balance(account_id, ConfirmationsPolicy::MIN), - value - ); + st.add_a_single_note(TestNoteConfig::from(value).with_address_type(AddressType::Internal)); // Value is considered pending at 10 confirmations. + let account = st.test_account().cloned().unwrap(); + let account_id = account.id(); assert_eq!( st.get_pending_shielded_balance(account_id, ConfirmationsPolicy::default()), value @@ -3450,30 +3202,20 @@ pub fn zip317_spend( ds_factory: Dsf, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); let dfvk = T::test_account_fvk(&st); // Add funds to the wallet - let (h1, _, _) = st.generate_next_block( - &dfvk, - AddressType::Internal, - Zatoshis::const_from_u64(50000), - ); + st.add_notes([Some(Zatoshis::const_from_u64(50000))]); // Add 10 dust notes to the wallet for _ in 1..=10 { - st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - Zatoshis::const_from_u64(1000), - ); + st.add_notes([Some(Zatoshis::const_from_u64(1000))]); } - st.scan_cached_blocks(h1, 11); - // Spendable balance matches total balance let total = Zatoshis::const_from_u64(60000); assert_eq!(st.get_total_balance(account_id), total); @@ -3547,7 +3289,7 @@ where use zcash_keys::keys::UnifiedAddressRequest; use zcash_primitives::transaction::builder::DEFAULT_TX_EXPIRY_DELTA; - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -3617,9 +3359,11 @@ where // Verify that a transaction enhancement request for the transaction containing the spent // outpoint does not yet exist. let requests = st.wallet().transaction_data_requests().unwrap(); - assert!(!requests - .iter() - .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid()))); + assert!( + !requests + .iter() + .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid())) + ); // Use `decrypt_and_store_transaction` for the side effect of creating enhancement requests for // the transparent inputs of the transaction. @@ -3633,9 +3377,11 @@ where // Verify that a transaction enhancement request for the received transaction was created let requests = st.wallet().transaction_data_requests().unwrap(); - assert!(requests - .iter() - .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid()))); + assert!( + requests + .iter() + .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid())) + ); // Now advance the chain by 40 blocks; even though a record for the transaction that created // `spent_outpoint` exists in the wallet database, the transaction can't be enhanced because @@ -3662,9 +3408,11 @@ where // Verify that the transaction enhancement request for the invalid txid has been deleted. let requests = st.wallet().transaction_data_requests().unwrap(); - assert!(!requests - .iter() - .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid()))); + assert!( + !requests + .iter() + .any(|req| req == &TransactionDataRequest::Enhancement(*spent_outpoint.txid())) + ); } // FIXME: This requires fixes to the test framework. @@ -3792,18 +3540,13 @@ pub fn checkpoint_gaps( ds_factory: Dsf, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); // Generate a block with funds belonging to our wallet. - st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - Zatoshis::const_from_u64(500000), - ); - st.scan_cached_blocks(account.birthday().height(), 1); + st.add_a_single_note(Zatoshis::const_from_u64(500000)); // Create a gap of 10 blocks having no shielded outputs, then add a block that doesn't // belong to us so that we can get a checkpoint in the tree. @@ -3879,7 +3622,9 @@ pub fn pool_crossing_required( cache: impl TestCache, ) { // TODO: Allow for Orchard activation after Sapling - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + // Here we choose P0, but this has no effect since we supply the viewing keys + // and generate the blocks directly on the state. + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -3967,7 +3712,7 @@ pub fn fully_funded_fully_private(); let account = st.test_account().cloned().unwrap(); @@ -4057,7 +3802,7 @@ pub fn fully_funded_send_to_t( cache: impl TestCache, ) { // TODO: Allow for Orchard activation after Sapling - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -4147,7 +3892,7 @@ pub fn multi_pool_checkpoint( cache: impl TestCache, ) { // TODO: Allow for Orchard activation after Sapling - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let acct_id = account.id(); @@ -4316,7 +4061,7 @@ pub fn multi_pool_checkpoints_with_pruning(); let account = st.test_account().cloned().unwrap(); @@ -4345,7 +4090,7 @@ pub fn valid_chain_states( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let dfvk = T::test_account_fvk(&st); @@ -4379,7 +4124,7 @@ pub fn invalid_chain_cache_disconnected( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let dfvk = T::test_account_fvk(&st); @@ -4434,7 +4179,7 @@ where Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4496,7 +4241,7 @@ where ::AccountId: std::fmt::Debug, C: TestCache, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -4630,7 +4375,7 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4685,7 +4430,7 @@ pub fn scan_cached_blocks_finds_received_notes( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4724,6 +4469,7 @@ pub fn scan_cached_blocks_finds_received_notes( } // TODO: This test can probably be entirely removed, as the following test duplicates it entirely. +// TODO(schell): ^still a valid todo? pub fn scan_cached_blocks_finds_change_notes( ds_factory: Dsf, cache: impl TestCache, @@ -4731,7 +4477,7 @@ pub fn scan_cached_blocks_finds_change_notes( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4741,14 +4487,15 @@ pub fn scan_cached_blocks_finds_change_notes( // Create a fake CompactBlock sending value to the address let value = Zatoshis::const_from_u64(50000); - let (received_height, _, nf) = - st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); + let (_, _, nf) = st.add_a_single_note(value); + // let (received_height, _, nf) = + // st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - // Scan the cache - st.scan_cached_blocks(received_height, 1); + // // Scan the cache + // st.scan_cached_blocks(received_height, 1); - // Account balance should reflect the received note - assert_eq!(st.get_total_balance(account.id()), value); + // // Account balance should reflect the received note + // assert_eq!(st.get_total_balance(account.id()), value); // Create a second fake CompactBlock spending value from the address let not_our_key = T::sk_to_fvk(&T::sk(&[0xf5; 32])); @@ -4773,7 +4520,7 @@ pub fn scan_cached_blocks_detects_spends_out_of_order::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4819,23 +4566,18 @@ pub fn metadata_queries_exclude_unwanted_notes( ::AccountId: std::fmt::Debug, TC: TestCache, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build(); - - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); + let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); // Create 10 blocks with successively increasing value - let value = Zatoshis::const_from_u64(100_0000); - let (h0, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - let mut note_values = vec![value]; - for i in 2..=10 { - let value = Zatoshis::const_from_u64(i * 100_0000); - st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - note_values.push(value); - } - st.scan_cached_blocks(h0, 10); - let target_height = TargetHeight::from(h0 + 10); + let note_values = (1..=10) + .map(|i| Zatoshis::const_from_u64(i * 100_0000)) + .collect::>(); + let h0 = st + .add_notes(note_values.clone().into_iter().map(|z| Some(z))) + .first_block_height(); + let target_height = TargetHeight::from(h0 + 10); + let account = st.test_account().cloned().unwrap(); let test_meta = |st: &TestState, query, expected_count| { let metadata = st .wallet() @@ -5025,7 +4767,7 @@ pub fn wallet_recovery_computes_fees(); let seed = Secret::new(st.test_seed().unwrap().expose_secret().clone()); let source_account = st.test_account().cloned().unwrap(); @@ -5034,14 +4776,11 @@ pub fn wallet_recovery_computes_fees( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build(); - - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); + let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); // Add funds to the wallet in two identical notes let value = Zatoshis::const_from_u64(60000); - let outputs = [ - FakeCompactOutput::new(&dfvk, AddressType::DefaultExternal, value), - FakeCompactOutput::new(&dfvk, AddressType::DefaultExternal, value), - ]; - let total_value = (value + value).unwrap(); - - // `st.generate_next_block` with multiple outputs. - let pre_activation_block = CachedBlock::none(st.sapling_activation_height() - 1); - let prior_cached_block = st - .latest_cached_block() - .unwrap_or(&pre_activation_block) - .clone(); - let h = prior_cached_block.height() + 1; - st.generate_block_at( - h, - prior_cached_block.chain_state.block_hash(), - &outputs, - prior_cached_block.sapling_end_size, - prior_cached_block.orchard_end_size, - false, - ); - - st.scan_cached_blocks(h, 1); - assert_eq!( - st.wallet() - .block_max_scanned() - .unwrap() - .unwrap() - .block_height(), - h - ); + let h = st.add_notes([[value, value]]).block_height(); // Spendable balance matches total balance. - assert_eq!(st.get_total_balance(account.id()), total_value); + let account = st.test_account().cloned().unwrap(); + let total_value = (value + value).unwrap(); assert_eq!( st.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), total_value diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs index 622e715bc5..ae0c0e7a78 100644 --- a/zcash_client_backend/src/data_api/testing/pool/dsl.rs +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -1,15 +1,25 @@ //! A convenient DSL for writing wallet tests. -use std::ops::{Deref, DerefMut}; +use std::{ + marker::PhantomData, + ops::{Deref, DerefMut}, +}; use zcash_primitives::block::BlockHash; -use zcash_protocol::local_consensus::LocalNetwork; +use zcash_protocol::{consensus::BlockHeight, local_consensus::LocalNetwork, value::Zatoshis}; use crate::data_api::{ - testing::{DataStoreFactory, TestBuilder, TestCache, TestState}, - WalletTest, + Account, AccountBalance, WalletRead, + chain::ScanSummary, + testing::{ + AddressType, DataStoreFactory, FakeCompactOutput, TestAccount, TestBuilder, TestCache, + TestFvk, TestState, + }, + wallet::ConfirmationsPolicy, }; +use super::ShieldedPoolTester; + /// A type-state wrapper struct that provides convenience methods. pub struct TestDsl { /// Either a `TestBuilder` or @@ -69,16 +79,295 @@ where .into() } - /// Build the builder, wrapping the resulting [`TestState`] in a [`TestDsl`]. - pub fn build(self) -> TestDsl> { - self.map(TestBuilder::build) + /// Build the builder, wrapping the resulting [`TestState`] in a [`TestDsl`] and [`TestScenario`]. + pub fn build(self) -> TestDsl> { + let state = self.inner.build(); + TestScenario { + state, + _phantom: PhantomData, + } + .into() } } -/// [`TestDsl`] provides convenience methods for common [`TestState`] operations. -impl TestDsl> +/// A proxy for `FakeCompactOutput` that allows test code to omit the `fvk` and +/// `address_type` fields, which can be derived from the `TestState` in most cases. +pub struct TestNoteConfig { + pub value: Zatoshis, + /// Diversifiable full viewing key of + pub fvk: Option, + pub address_type: Option, +} + +impl From for TestNoteConfig { + fn from(value: Zatoshis) -> Self { + TestNoteConfig { + value, + fvk: None, + address_type: None, + } + } +} + +impl TestNoteConfig { + pub fn with_address_type(mut self, address_type: AddressType) -> Self { + self.address_type = Some(address_type); + self + } + + pub fn with_fvk(mut self, fvk: T::Fvk) -> Self { + self.fvk = Some(fvk); + self + } +} + +pub struct AddFundsStepResult { + pub block_height: BlockHeight, + pub insert_result: C::InsertResult, + /// Empty when the step was to generate an empty block + pub nullifiers: Vec<::Nullifier>, +} + +/// The input and output of one "add funds" step. +pub struct AddFundsStep { + pub notes: Vec>, + pub results: AddFundsStepResult, +} + +/// A collection of results from adding funds to a `TestState`. +pub struct AddFundsSummary { + pub steps: Vec>, + pub scan_summary: Option, +} + +impl Default for AddFundsSummary { + fn default() -> Self { + Self { + steps: Default::default(), + scan_summary: None, + } + } +} + +impl AddFundsSummary { + /// Return the first block height. + pub fn first_block_height(&self) -> BlockHeight { + if let Some(step) = self.steps.first() { + step.results.block_height + } else { + BlockHeight::from_u32(0) + } + } + + /// Return the latest block height after generating the blocks + /// that added funds. + pub fn block_height(&self) -> BlockHeight { + if let Some(step) = self.steps.last() { + step.results.block_height + } else { + BlockHeight::from_u32(0) + } + } +} + +#[repr(transparent)] +pub struct TestScenario { + /// The current scenario state. + state: TestState, + _phantom: PhantomData, +} + +impl Deref for TestScenario where - DataStore: WalletTest, + T: ShieldedPoolTester, + D: DataStoreFactory, +{ + type Target = TestState; + + fn deref(&self) -> &Self::Target { + &self.state + } +} + +impl DerefMut for TestScenario +where + T: ShieldedPoolTester, + D: DataStoreFactory, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.state + } +} + +/// Add funds scenarios. +impl TestScenario +where + T: ShieldedPoolTester, Cache: TestCache, + Dsf: DataStoreFactory, { + /// Return the current test account balance, if possible. + /// + /// Returns `None` when no account summary data is available, which is + /// the case before the wallet has scanned any blocks. + pub fn get_account_balance( + &self, + confirmations_policy: ConfirmationsPolicy, + ) -> Option { + let account = self.get_account(); + let binding = self + .wallet() + .get_wallet_summary(confirmations_policy) + .unwrap()?; + let balance = binding.account_balances().get(&account.id())?; + Some(balance.clone()) + } + + /// Adds funds from a single note from an address of the given type. + /// + /// Returns the current block height, cache insert result and test viewing key nullifier. + /// + /// This is shorthand for: + /// ```rust,ignore + /// { + /// let dfvk = T::test_account_fvk(&st); + /// let output@(h, _, _) = st.generate_next_block(&dfvk, address_type, zatoshis); + /// st.scan_cached_blocks(h, 1); + /// output + /// } + /// ``` + /// + /// This also verifies that the test account contains the expected funds as + /// part of the _total_, and that the funds are spendable with the minimum number + /// of confirmations. + pub fn add_a_single_note( + &mut self, + note: impl Into>, + ) -> ( + BlockHeight, + Cache::InsertResult, + ::Nullifier, + ) { + let mut summary = self.add_notes([[note]]); + let res = summary.steps.pop().unwrap().results; + (res.block_height, res.insert_result, res.nullifiers[0]) + } + + /// Generates `N` empty blocks. + /// + /// Returns the current block height. + pub fn add_empty_blocks(&mut self, n: usize) -> BlockHeight { + let mut out_height = BlockHeight::from_u32(0); + for _ in 0..n { + let (h, _) = self.generate_empty_block(); + out_height = h; + } + out_height + } + + /// Returns the test account. + pub fn get_account(&self) -> TestAccount { + self.test_account().expect("not configured").clone() + } + + /// Creates a `FakeCompactOutput` from the given `TestNoteConfig`. + fn make_fake_output(&self, note_config: &TestNoteConfig) -> FakeCompactOutput { + let TestNoteConfig { + value, + fvk, + address_type, + } = note_config; + FakeCompactOutput::new( + fvk.clone().unwrap_or_else(|| T::test_account_fvk(self)), + address_type.unwrap_or(AddressType::DefaultExternal), + *value, + ) + } + + /// Add funds from multiple notes in one or more blocks, or generate empty blocks. + /// + /// This step also verifies that the test account contains the expected + /// funds as part of the _total_. Keep in mind that these funds may not yet + /// be _spendable_ due to the number confirmations required. + /// + /// Returns a summary of steps. + /// + /// ## Note + /// Keep in mind: + /// * Each block coalesces these notes into a single transaction. + /// * Funds are added to the default test account. + pub fn add_notes( + &mut self, + blocks: impl IntoIterator>>>, + ) -> AddFundsSummary { + let mut from_height = None; + let mut current_height = BlockHeight::from_u32(0); + let mut limit = 0; + let account = self.get_account(); + let starting_balance = self + .get_account_balance(ConfirmationsPolicy::MIN) + .map(|b| b.total()) + .unwrap_or(Zatoshis::ZERO); + let mut expected_total = starting_balance; + let mut summary = AddFundsSummary::default(); + for notes in blocks.into_iter() { + // Collect the notes while also counting their value. + let (fake_outputs, note_configs): (Vec<_>, Vec<_>) = notes + .into_iter() + .map(|into_note_config| { + let note_config = into_note_config.into(); + expected_total = (expected_total + note_config.value).unwrap(); + (self.make_fake_output(¬e_config), note_config) + }) + .unzip(); + let step_result = if fake_outputs.is_empty() { + let (h, r) = self.generate_empty_block(); + AddFundsStepResult { + block_height: h, + insert_result: r, + nullifiers: vec![], + } + } else { + let (h, r, n) = self.generate_next_block_multi(&fake_outputs); + AddFundsStepResult { + block_height: h, + insert_result: r, + nullifiers: n, + } + }; + current_height = step_result.block_height; + if from_height.is_none() { + from_height = Some(current_height); + } + summary.steps.push(AddFundsStep { + notes: note_configs, + results: step_result, + }); + limit += 1; + } + if let Some(from_height) = from_height { + summary.scan_summary = Some(self.scan_cached_blocks(from_height, limit)); + } + + // Do most of the assertions that we care about at the "add funds" callsites + assert_eq!( + self.get_total_balance(account.id()), + expected_total, + "Unexpected total balance" + ); + assert_eq!( + self.wallet() + .block_max_scanned() + .unwrap() + .unwrap() + .block_height(), + current_height + ); + assert_eq!( + self.get_spendable_balance(account.id(), ConfirmationsPolicy::MIN), + expected_total + ); + + summary + } } From 9bf627a37916aab42945f68d94de23f1a6c5e769 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Wed, 5 Nov 2025 13:52:03 +1300 Subject: [PATCH 011/263] clean up unused dfvk binding warnings --- .../src/data_api/testing/pool.rs | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 5c9039a8bf..c818ac5da8 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -1459,9 +1459,6 @@ pub fn send_with_multiple_change_outputs( ) { let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); - // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(650_0000); let (h, _, _) = st.add_a_single_note(value); @@ -1487,6 +1484,7 @@ pub fn send_with_multiple_change_outputs( ), ); + let account = st.test_account().cloned().unwrap(); let proposal = st .propose_transfer( account.id(), @@ -1982,9 +1980,6 @@ pub fn spend_all_funds_single_step_proposed_transfer( ) { let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); - // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(60000); let (h, _, _) = st.add_a_single_note(value); @@ -2009,6 +2004,7 @@ pub fn spend_all_funds_single_step_proposed_transfer( ); let input_selector = GreedyInputSelector::new(); + let account = st.test_account().cloned().unwrap(); let proposal = st .propose_transfer( account.id(), @@ -2609,10 +2605,6 @@ pub fn spend_fails_on_locked_notes( ) { let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); - let account = st.test_account().cloned().unwrap(); - let account_id = account.id(); - let dfvk = T::test_account_fvk(&st); - let fee_rule = StandardFeeRule::Zip317; // Add funds to the wallet in a single note @@ -2622,6 +2614,8 @@ pub fn spend_fails_on_locked_notes( // Send some of the funds to another address, but don't mine the tx. let extsk2 = T::sk(&[0xf5; 32]); let to = T::sk_default_address(&extsk2); + let account = st.test_account().cloned().unwrap(); + let account_id = account.id(); let proposal = st .propose_standard_transfer::( account_id, @@ -2826,10 +2820,6 @@ pub fn spend_succeeds_to_t_addr_zero_change( ) { let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); - let account = st.test_account().cloned().unwrap(); - let account_id = account.id(); - let dfvk = T::test_account_fvk(&st); - // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(70000); st.add_a_single_note(value); @@ -2838,6 +2828,8 @@ pub fn spend_succeeds_to_t_addr_zero_change( // TODO: generate_next_block_from_tx does not currently support transparent outputs. let to = TransparentAddress::PublicKeyHash([7; 20]).into(); + let account = st.test_account().cloned().unwrap(); + let account_id = account.id(); let proposal = st .propose_standard_transfer::( account_id, @@ -3542,14 +3534,12 @@ pub fn checkpoint_gaps( ) { let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); - let account = st.test_account().cloned().unwrap(); - let dfvk = T::test_account_fvk(&st); - // Generate a block with funds belonging to our wallet. st.add_a_single_note(Zatoshis::const_from_u64(500000)); // Create a gap of 10 blocks having no shielded outputs, then add a block that doesn't // belong to us so that we can get a checkpoint in the tree. + let account = st.test_account().cloned().unwrap(); let not_our_key = T::sk_to_fvk(&T::sk(&[0xf5; 32])); let not_our_value = Zatoshis::const_from_u64(10000); let sapling_end_size = st.latest_cached_block().unwrap().sapling_end_size(); From eda4fdab517e63de7f69557abc6a2786651f20ac Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Wed, 5 Nov 2025 14:32:35 +1300 Subject: [PATCH 012/263] test DSL - don't count dust notes in expected total --- zcash_client_backend/src/data_api/testing/pool/dsl.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs index ae0c0e7a78..43d5d13cb6 100644 --- a/zcash_client_backend/src/data_api/testing/pool/dsl.rs +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -5,7 +5,7 @@ use std::{ ops::{Deref, DerefMut}, }; -use zcash_primitives::block::BlockHash; +use zcash_primitives::{block::BlockHash, transaction::fees::zip317}; use zcash_protocol::{consensus::BlockHeight, local_consensus::LocalNetwork, value::Zatoshis}; use crate::data_api::{ @@ -316,7 +316,11 @@ where .into_iter() .map(|into_note_config| { let note_config = into_note_config.into(); - expected_total = (expected_total + note_config.value).unwrap(); + if note_config.value > zip317::MARGINAL_FEE { + // Don't include dust in the expected total, as the balance + // won't include it. + expected_total = (expected_total + note_config.value).unwrap(); + } (self.make_fake_output(¬e_config), note_config) }) .unzip(); From fa285cfbe0195b55602f0377a3476b540102a03f Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Wed, 5 Nov 2025 14:49:24 +1300 Subject: [PATCH 013/263] fix clippys --- zcash_client_backend/src/data_api/testing/pool.rs | 2 +- zcash_client_backend/src/data_api/testing/pool/dsl.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index c818ac5da8..1836ea73f5 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -4563,7 +4563,7 @@ pub fn metadata_queries_exclude_unwanted_notes( .map(|i| Zatoshis::const_from_u64(i * 100_0000)) .collect::>(); let h0 = st - .add_notes(note_values.clone().into_iter().map(|z| Some(z))) + .add_notes(note_values.clone().into_iter().map(Some)) .first_block_height(); let target_height = TargetHeight::from(h0 + 10); diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs index 43d5d13cb6..b6025428a4 100644 --- a/zcash_client_backend/src/data_api/testing/pool/dsl.rs +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -220,7 +220,7 @@ where .get_wallet_summary(confirmations_policy) .unwrap()?; let balance = binding.account_balances().get(&account.id())?; - Some(balance.clone()) + Some(*balance) } /// Adds funds from a single note from an address of the given type. From 1c0710ea21671542243fccb632138548f08d11b3 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Thu, 13 Nov 2025 07:07:11 +1300 Subject: [PATCH 014/263] AddressType does not need Default --- zcash_client_backend/src/data_api/testing.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index 4a850a5573..6f34c5bc24 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -2110,10 +2110,9 @@ impl TestFvk for ::orchard::keys::FullViewingKey { /// Configures how a [`TestFvk`] receives a particular output. /// /// Used with [`TestFvk::add_output`] and [`TestFvk::add_logical_action`]. -#[derive(Clone, Copy, Default, Debug)] +#[derive(Clone, Copy, Debug)] pub enum AddressType { /// The output will be sent to the default address of the full viewing key. - #[default] DefaultExternal, /// The output will be sent to the specified diversified address of the full viewing /// key. From 424034cb62837447d5609f2a1b277e0ef27eef4b Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Mon, 17 Nov 2025 09:56:00 +1300 Subject: [PATCH 015/263] better docs, fixed typos --- zcash_client_backend/src/data_api/testing/pool.rs | 12 +----------- .../src/data_api/testing/pool/dsl.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 1836ea73f5..5b6cd7a705 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -3203,7 +3203,7 @@ pub fn zip317_spend( // Add funds to the wallet st.add_notes([Some(Zatoshis::const_from_u64(50000))]); - // Add 10 dust notes to the wallet + // Add 10 uneconomic (dust) notes to the wallet for _ in 1..=10 { st.add_notes([Some(Zatoshis::const_from_u64(1000))]); } @@ -4458,8 +4458,6 @@ pub fn scan_cached_blocks_finds_received_notes( ); } -// TODO: This test can probably be entirely removed, as the following test duplicates it entirely. -// TODO(schell): ^still a valid todo? pub fn scan_cached_blocks_finds_change_notes( ds_factory: Dsf, cache: impl TestCache, @@ -4478,14 +4476,6 @@ pub fn scan_cached_blocks_finds_change_notes( // Create a fake CompactBlock sending value to the address let value = Zatoshis::const_from_u64(50000); let (_, _, nf) = st.add_a_single_note(value); - // let (received_height, _, nf) = - // st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - - // // Scan the cache - // st.scan_cached_blocks(received_height, 1); - - // // Account balance should reflect the received note - // assert_eq!(st.get_total_balance(account.id()), value); // Create a second fake CompactBlock spending value from the address let not_our_key = T::sk_to_fvk(&T::sk(&[0xf5; 32])); diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs index b6025428a4..82155657df 100644 --- a/zcash_client_backend/src/data_api/testing/pool/dsl.rs +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -93,9 +93,11 @@ where /// A proxy for `FakeCompactOutput` that allows test code to omit the `fvk` and /// `address_type` fields, which can be derived from the `TestState` in most cases. pub struct TestNoteConfig { + /// The amount of the note. pub value: Zatoshis, - /// Diversifiable full viewing key of + /// Diversifiable full viewing key of the recipient. pub fvk: Option, + /// Address type of the recipient. pub address_type: Option, } @@ -288,7 +290,7 @@ where /// /// This step also verifies that the test account contains the expected /// funds as part of the _total_. Keep in mind that these funds may not yet - /// be _spendable_ due to the number confirmations required. + /// be _spendable_ due to the number of confirmations required. /// /// Returns a summary of steps. /// @@ -317,8 +319,8 @@ where .map(|into_note_config| { let note_config = into_note_config.into(); if note_config.value > zip317::MARGINAL_FEE { - // Don't include dust in the expected total, as the balance - // won't include it. + // Don't include uneconomic (dust) notes in the expected + // total, as the balance won't include them. expected_total = (expected_total + note_config.value).unwrap(); } (self.make_fake_output(¬e_config), note_config) From 4fc0574a645b5ce5728c3134a33a91fccc6c9170 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Thu, 13 Nov 2025 14:53:48 +1300 Subject: [PATCH 016/263] Remove deprecations from zcash_primitives and zcash_address --- components/zcash_address/CHANGELOG.md | 4 ++ components/zcash_address/src/lib.rs | 3 -- zcash_client_backend/src/data_api/chain.rs | 4 +- zcash_primitives/CHANGELOG.md | 25 +++++++++- .../src/transaction/components.rs | 47 ------------------- .../src/transaction/components/tze.rs | 5 +- zcash_primitives/src/transaction/sighash.rs | 14 ------ 7 files changed, 32 insertions(+), 70 deletions(-) diff --git a/components/zcash_address/CHANGELOG.md b/components/zcash_address/CHANGELOG.md index fd011857f1..c46fa40eb3 100644 --- a/components/zcash_address/CHANGELOG.md +++ b/components/zcash_address/CHANGELOG.md @@ -10,6 +10,10 @@ workspace. ## [Unreleased] +### Removed + +- Removed deprecated `zcash_address::Network`, use `zcash_protocol::consensus::Network` instead. + ## [0.10.1] - 2025-10-18 ### Fixed diff --git a/components/zcash_address/src/lib.rs b/components/zcash_address/src/lib.rs index 713f24b157..27e99421b7 100644 --- a/components/zcash_address/src/lib.rs +++ b/components/zcash_address/src/lib.rs @@ -152,9 +152,6 @@ pub use encoding::ParseError; pub use kind::unified; use kind::unified::Receiver; -#[deprecated(note = "use ::zcash_protocol::consensus::NetworkType instead")] -pub type Network = zcash_protocol::consensus::NetworkType; - use zcash_protocol::{consensus::NetworkType, PoolType}; /// A Zcash address. diff --git a/zcash_client_backend/src/data_api/chain.rs b/zcash_client_backend/src/data_api/chain.rs index 031d7cf026..5b53ad09a1 100644 --- a/zcash_client_backend/src/data_api/chain.rs +++ b/zcash_client_backend/src/data_api/chain.rs @@ -331,7 +331,7 @@ pub trait BlockSource { /// # zcash_primitives::block::BlockHash([0; 32]), /// # sapling::Nullifier([0; 32]), /// # &dfvk, -/// # zcash_primitives::transaction::components::amount::NonNegativeAmount::const_from_u64(5), +/// # zcash_protocol::value::Zatoshis::const_from_u64(5), /// # false, /// # None, /// # ); @@ -340,7 +340,7 @@ pub trait BlockSource { /// # zcash_primitives::block::BlockHash([0; 32]), /// # sapling::Nullifier([0; 32]), /// # &dfvk, -/// # zcash_primitives::transaction::components::amount::NonNegativeAmount::const_from_u64(5), +/// # zcash_protocol::value::Zatoshis::const_from_u64(5), /// # false, /// # None, /// # ); diff --git a/zcash_primitives/CHANGELOG.md b/zcash_primitives/CHANGELOG.md index 91d92b2bfa..a7c18ba526 100644 --- a/zcash_primitives/CHANGELOG.md +++ b/zcash_primitives/CHANGELOG.md @@ -14,7 +14,30 @@ workspace. - MSRV is now 1.85.1. ### Removed -- Removed deprecated modules: + +- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_ALL`, use `zcash_transparent::sighash::SIGHASH_ALL` instead. +- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_NONE`, use `zcash_transparent::sighash::SIGHASH_NONE` instead. +- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_SINGLE`, use `zcash_transparent::sighash::SIGHASH_SINGLE` instead. +- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_MASK`, use `zcash_transparent::sighash::SIGHASH_MASK` instead. +- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_ANYONECANPAY`, use `zcash_transparent::sighash::SIGHASH_ANYONECANPAY` instead. +- Removed deprecated `zcash_primitives::transaction::sighash::SighashType`, use `zcash_transparent::sighash::SighashType` instead. + +- Removed deprecated module `zcash_primitives::transaction::components::amount::testing`: + - `arb_positive_amount`, use `zcash_protocol::value::testing::arb_positive_zat_balance` instead. + - `arb_amount`, use `zcash_protocol::value::testing::arb_zat_balance` + - `arb_nonnegative_amount`, use `zcash_protocol::value::testing::arb_zatoshis` +- Removed deprecated module `zcash_primitives::transaction::components::amount`, use `zcash_protocol::value` instead. +- Removed deprecated module `zcash_primitives::transaction::components::transparent::builder`, use `zcash_transparent::builder` instead. +- Removed deprecated module `zcash_primitives::transaction::components::transparent::pczt`, use `zcash_transparent::pczt` instead. +- Removed deprecated module `zcash_primitives::transaction::components::transparent`, use `zcash_transparent` instead. +- Removed deprecated `zcash_primitives::transaction::components::Outpoint`, use `zcash_transparent::bundle::Outpoint` instead. +- Removed deprecated `zcash_primitives::transaction::components::TxIn`, use `zcash_transparent::bundle::TxIn` instead. +- Removed deprecated `zcash_primitives::transaction::components::TxOut`, use `zcash_transparent::bundle::TxOut` instead. +- Removed deprecated `zcash_primitives::transaction::components::ZatBalance`, use `zcash_protocol::value::ZatBalance` instead. +- Removed deprecated `zcash_primitives::transaction::components::OutputDescription`, use `sapling_crypto::bundle::OutputDescription` instead. +- Removed deprecated `zcash_primitives::transaction::components::SpendDescription`, use `sapling_crypto::bundle::SpendDescription` instead. + +- Removed other deprecated modules: - `zcash_primitives::consensus` - `zcash_primitives::constants` - `zcash_primitives::memo` diff --git a/zcash_primitives/src/transaction/components.rs b/zcash_primitives/src/transaction/components.rs index 944f45e9d9..295ba3d910 100644 --- a/zcash_primitives/src/transaction/components.rs +++ b/zcash_primitives/src/transaction/components.rs @@ -7,53 +7,6 @@ pub mod tze; pub use self::sprout::JsDescription; -#[deprecated(note = "This module is deprecated; use `::zcash_protocol::value` instead.")] -pub mod amount { - #[deprecated(note = "Use `::zcash_protocol::value::BalanceError` instead.")] - pub type BalanceError = zcash_protocol::value::BalanceError; - #[deprecated(note = "Use `::zcash_protocol::value::ZatBalance` instead.")] - pub type Amount = zcash_protocol::value::ZatBalance; - #[deprecated(note = "Use `::zcash_protocol::value::Zatoshis` instead.")] - pub type NonNegativeAmount = zcash_protocol::value::Zatoshis; - #[deprecated(note = "Use `::zcash_protocol::value::COIN` instead.")] - pub const COIN: u64 = zcash_protocol::value::COIN; - - #[cfg(any(test, feature = "test-dependencies"))] - #[deprecated(note = "Use `::zcash_protocol::value::testing` instead.")] - pub mod testing { - pub use zcash_protocol::value::testing::arb_positive_zat_balance as arb_positive_amount; - pub use zcash_protocol::value::testing::arb_zat_balance as arb_amount; - pub use zcash_protocol::value::testing::arb_zatoshis as arb_nonnegative_amount; - } -} - -#[deprecated(note = "This module is deprecated; use the `zcash_transparent` crate instead.")] -pub mod transparent { - #[deprecated(note = "This module is deprecated; use `::zcash_transparent::builder` instead.")] - pub mod builder { - pub use ::transparent::builder::*; - } - pub use ::transparent::bundle::*; - #[deprecated(note = "This module is deprecated; use `::zcash_transparent::pczt` instead.")] - pub mod pczt { - pub use ::transparent::pczt::*; - } -} - -#[deprecated(note = "use `::zcash_transparent::bundle::OutPoint` instead.")] -pub type OutPoint = ::transparent::bundle::OutPoint; -#[deprecated(note = "use `::zcash_transparent::bundle::TxIn` instead.")] -pub type TxIn = ::transparent::bundle::TxIn; -#[deprecated(note = "use `::zcash_transparent::bundle::TxIn` instead.")] -pub type TxOut = ::transparent::bundle::TxOut; -#[deprecated(note = "use `::zcash_protocol::value::ZatBalance` instead.")] -pub type Amount = zcash_protocol::value::ZatBalance; - -#[deprecated(note = "Use `::sapling_crypto::bundle::OutputDescription` instead.")] -pub type OutputDescription = ::sapling::bundle::OutputDescription; -#[deprecated(note = "Use `::sapling_crypto::bundle::SpendDescription` instead.")] -pub type SpendDescription = ::sapling::bundle::SpendDescription; - #[cfg(zcash_unstable = "zfuture")] pub use self::tze::{TzeIn, TzeOut}; diff --git a/zcash_primitives/src/transaction/components/tze.rs b/zcash_primitives/src/transaction/components/tze.rs index 10e85ea308..dc208fceec 100644 --- a/zcash_primitives/src/transaction/components/tze.rs +++ b/zcash_primitives/src/transaction/components/tze.rs @@ -241,11 +241,10 @@ impl TzeOut { pub mod testing { use proptest::collection::vec; use proptest::prelude::*; - use zcash_protocol::consensus::BranchId; + use zcash_protocol::{consensus::BranchId, value::testing::arb_zatoshis}; use crate::{ extensions::transparent::{AuthData, Precondition, Witness}, - transaction::components::amount::testing::arb_nonnegative_amount, transaction::testing::arb_txid, }; @@ -276,7 +275,7 @@ pub mod testing { } prop_compose! { - pub fn arb_tzeout()(value in arb_nonnegative_amount(), precondition in arb_precondition()) -> TzeOut { + pub fn arb_tzeout()(value in arb_zatoshis(), precondition in arb_precondition()) -> TzeOut { TzeOut { value: value.into(), precondition } } } diff --git a/zcash_primitives/src/transaction/sighash.rs b/zcash_primitives/src/transaction/sighash.rs index 3cf7c80746..b55a204c39 100644 --- a/zcash_primitives/src/transaction/sighash.rs +++ b/zcash_primitives/src/transaction/sighash.rs @@ -12,20 +12,6 @@ use {crate::extensions::transparent::Precondition, zcash_protocol::value::Zatosh #[cfg(any(zcash_unstable = "zfuture", zcash_unstable = "nu7"))] use super::sighash_v6::v6_signature_hash; -#[deprecated(note = "use `::zcash_transparent::sighash::SIGHASH_ALL` instead.")] -pub const SIGHASH_ALL: u8 = ::transparent::sighash::SIGHASH_ALL; -#[deprecated(note = "use `::zcash_transparent::sighash::SIGHASH_NONE` instead.")] -pub const SIGHASH_NONE: u8 = ::transparent::sighash::SIGHASH_NONE; -#[deprecated(note = "use `::zcash_transparent::sighash::SIGHASH_SINGLE` instead.")] -pub const SIGHASH_SINGLE: u8 = ::transparent::sighash::SIGHASH_SINGLE; -#[deprecated(note = "use `::zcash_transparent::sighash::SIGHASH_MASK` instead.")] -pub const SIGHASH_MASK: u8 = ::transparent::sighash::SIGHASH_MASK; -#[deprecated(note = "use `::zcash_transparent::sighash::SIGHASH_ANYONECANPAY` instead.")] -pub const SIGHASH_ANYONECANPAY: u8 = ::transparent::sighash::SIGHASH_ANYONECANPAY; - -#[deprecated(note = "use `::zcash_transparent::sighash::SighashType` instead.")] -pub type SighashType = ::transparent::sighash::SighashType; - pub enum SignableInput<'a> { Shielded, Transparent(transparent::sighash::SignableInput<'a>), From e3133a5727598cccad9e186f00b05be86cf9f94d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 05:02:31 +0000 Subject: [PATCH 017/263] build(deps): bump actions/checkout from 5 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/audits.yml | 4 ++-- .github/workflows/book.yml | 2 +- .github/workflows/ci.yml | 30 +++++++++++++++--------------- .github/workflows/zizmor.yml | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/audits.yml b/.github/workflows/audits.yml index 3c72aeff5d..d85fe0e9ee 100644 --- a/.github/workflows/audits.yml +++ b/.github/workflows/audits.yml @@ -13,7 +13,7 @@ jobs: name: Vet Rust dependencies runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - uses: dtolnay/rust-toolchain@stable @@ -28,7 +28,7 @@ jobs: name: Check licenses runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - uses: EmbarkStudios/cargo-deny-action@f2ba7abc2abebaf185c833c3961145a3c275caad # v2.0.13 diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 1750e07914..03ef63dde8 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -9,7 +9,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 468f1c599d..e8449beef3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: RUSTDOCFLAGS: ${{ matrix.rustflags }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -122,7 +122,7 @@ jobs: RUSTDOCFLAGS: ${{ matrix.rustflags }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -184,7 +184,7 @@ jobs: RUSTDOCFLAGS: ${{ matrix.rustflags }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -246,7 +246,7 @@ jobs: RUSTDOCFLAGS: ${{ matrix.rustflags }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -280,7 +280,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -324,7 +324,7 @@ jobs: build_deps: > gcc-multilib steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false path: crates @@ -370,7 +370,7 @@ jobs: build_deps: > gcc-arm-none-eabi steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false path: crates @@ -415,7 +415,7 @@ jobs: name: Bitrot check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false # Build benchmarks to prevent bitrot @@ -428,7 +428,7 @@ jobs: permissions: checks: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false # We can't currently use only the common feature set (to exclude checking of @@ -452,7 +452,7 @@ jobs: checks: write continue-on-error: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false # We can't currently use only the common feature set (to exclude checking of @@ -485,7 +485,7 @@ jobs: options: --security-opt seccomp=unconfined steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -518,7 +518,7 @@ jobs: name: Intra-doc links runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -544,7 +544,7 @@ jobs: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Check formatting @@ -554,7 +554,7 @@ jobs: name: protobuf consistency runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - id: prepare @@ -580,7 +580,7 @@ jobs: name: UUID validity runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Extract UUIDs diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index ac7ada0b9c..e45d095409 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -15,7 +15,7 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0 + a doc-only README update + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.0 + a doc-only README update with: persist-credentials: false - name: Install the latest version of uv From 6b818313c0213c0debe0bae5659750c1d8904f58 Mon Sep 17 00:00:00 2001 From: Daira-Emma Hopwood Date: Mon, 24 Nov 2025 17:42:58 +0000 Subject: [PATCH 018/263] zizmor.yml: update actions/checkout to pinned v6.0.0 Signed-off-by: Daira-Emma Hopwood --- .github/workflows/zizmor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index e45d095409..221d6ac104 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -15,7 +15,7 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.0 + a doc-only README update + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false - name: Install the latest version of uv From 3645510ffe23f2ad10e4cc9dabd2c86d3242669f Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Tue, 25 Nov 2025 12:06:08 +1300 Subject: [PATCH 019/263] TestDsl::first_block_height and TestDsl::block_height return Option, renamed TestDsl::with_standard_sapling_account to TestDsl::with_sapling_birthday_account --- .../src/data_api/testing/pool.rs | 93 ++++++++++--------- .../src/data_api/testing/pool/dsl.rs | 18 +--- 2 files changed, 53 insertions(+), 58 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 5b6cd7a705..20d44d6f02 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -204,7 +204,7 @@ pub fn send_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in a single note let (h, _, _) = st.add_a_single_note(Zatoshis::const_from_u64(60000)); @@ -366,7 +366,7 @@ pub fn zip_315_confirmations_test_steps( cache: impl TestCache, input_trust: InputTrust, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); let account = st.test_account().cloned().unwrap(); let starting_balance = Zatoshis::const_from_u64(60_000); @@ -454,13 +454,14 @@ pub fn spend_max_spendable_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in two notes over 5 blocks let value = Zatoshis::const_from_u64(60000); let h = st .add_notes([Some(value), None, None, None, Some(value)]) - .block_height(); + .block_height() + .unwrap(); // Spendable balance matches total balance let account = st.test_account().cloned().unwrap(); @@ -605,7 +606,7 @@ pub fn spend_everything_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -739,7 +740,7 @@ pub fn fails_to_send_max_spendable_to_transparent_with_memo(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in a single note st.add_a_single_note(Zatoshis::const_from_u64(60000)); @@ -783,7 +784,7 @@ pub fn spend_everything_proposal_fails_when_unconfirmed_funds_present(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); st.add_notes([ Some(Zatoshis::const_from_u64(60000)), None, @@ -847,7 +848,7 @@ pub fn send_max_spendable_proposal_succeeds_when_unconfirmed_funds_present< dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); let h = st .add_notes([ Some(Zatoshis::const_from_u64(60000)), @@ -855,7 +856,8 @@ pub fn send_max_spendable_proposal_succeeds_when_unconfirmed_funds_present< None, Some(Zatoshis::const_from_u64(123456)), ]) - .block_height(); + .block_height() + .unwrap(); // Spendable balance doesn't match total balance let account = st.test_account().cloned().unwrap(); @@ -998,7 +1000,7 @@ pub fn spend_everything_multi_step_single_note_proposed_transfer(); @@ -1155,7 +1157,7 @@ pub fn spend_everything_multi_step_many_notes_proposed_transfer(); @@ -1309,7 +1311,7 @@ pub fn spend_everything_multi_step_with_marginal_notes_proposed_transfer< { use crate::data_api::{MaxSpendMode, OutputOfSentTx, testing::transparent::GapLimits}; - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) .build::(); @@ -1457,7 +1459,7 @@ pub fn send_with_multiple_change_outputs( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(650_0000); @@ -1628,7 +1630,7 @@ pub fn send_multi_step_proposed_transfer( }; let gap_limits = GapLimits::new(10, 5, 3); - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(gap_limits)) .build::(); @@ -1978,7 +1980,7 @@ pub fn spend_all_funds_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(60000); @@ -2130,7 +2132,7 @@ pub fn spend_all_funds_multi_step_proposed_transfer( { use crate::data_api::{OutputOfSentTx, testing::transparent::GapLimits}; - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache) + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache) .map(|builder| builder.with_gap_limits(GapLimits::new(10, 5, 3))) .build::(); @@ -2277,7 +2279,7 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2356,7 +2358,7 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( ds_factory: Dsf, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, ()).build::(); let dfvk = T::test_account_fvk(&st); let to = T::fvk_default_address(&dfvk); @@ -2393,7 +2395,7 @@ where Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, ()).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, ()).build::(); let account_id = st.test_account().unwrap().id(); let dfvk = T::test_account_fvk(&st); @@ -2422,7 +2424,7 @@ pub fn spend_fails_on_unverified_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2603,7 +2605,7 @@ pub fn spend_fails_on_locked_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let fee_rule = StandardFeeRule::Zip317; @@ -2738,7 +2740,7 @@ pub fn ovk_policy_prevents_recovery_from_chain( ) where Dsf: DataStoreFactory, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -2818,7 +2820,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(70000); @@ -2854,7 +2856,7 @@ pub fn change_note_spends_succeed( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); // Add funds to the wallet in a single note owned by the internal spending key let value = Zatoshis::const_from_u64(70000); @@ -3194,7 +3196,7 @@ pub fn zip317_spend( ds_factory: Dsf, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let account_id = account.id(); @@ -3281,7 +3283,7 @@ where use zcash_keys::keys::UnifiedAddressRequest; use zcash_primitives::transaction::builder::DEFAULT_TX_EXPIRY_DELTA; - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -3532,7 +3534,7 @@ pub fn checkpoint_gaps( ds_factory: Dsf, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); // Generate a block with funds belonging to our wallet. st.add_a_single_note(Zatoshis::const_from_u64(500000)); @@ -3614,7 +3616,7 @@ pub fn pool_crossing_required( // TODO: Allow for Orchard activation after Sapling // Here we choose P0, but this has no effect since we supply the viewing keys // and generate the blocks directly on the state. - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -3702,7 +3704,7 @@ pub fn fully_funded_fully_private(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -3792,7 +3794,7 @@ pub fn fully_funded_send_to_t( cache: impl TestCache, ) { // TODO: Allow for Orchard activation after Sapling - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -3882,7 +3884,7 @@ pub fn multi_pool_checkpoint( cache: impl TestCache, ) { // TODO: Allow for Orchard activation after Sapling - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let acct_id = account.id(); @@ -4051,7 +4053,7 @@ pub fn multi_pool_checkpoints_with_pruning(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -4080,7 +4082,7 @@ pub fn valid_chain_states( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let dfvk = T::test_account_fvk(&st); @@ -4114,7 +4116,7 @@ pub fn invalid_chain_cache_disconnected( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let dfvk = T::test_account_fvk(&st); @@ -4169,7 +4171,7 @@ where Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4231,7 +4233,7 @@ where ::AccountId: std::fmt::Debug, C: TestCache, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); @@ -4365,7 +4367,7 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4420,7 +4422,7 @@ pub fn scan_cached_blocks_finds_received_notes( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4465,7 +4467,7 @@ pub fn scan_cached_blocks_finds_change_notes( Dsf: DataStoreFactory, ::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4500,7 +4502,7 @@ pub fn scan_cached_blocks_detects_spends_out_of_order::AccountId: std::fmt::Debug, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let account = st.test_account().cloned().unwrap(); let dfvk = T::test_account_fvk(&st); @@ -4546,7 +4548,7 @@ pub fn metadata_queries_exclude_unwanted_notes( ::AccountId: std::fmt::Debug, TC: TestCache, { - let mut st = TestDsl::with_standard_sapling_account(ds_factory, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); // Create 10 blocks with successively increasing value let note_values = (1..=10) @@ -4554,7 +4556,8 @@ pub fn metadata_queries_exclude_unwanted_notes( .collect::>(); let h0 = st .add_notes(note_values.clone().into_iter().map(Some)) - .first_block_height(); + .first_block_height() + .unwrap(); let target_height = TargetHeight::from(h0 + 10); let account = st.test_account().cloned().unwrap(); @@ -4747,7 +4750,7 @@ pub fn wallet_recovery_computes_fees(); + let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); let seed = Secret::new(st.test_seed().unwrap().expose_secret().clone()); let source_account = st.test_account().cloned().unwrap(); @@ -4893,11 +4896,11 @@ pub fn receive_two_notes_with_same_value( dsf: impl DataStoreFactory, cache: impl TestCache, ) { - let mut st = TestDsl::with_standard_sapling_account(dsf, cache).build::(); + let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in two identical notes let value = Zatoshis::const_from_u64(60000); - let h = st.add_notes([[value, value]]).block_height(); + let h = st.add_notes([[value, value]]).block_height().unwrap(); // Spendable balance matches total balance. let account = st.test_account().cloned().unwrap(); diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs index 82155657df..6bbb38aef3 100644 --- a/zcash_client_backend/src/data_api/testing/pool/dsl.rs +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -71,7 +71,7 @@ where /// .with_account_from_sapling_activation(BlockHash([0; 32])) /// .into(); /// ``` - pub fn with_standard_sapling_account(dsf: Dsf, tc: Cache) -> Self { + pub fn with_sapling_birthday_account(dsf: Dsf, tc: Cache) -> Self { TestBuilder::new() .with_data_store_factory(dsf) .with_block_cache(tc) @@ -153,22 +153,14 @@ impl Default for AddFundsSummary { impl AddFundsSummary { /// Return the first block height. - pub fn first_block_height(&self) -> BlockHeight { - if let Some(step) = self.steps.first() { - step.results.block_height - } else { - BlockHeight::from_u32(0) - } + pub fn first_block_height(&self) -> Option { + self.steps.first().map(|step| step.results.block_height) } /// Return the latest block height after generating the blocks /// that added funds. - pub fn block_height(&self) -> BlockHeight { - if let Some(step) = self.steps.last() { - step.results.block_height - } else { - BlockHeight::from_u32(0) - } + pub fn block_height(&self) -> Option { + self.steps.last().map(|step| step.results.block_height) } } From a3dfd9ecb883c38e3c2cc8c739d6538ad5860ba0 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Tue, 25 Nov 2025 15:05:10 +1300 Subject: [PATCH 020/263] Rename TestDsl::add_a_single_note and add_notes with *_checking_balance suffix --- .../src/data_api/testing/pool.rs | 63 ++++++++++--------- .../src/data_api/testing/pool/dsl.rs | 25 ++++++-- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 20d44d6f02..d9bb512baa 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -207,7 +207,7 @@ pub fn send_single_step_proposed_transfer( let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in a single note - let (h, _, _) = st.add_a_single_note(Zatoshis::const_from_u64(60000)); + let (h, _, _) = st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(60000)); let to_extsk = T::sk(&[0xf5; 32]); let to: Address = T::sk_default_address(&to_extsk); @@ -385,8 +385,9 @@ pub fn zip_315_confirmations_test_steps( }; let min_confirmations = u32::from(min_confirmations); - let (_, r, _) = st - .add_a_single_note(TestNoteConfig::from(starting_balance).with_address_type(address_type)); + let (_, r, _) = st.add_a_single_note_checking_balance( + TestNoteConfig::from(starting_balance).with_address_type(address_type), + ); let txid = r.txids()[0]; // Mark the external input as explicitly trusted, if so requested @@ -459,7 +460,7 @@ pub fn spend_max_spendable_single_step_proposed_transfer( // Add funds to the wallet in two notes over 5 blocks let value = Zatoshis::const_from_u64(60000); let h = st - .add_notes([Some(value), None, None, None, Some(value)]) + .add_notes_checking_balance([Some(value), None, None, None, Some(value)]) .block_height() .unwrap(); @@ -611,7 +612,7 @@ pub fn spend_everything_single_step_proposed_transfer( let account = st.test_account().cloned().unwrap(); // Add funds to the wallet in a single note - let (h, _, _) = st.add_a_single_note(Zatoshis::const_from_u64(60000)); + let (h, _, _) = st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(60000)); let to_extsk = T::sk(&[0xf5; 32]); let to: Address = T::sk_default_address(&to_extsk); @@ -743,7 +744,7 @@ pub fn fails_to_send_max_spendable_to_transparent_with_memo(); // Add funds to the wallet in a single note - st.add_a_single_note(Zatoshis::const_from_u64(60000)); + st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(60000)); let account = st.test_account().cloned().unwrap(); let (default_addr, _) = account.usk().default_transparent_address(); @@ -785,7 +786,7 @@ pub fn spend_everything_proposal_fails_when_unconfirmed_funds_present(); - st.add_notes([ + st.add_notes_checking_balance([ Some(Zatoshis::const_from_u64(60000)), None, None, @@ -840,8 +841,7 @@ pub fn spend_everything_proposal_fails_when_unconfirmed_funds_present( @@ -850,7 +850,7 @@ pub fn send_max_spendable_proposal_succeeds_when_unconfirmed_funds_present< ) { let mut st = TestDsl::with_sapling_birthday_account(dsf, cache).build::(); let h = st - .add_notes([ + .add_notes_checking_balance([ Some(Zatoshis::const_from_u64(60000)), None, None, @@ -1010,7 +1010,7 @@ pub fn spend_everything_multi_step_single_note_proposed_transfer( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(650_0000); - let (h, _, _) = st.add_a_single_note(value); + let (h, _, _) = st.add_a_single_note_checking_balance(value); let to_extsk = T::sk(&[0xf5; 32]); let to: Address = T::sk_default_address(&to_extsk); @@ -1984,7 +1984,7 @@ pub fn spend_all_funds_single_step_proposed_transfer( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.add_a_single_note(value); + let (h, _, _) = st.add_a_single_note_checking_balance(value); let spend_amount = Zatoshis::const_from_u64(50000); let to_extsk = T::sk(&[0xf5; 32]); @@ -2432,7 +2432,7 @@ pub fn spend_fails_on_unverified_notes( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(50000); - st.add_a_single_note(value); + st.add_a_single_note_checking_balance(value); // Value is considered pending at 10 confirmations. assert_eq!( @@ -2458,7 +2458,7 @@ pub fn spend_fails_on_unverified_notes( assert_eq!(summary.map(|s| s.progress().scan()), Some(Ratio::new(1, 1))); // Add more funds to the wallet in a second note - let (h2, _, _) = st.add_a_single_note(value); + let (h2, _, _) = st.add_a_single_note_checking_balance(value); // Verified balance does not include the second note let total = (value + value).unwrap(); @@ -2611,7 +2611,7 @@ pub fn spend_fails_on_locked_notes( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(50000); - let (h1, _, _) = st.add_a_single_note(value); + let (h1, _, _) = st.add_a_single_note_checking_balance(value); // Send some of the funds to another address, but don't mine the tx. let extsk2 = T::sk(&[0xf5; 32]); @@ -2748,7 +2748,7 @@ pub fn ovk_policy_prevents_recovery_from_chain( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(50000); - let (h1, _, _) = st.add_a_single_note(value); + let (h1, _, _) = st.add_a_single_note_checking_balance(value); let extsk2 = T::sk(&[0xf5; 32]); let addr2 = T::sk_default_address(&extsk2); @@ -2824,7 +2824,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(70000); - st.add_a_single_note(value); + st.add_a_single_note_checking_balance(value); let fee_rule = StandardFeeRule::Zip317; @@ -2860,7 +2860,9 @@ pub fn change_note_spends_succeed( // Add funds to the wallet in a single note owned by the internal spending key let value = Zatoshis::const_from_u64(70000); - st.add_a_single_note(TestNoteConfig::from(value).with_address_type(AddressType::Internal)); + st.add_a_single_note_checking_balance( + TestNoteConfig::from(value).with_address_type(AddressType::Internal), + ); // Value is considered pending at 10 confirmations. let account = st.test_account().cloned().unwrap(); @@ -3203,11 +3205,11 @@ pub fn zip317_spend( let dfvk = T::test_account_fvk(&st); // Add funds to the wallet - st.add_notes([Some(Zatoshis::const_from_u64(50000))]); + st.add_notes_checking_balance([Some(Zatoshis::const_from_u64(50000))]); // Add 10 uneconomic (dust) notes to the wallet for _ in 1..=10 { - st.add_notes([Some(Zatoshis::const_from_u64(1000))]); + st.add_notes_checking_balance([Some(Zatoshis::const_from_u64(1000))]); } // Spendable balance matches total balance @@ -3537,7 +3539,7 @@ pub fn checkpoint_gaps( let mut st = TestDsl::with_sapling_birthday_account(ds_factory, cache).build::(); // Generate a block with funds belonging to our wallet. - st.add_a_single_note(Zatoshis::const_from_u64(500000)); + st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(500000)); // Create a gap of 10 blocks having no shielded outputs, then add a block that doesn't // belong to us so that we can get a checkpoint in the tree. @@ -4477,7 +4479,7 @@ pub fn scan_cached_blocks_finds_change_notes( // Create a fake CompactBlock sending value to the address let value = Zatoshis::const_from_u64(50000); - let (_, _, nf) = st.add_a_single_note(value); + let (_, _, nf) = st.add_a_single_note_checking_balance(value); // Create a second fake CompactBlock spending value from the address let not_our_key = T::sk_to_fvk(&T::sk(&[0xf5; 32])); @@ -4555,7 +4557,7 @@ pub fn metadata_queries_exclude_unwanted_notes( .map(|i| Zatoshis::const_from_u64(i * 100_0000)) .collect::>(); let h0 = st - .add_notes(note_values.clone().into_iter().map(Some)) + .add_notes_checking_balance(note_values.clone().into_iter().map(Some)) .first_block_height() .unwrap(); @@ -4763,7 +4765,7 @@ pub fn wallet_recovery_computes_fees( // Add funds to the wallet in two identical notes let value = Zatoshis::const_from_u64(60000); - let h = st.add_notes([[value, value]]).block_height().unwrap(); + let h = st + .add_notes_checking_balance([[value, value]]) + .block_height() + .unwrap(); // Spendable balance matches total balance. let account = st.test_account().cloned().unwrap(); diff --git a/zcash_client_backend/src/data_api/testing/pool/dsl.rs b/zcash_client_backend/src/data_api/testing/pool/dsl.rs index 6bbb38aef3..5586139c8c 100644 --- a/zcash_client_backend/src/data_api/testing/pool/dsl.rs +++ b/zcash_client_backend/src/data_api/testing/pool/dsl.rs @@ -234,7 +234,7 @@ where /// This also verifies that the test account contains the expected funds as /// part of the _total_, and that the funds are spendable with the minimum number /// of confirmations. - pub fn add_a_single_note( + pub fn add_a_single_note_checking_balance( &mut self, note: impl Into>, ) -> ( @@ -242,16 +242,24 @@ where Cache::InsertResult, ::Nullifier, ) { - let mut summary = self.add_notes([[note]]); + let mut summary = self.add_notes_checking_balance([[note]]); let res = summary.steps.pop().unwrap().results; (res.block_height, res.insert_result, res.nullifiers[0]) } + fn scanned_block_height(&self) -> BlockHeight { + self.wallet() + .block_max_scanned() + .unwrap() + .map(|meta| meta.block_height()) + .unwrap_or_else(|| BlockHeight::from_u32(0)) + } + /// Generates `N` empty blocks. /// /// Returns the current block height. pub fn add_empty_blocks(&mut self, n: usize) -> BlockHeight { - let mut out_height = BlockHeight::from_u32(0); + let mut out_height = self.scanned_block_height(); for _ in 0..n { let (h, _) = self.generate_empty_block(); out_height = h; @@ -286,16 +294,23 @@ where /// /// Returns a summary of steps. /// + /// ## Parameters + /// + /// * `blocks` - A collection of "blocks", where each "block" is a collection of + /// "notes". More specifically, "notes" can be anything that can be converted + /// into a [`TestNoteConfig`]. This allows you to add multiple blocks that each + /// containing zero or more notes with one call to `add_notes`. + /// /// ## Note /// Keep in mind: /// * Each block coalesces these notes into a single transaction. /// * Funds are added to the default test account. - pub fn add_notes( + pub fn add_notes_checking_balance( &mut self, blocks: impl IntoIterator>>>, ) -> AddFundsSummary { let mut from_height = None; - let mut current_height = BlockHeight::from_u32(0); + let mut current_height = self.scanned_block_height(); let mut limit = 0; let account = self.get_account(); let starting_balance = self From fe64d7f992934b34571589b8aa24bf38dfa63075 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Tue, 25 Nov 2025 09:49:39 -0700 Subject: [PATCH 021/263] Apply suggestions from code review Co-authored-by: Daira-Emma Hopwood --- zcash_primitives/CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/zcash_primitives/CHANGELOG.md b/zcash_primitives/CHANGELOG.md index a7c18ba526..d2e66e49c1 100644 --- a/zcash_primitives/CHANGELOG.md +++ b/zcash_primitives/CHANGELOG.md @@ -22,10 +22,11 @@ workspace. - Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_ANYONECANPAY`, use `zcash_transparent::sighash::SIGHASH_ANYONECANPAY` instead. - Removed deprecated `zcash_primitives::transaction::sighash::SighashType`, use `zcash_transparent::sighash::SighashType` instead. -- Removed deprecated module `zcash_primitives::transaction::components::amount::testing`: - - `arb_positive_amount`, use `zcash_protocol::value::testing::arb_positive_zat_balance` instead. - - `arb_amount`, use `zcash_protocol::value::testing::arb_zat_balance` - - `arb_nonnegative_amount`, use `zcash_protocol::value::testing::arb_zatoshis` +- Removed deprecated module `zcash_primitives::transaction::components::amount::testing`, + use `zcash_protocol::value::testing` instead with the following renames: + - `arb_positive_amount` to `zcash_protocol::value::testing::arb_positive_zat_balance` + - `arb_amount` to `zcash_protocol::value::testing::arb_zat_balance` + - `arb_nonnegative_amount` to `zcash_protocol::value::testing::arb_zatoshis`. - Removed deprecated module `zcash_primitives::transaction::components::amount`, use `zcash_protocol::value` instead. - Removed deprecated module `zcash_primitives::transaction::components::transparent::builder`, use `zcash_transparent::builder` instead. - Removed deprecated module `zcash_primitives::transaction::components::transparent::pczt`, use `zcash_transparent::pczt` instead. From b7e65935442141ae19b5b61480ceadb64a2f5fbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 05:01:59 +0000 Subject: [PATCH 022/263] build(deps): bump EmbarkStudios/cargo-deny-action from 2.0.13 to 2.0.14 Bumps [EmbarkStudios/cargo-deny-action](https://github.com/embarkstudios/cargo-deny-action) from 2.0.13 to 2.0.14. - [Release notes](https://github.com/embarkstudios/cargo-deny-action/releases) - [Commits](https://github.com/embarkstudios/cargo-deny-action/compare/f2ba7abc2abebaf185c833c3961145a3c275caad...76cd80eb775d7bbbd2d80292136d74d39e1b4918) --- updated-dependencies: - dependency-name: EmbarkStudios/cargo-deny-action dependency-version: 2.0.14 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/audits.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/audits.yml b/.github/workflows/audits.yml index 3c72aeff5d..ced9278cb3 100644 --- a/.github/workflows/audits.yml +++ b/.github/workflows/audits.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: EmbarkStudios/cargo-deny-action@f2ba7abc2abebaf185c833c3961145a3c275caad # v2.0.13 + - uses: EmbarkStudios/cargo-deny-action@76cd80eb775d7bbbd2d80292136d74d39e1b4918 # v2.0.14 with: command: check licenses From 80b1d26d6b813029481a714838e725dd3c5f1440 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 3 Nov 2025 16:48:49 -0700 Subject: [PATCH 023/263] zcash_keys: Add `UnifiedFullViewingKey::select_ovk`. --- zcash_keys/CHANGELOG.md | 4 ++ zcash_keys/src/keys.rs | 105 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/zcash_keys/CHANGELOG.md b/zcash_keys/CHANGELOG.md index e12e4444e0..6f6c9a2c00 100644 --- a/zcash_keys/CHANGELOG.md +++ b/zcash_keys/CHANGELOG.md @@ -9,6 +9,10 @@ workspace. ## [Unreleased] +### Added +- `zcash_keys::keys::OutgoingViewingKey` +- `zcash_keys::keys::UnifiedFullViewingKey::select_ovk` + ### Changed - MSRV is now 1.85.1. diff --git a/zcash_keys/src/keys.rs b/zcash_keys/src/keys.rs index b880f6d8a4..ccf92b7ecc 100644 --- a/zcash_keys/src/keys.rs +++ b/zcash_keys/src/keys.rs @@ -4,9 +4,10 @@ use ::transparent::keys::TransparentKeyScope; use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::fmt::{self, Display}; +use nonempty::NonEmpty; use zcash_address::unified::{self, Container, Encoding, Typecode, Ufvk, Uivk}; -use zcash_protocol::consensus; +use zcash_protocol::{PoolType, consensus}; use zip32::{AccountId, DiversifierIndex}; use crate::address::UnifiedAddress; @@ -758,6 +759,51 @@ impl From for DerivationError { } } +/// A key that provides the capability to recover outgoing transaction information from +/// the block chain. +#[derive(Debug, Clone, Copy)] +pub struct OutgoingViewingKey([u8; 32]); + +impl From<[u8; 32]> for OutgoingViewingKey { + fn from(ovk: [u8; 32]) -> Self { + OutgoingViewingKey(ovk) + } +} + +#[cfg(feature = "sapling")] +impl From for ::sapling::keys::OutgoingViewingKey { + fn from(value: OutgoingViewingKey) -> Self { + ::sapling::keys::OutgoingViewingKey(value.0) + } +} + +#[cfg(feature = "sapling")] +impl From<::sapling::keys::OutgoingViewingKey> for OutgoingViewingKey { + fn from(value: ::sapling::keys::OutgoingViewingKey) -> Self { + OutgoingViewingKey(value.0) + } +} + +#[cfg(feature = "orchard")] +impl From for ::orchard::keys::OutgoingViewingKey { + fn from(value: OutgoingViewingKey) -> Self { + ::orchard::keys::OutgoingViewingKey::from(value.0) + } +} + +#[cfg(feature = "orchard")] +impl From<::orchard::keys::OutgoingViewingKey> for OutgoingViewingKey { + fn from(value: ::orchard::keys::OutgoingViewingKey) -> Self { + OutgoingViewingKey(*value.as_ref()) + } +} + +impl AsRef<[u8; 32]> for OutgoingViewingKey { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + /// A [ZIP 316](https://zips.z.cash/zip-0316) unified full viewing key. #[derive(Clone, Debug)] pub struct UnifiedFullViewingKey { @@ -1080,6 +1126,63 @@ impl UnifiedFullViewingKey { .default_address() }) } + + /// Selects an outgoing viewing key for a transaction's outputs based upon the type(s) of + /// inputs spent in the transaction. + /// + /// This method selects the OVK of the highest-preference item in [ZIP 316] preference order + /// from among the item types represented by the provided input types. It will return `None` in + /// the case that this FVK does not contain any items corresponding to the provided input + /// sources; this should ordinarily never occur because in order to spend an input, a spending + /// key of the appropriate type must be available and that spending key should be represented + /// among this UFVK's items. + pub fn select_ovk( + &self, + scope: zip32::Scope, + input_sources: &NonEmpty, + ) -> Option { + #[cfg(feature = "orchard")] + if let Some(ovk) = input_sources + .contains(&PoolType::ORCHARD) + .then(|| { + self.orchard() + .map(|k| OutgoingViewingKey::from(k.to_ovk(scope))) + }) + .flatten() + { + return Some(ovk); + }; + + #[cfg(feature = "sapling")] + if let Some(ovk) = input_sources + .contains(&PoolType::SAPLING) + .then(|| { + self.sapling() + .map(|k| OutgoingViewingKey::from(k.to_ovk(scope))) + }) + .flatten() + { + return Some(ovk); + } + + #[cfg(feature = "transparent-inputs")] + if let Some(ovk) = input_sources + .contains(&PoolType::Transparent) + .then(|| { + self.transparent().map(|k| { + OutgoingViewingKey(match scope { + Scope::External => k.external_ovk().as_bytes(), + Scope::Internal => k.internal_ovk().as_bytes(), + }) + }) + }) + .flatten() + { + return Some(ovk); + } + + None + } } /// A [ZIP 316](https://zips.z.cash/zip-0316) unified incoming viewing key. From d1700ce2abfb64cc97b254d811a8ede29b765827 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 26 Nov 2025 10:06:35 -0700 Subject: [PATCH 024/263] zcash_client_backend: Modify transaction construction to use `UnifiedFullViewingKey::select_ovk` This alters the OVK behavior for transactions created by `zcash_client_backend::data_api::wallet::create_proposed_transaction` to mirror the approach implemented by `z_sendmany` in `zcashd`. Prior to this change, external outputs to a particular pool were made decryptable by the pool-specific OVK corresponding to the UFVK for account that provided funds to the transaction, irrespective of whether any of the funds provided were sourced from that pool. After this change, a single preferred OVK is selected from the UFVK for the source account based upon the pools that provided inputs to the transaction; that OVK is then used to encrypt all external outputs, irrespective of pool. --- zcash_client_backend/src/data_api/error.rs | 1 + zcash_client_backend/src/data_api/wallet.rs | 122 ++++++++++---------- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/zcash_client_backend/src/data_api/error.rs b/zcash_client_backend/src/data_api/error.rs index 044e141adc..83025398ff 100644 --- a/zcash_client_backend/src/data_api/error.rs +++ b/zcash_client_backend/src/data_api/error.rs @@ -43,6 +43,7 @@ pub enum Error ufvk.sapling().map(|k| k.fvk().clone()), @@ -1259,44 +1278,28 @@ where utxos_spent }; - #[cfg(feature = "orchard")] - let orchard_external_ovk = match &ovk_policy { - OvkPolicy::Sender => ufvk - .orchard() - .map(|fvk| fvk.to_ovk(orchard::keys::Scope::External)), - OvkPolicy::Custom { orchard, .. } => Some(orchard.clone()), - OvkPolicy::Discard => None, - }; - - #[cfg(feature = "orchard")] - let orchard_internal_ovk = || { - #[cfg(feature = "transparent-inputs")] - if proposal_step.is_shielding() { - return ufvk - .transparent() - .map(|k| orchard::keys::OutgoingViewingKey::from(k.internal_ovk().as_bytes())); + let external_ovk = match ovk_policy { + OvkPolicy::Sender => Some( + ufvk.select_ovk(zip32::Scope::External, &input_sources) + .ok_or(Error::KeyNotAvailable(input_sources.head))?, + ), + OvkPolicy::Custom { + sapling, + #[cfg(feature = "orchard")] + orchard, + } => { + let mut ovk = Some(OutgoingViewingKey::from(sapling)); + #[cfg(feature = "orchard")] + if input_sources.contains(&PoolType::ORCHARD) { + ovk = Some(OutgoingViewingKey::from(orchard)); + } + ovk } - - ufvk.orchard().map(|k| k.to_ovk(Scope::Internal)) - }; - - // Apply the outgoing viewing key policy. - let sapling_external_ovk = match &ovk_policy { - OvkPolicy::Sender => ufvk.sapling().map(|k| k.to_ovk(Scope::External)), - OvkPolicy::Custom { sapling, .. } => Some(*sapling), OvkPolicy::Discard => None, }; - - let sapling_internal_ovk = || { - #[cfg(feature = "transparent-inputs")] - if proposal_step.is_shielding() { - return ufvk - .transparent() - .map(|k| sapling::keys::OutgoingViewingKey(k.internal_ovk().as_bytes())); - } - - ufvk.sapling().map(|k| k.to_ovk(Scope::Internal)) - }; + let internal_ovk = ufvk + .select_ovk(zip32::Scope::Internal, &input_sources) + .ok_or(Error::KeyNotAvailable(input_sources.head))?; #[cfg(feature = "orchard")] let mut orchard_output_meta: Vec<(BuildRecipient<_>, Zatoshis, Option)> = vec![]; @@ -1318,25 +1321,28 @@ where ); let recipient_address = payment.recipient_address(); - let add_sapling_output = |builder: &mut Builder<_, _>, - sapling_output_meta: &mut Vec<_>, - to: sapling::PaymentAddress| - -> Result< - (), - CreateErrT, - > { - let memo = payment.memo().map_or_else(MemoBytes::empty, |m| m.clone()); - builder.add_sapling_output(sapling_external_ovk, to, payment.amount(), memo.clone())?; - sapling_output_meta.push(( - BuildRecipient::External { - recipient_address: recipient_address.clone(), - output_pool: PoolType::SAPLING, - }, - payment.amount(), - Some(memo), - )); - Ok(()) - }; + let add_sapling_output = + |builder: &mut Builder<_, _>, + sapling_output_meta: &mut Vec<_>, + to: sapling::PaymentAddress| + -> Result<(), CreateErrT> { + let memo = payment.memo().map_or_else(MemoBytes::empty, |m| m.clone()); + builder.add_sapling_output( + external_ovk.map(|k| k.into()), + to, + payment.amount(), + memo.clone(), + )?; + sapling_output_meta.push(( + BuildRecipient::External { + recipient_address: recipient_address.clone(), + output_pool: PoolType::SAPLING, + }, + payment.amount(), + Some(memo), + )); + Ok(()) + }; #[cfg(feature = "orchard")] let add_orchard_output = @@ -1346,7 +1352,7 @@ where -> Result<(), CreateErrT> { let memo = payment.memo().map_or_else(MemoBytes::empty, |m| m.clone()); builder.add_orchard_output( - orchard_external_ovk.clone(), + external_ovk.map(|k| k.into()), to, payment.amount().into(), memo.clone(), @@ -1435,7 +1441,7 @@ where match output_pool { PoolType::Shielded(ShieldedProtocol::Sapling) => { builder.add_sapling_output( - sapling_internal_ovk(), + Some(internal_ovk.into()), ufvk.sapling() .ok_or(Error::KeyNotAvailable(PoolType::SAPLING))? .change_address() @@ -1459,7 +1465,7 @@ where #[cfg(feature = "orchard")] { builder.add_orchard_output( - orchard_internal_ovk(), + Some(internal_ovk.into()), ufvk.orchard() .ok_or(Error::KeyNotAvailable(PoolType::ORCHARD))? .address_at(0u32, orchard::keys::Scope::Internal), From 3363b6fe0e6ff97d45cb7dd744b703233d01c22d Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 26 Nov 2025 16:46:36 -0700 Subject: [PATCH 025/263] zcash_client_backend: Modify `OvkPolicy` to make transactions decryptable with a single OVK Prior to this change: - When using `OvkPolicy::Custom`, external outputs were made decryptable with the OVK corresponding to the pool in which those outputs were produced. - Internal outputs were always made decryptable using the wallet's internal OVK. After this change: - When using `OvkPolicy::Custom`, all external outputs are made decryptable with a single OVK, irrespective of pool. - Internal outputs are not made decryptable using an OVK, unless one is explicitly specified using the `internal_ovk` property of `OvkPolicy::Custom`. In all other cases, wallet-internal outputs will only be recoverable using the wallet's internal IVK. --- zcash_client_backend/CHANGELOG.md | 18 +++++++++++ zcash_client_backend/src/data_api/wallet.rs | 36 ++++++++------------- zcash_client_backend/src/wallet.rs | 24 +++++++------- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 1d6740cb53..26ff4e7d8a 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -10,6 +10,24 @@ workspace. ## [Unreleased] +### Changed +- `zcash_client_backend::wallet::OvkPolicy` has been substantially modified + to reflect the view that a single outgoing viewing key should be uniformly + applied to encrypt all external transaction outputs, irrespective of which + pool those outputs are produced into, and that by default wallet-internal + outputs should not be decryptable using an OVK (and will therefore only + be recoverable using the wallet's internal IVK). + - The semantics of `OvkPolicy::Sender` have changed. This policy now + specifies that wallet-internal change outputs should be encrypted + using a random key, rendering them unrecoverable to entities that + do not posess the internal IVK for the wallet. + - The `OvkPolicy::Custom` variant has changed. Instead of pool-specific + OVKs, this now encapsulates a pair of OVKs, one to be used for all + shielded external outputs of the transaction, and a second (optional) + key that will be used to encrypt any wallet-internal change outputs + that would otherwise only be recoverable using the wallet's internal + IVK. + ## [0.21.0] - 2025-11-05 ### Added diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index d26e876b31..0e6e1af226 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -64,7 +64,7 @@ use transparent::{address::TransparentAddress, builder::TransparentSigningSet, b use zcash_address::ZcashAddress; use zcash_keys::{ address::Address, - keys::{OutgoingViewingKey, UnifiedFullViewingKey, UnifiedSpendingKey}, + keys::{UnifiedFullViewingKey, UnifiedSpendingKey}, }; use zcash_primitives::transaction::{ Transaction, TxId, @@ -1278,28 +1278,20 @@ where utxos_spent }; - let external_ovk = match ovk_policy { - OvkPolicy::Sender => Some( - ufvk.select_ovk(zip32::Scope::External, &input_sources) - .ok_or(Error::KeyNotAvailable(input_sources.head))?, + let (external_ovk, internal_ovk) = match ovk_policy { + OvkPolicy::Sender => ( + Some( + ufvk.select_ovk(zip32::Scope::External, &input_sources) + .ok_or(Error::KeyNotAvailable(input_sources.head))?, + ), + None, ), OvkPolicy::Custom { - sapling, - #[cfg(feature = "orchard")] - orchard, - } => { - let mut ovk = Some(OutgoingViewingKey::from(sapling)); - #[cfg(feature = "orchard")] - if input_sources.contains(&PoolType::ORCHARD) { - ovk = Some(OutgoingViewingKey::from(orchard)); - } - ovk - } - OvkPolicy::Discard => None, + external_ovk, + internal_ovk, + } => (Some(external_ovk), internal_ovk), + OvkPolicy::Discard => (None, None), }; - let internal_ovk = ufvk - .select_ovk(zip32::Scope::Internal, &input_sources) - .ok_or(Error::KeyNotAvailable(input_sources.head))?; #[cfg(feature = "orchard")] let mut orchard_output_meta: Vec<(BuildRecipient<_>, Zatoshis, Option)> = vec![]; @@ -1441,7 +1433,7 @@ where match output_pool { PoolType::Shielded(ShieldedProtocol::Sapling) => { builder.add_sapling_output( - Some(internal_ovk.into()), + internal_ovk.map(|k| k.into()), ufvk.sapling() .ok_or(Error::KeyNotAvailable(PoolType::SAPLING))? .change_address() @@ -1465,7 +1457,7 @@ where #[cfg(feature = "orchard")] { builder.add_orchard_output( - Some(internal_ovk.into()), + internal_ovk.map(|k| k.into()), ufvk.orchard() .ok_or(Error::KeyNotAvailable(PoolType::ORCHARD))? .address_at(0u32, orchard::keys::Scope::Internal), diff --git a/zcash_client_backend/src/wallet.rs b/zcash_client_backend/src/wallet.rs index 9d5ef24867..2ce5999e65 100644 --- a/zcash_client_backend/src/wallet.rs +++ b/zcash_client_backend/src/wallet.rs @@ -9,6 +9,7 @@ use ::transparent::{ bundle::{OutPoint, TxOut}, }; use zcash_address::ZcashAddress; +use zcash_keys::keys::OutgoingViewingKey; use zcash_note_encryption::EphemeralKeyBytes; use zcash_primitives::transaction::{TxId, fees::transparent as transparent_fees}; use zcash_protocol::{ @@ -602,8 +603,9 @@ impl orchard_fees::InputView for ReceivedNote, }, /// Use no outgoing viewing keys. Transaction outputs will be decryptable by their /// recipients, but not by the sender. @@ -624,15 +625,16 @@ pub enum OvkPolicy { } impl OvkPolicy { - /// Constructs an [`OvkPolicy::Custom`] value from a single arbitrary 32-byte key. + /// Constructs an [`OvkPolicy::Custom`] value from a single arbitrary 32-byte key with both the + /// external_ovk and internal_ovk components set to the same key. /// - /// Outputs of transactions created with this OVK policy will be recoverable using - /// this key irrespective of the output pool. + /// Outputs of transactions created with this OVK policy will be recoverable using this key + /// irrespective of whether they are external outputs or wallet-internal change outputs. pub fn custom_from_common_bytes(key: &[u8; 32]) -> Self { + let k = OutgoingViewingKey::from(*key); OvkPolicy::Custom { - sapling: sapling::keys::OutgoingViewingKey(*key), - #[cfg(feature = "orchard")] - orchard: orchard::keys::OutgoingViewingKey::from(*key), + external_ovk: k, + internal_ovk: Some(k), } } } From 4e634914ccf86f955a63eb29105286cf19b3f923 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Fri, 28 Nov 2025 11:08:06 -0700 Subject: [PATCH 026/263] Address comments from code review. --- zcash_client_backend/CHANGELOG.md | 9 +++++---- zcash_client_backend/src/data_api/wallet.rs | 6 ++---- zcash_client_backend/src/wallet.rs | 4 +++- zcash_keys/Cargo.toml | 1 + zcash_keys/src/keys.rs | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 26ff4e7d8a..833a47eea9 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -17,10 +17,11 @@ workspace. pool those outputs are produced into, and that by default wallet-internal outputs should not be decryptable using an OVK (and will therefore only be recoverable using the wallet's internal IVK). - - The semantics of `OvkPolicy::Sender` have changed. This policy now - specifies that wallet-internal change outputs should be encrypted - using a random key, rendering them unrecoverable to entities that - do not posess the internal IVK for the wallet. + - The semantics of `OvkPolicy::Sender` have changed. In addition to using + a single OVK for all shielded outputs irrespective of pools, it now + specifies that wallet-internal change outputs should be treated as though + the policy for those outputs were `OvkPolicy::None`, rendering them only + recoverable using the wallet's internal IVK. - The `OvkPolicy::Custom` variant has changed. Instead of pool-specific OVKs, this now encapsulates a pair of OVKs, one to be used for all shielded external outputs of the transaction, and a second (optional) diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 0e6e1af226..66bf6a6245 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -1007,10 +1007,6 @@ where // We only support spending transparent payments or transparent ephemeral outputs from a // prior step (when "transparent-inputs" is enabled). - // - // TODO: Maybe support spending prior shielded outputs at some point? Doing so would require - // a higher-level approach in the wallet that waits for transactions with shielded outputs to - // be mined and only then attempts to perform the next step. #[allow(clippy::never_loop)] for input_ref in proposal_step.prior_step_inputs() { let (prior_step, _) = prior_step_results @@ -1150,6 +1146,8 @@ where if !orchard_inputs.is_empty() { sources.push(PoolType::ORCHARD); } + // We assume here that prior step outputs cannot be shielded, due to checks above (and the + // fact that the witness required to spend such outputs could not be computed.) #[cfg(feature = "transparent-inputs")] if !(proposal_step.transparent_inputs().is_empty() && proposal_step.prior_step_inputs().is_empty()) diff --git a/zcash_client_backend/src/wallet.rs b/zcash_client_backend/src/wallet.rs index 2ce5999e65..bd81cf54dd 100644 --- a/zcash_client_backend/src/wallet.rs +++ b/zcash_client_backend/src/wallet.rs @@ -601,13 +601,15 @@ impl orchard_fees::InputView for ReceivedNote k.external_ovk().as_bytes(), - Scope::Internal => k.internal_ovk().as_bytes(), + zip32::Scope::External => k.external_ovk().as_bytes(), + zip32::Scope::Internal => k.internal_ovk().as_bytes(), }) }) }) From 0e7c8d5c526703d940a7a606884d686754517d9c Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 2 Dec 2025 10:55:51 +0000 Subject: [PATCH 027/263] zcash_primitives: Clean up changelog --- zcash_primitives/CHANGELOG.md | 59 +++++++++++++++++------------------ 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/zcash_primitives/CHANGELOG.md b/zcash_primitives/CHANGELOG.md index d2e66e49c1..27a5345ec8 100644 --- a/zcash_primitives/CHANGELOG.md +++ b/zcash_primitives/CHANGELOG.md @@ -14,36 +14,35 @@ workspace. - MSRV is now 1.85.1. ### Removed - -- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_ALL`, use `zcash_transparent::sighash::SIGHASH_ALL` instead. -- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_NONE`, use `zcash_transparent::sighash::SIGHASH_NONE` instead. -- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_SINGLE`, use `zcash_transparent::sighash::SIGHASH_SINGLE` instead. -- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_MASK`, use `zcash_transparent::sighash::SIGHASH_MASK` instead. -- Removed deprecated `zcash_primitives::transaction::sighash::SIGHASH_ANYONECANPAY`, use `zcash_transparent::sighash::SIGHASH_ANYONECANPAY` instead. -- Removed deprecated `zcash_primitives::transaction::sighash::SighashType`, use `zcash_transparent::sighash::SighashType` instead. - -- Removed deprecated module `zcash_primitives::transaction::components::amount::testing`, - use `zcash_protocol::value::testing` instead with the following renames: - - `arb_positive_amount` to `zcash_protocol::value::testing::arb_positive_zat_balance` - - `arb_amount` to `zcash_protocol::value::testing::arb_zat_balance` - - `arb_nonnegative_amount` to `zcash_protocol::value::testing::arb_zatoshis`. -- Removed deprecated module `zcash_primitives::transaction::components::amount`, use `zcash_protocol::value` instead. -- Removed deprecated module `zcash_primitives::transaction::components::transparent::builder`, use `zcash_transparent::builder` instead. -- Removed deprecated module `zcash_primitives::transaction::components::transparent::pczt`, use `zcash_transparent::pczt` instead. -- Removed deprecated module `zcash_primitives::transaction::components::transparent`, use `zcash_transparent` instead. -- Removed deprecated `zcash_primitives::transaction::components::Outpoint`, use `zcash_transparent::bundle::Outpoint` instead. -- Removed deprecated `zcash_primitives::transaction::components::TxIn`, use `zcash_transparent::bundle::TxIn` instead. -- Removed deprecated `zcash_primitives::transaction::components::TxOut`, use `zcash_transparent::bundle::TxOut` instead. -- Removed deprecated `zcash_primitives::transaction::components::ZatBalance`, use `zcash_protocol::value::ZatBalance` instead. -- Removed deprecated `zcash_primitives::transaction::components::OutputDescription`, use `sapling_crypto::bundle::OutputDescription` instead. -- Removed deprecated `zcash_primitives::transaction::components::SpendDescription`, use `sapling_crypto::bundle::SpendDescription` instead. - -- Removed other deprecated modules: - - `zcash_primitives::consensus` - - `zcash_primitives::constants` - - `zcash_primitives::memo` - - `zcash_primitives::zip32` - - `zcash_primitives::legacy` +- `zcash_primitives::consensus` module (use `zcash_protocol::consensus` instead). +- `zcash_primitives::constants` module (use `zcash_protocol::constants` instead). +- `zcash_primitives::legacy` module (use the `zcash_transparent` crate instead). +- `zcash_primitives::memo` module (use `zcash_protocol::memo` instead) +- `zcash_primitives::transaction`: + - `components`: + - `amount::testing` module; use `zcash_protocol::value::testing` instead + with the following renames: + - `arb_positive_amount` to `zcash_protocol::value::testing::arb_positive_zat_balance` + - `arb_amount` to `zcash_protocol::value::testing::arb_zat_balance` + - `arb_nonnegative_amount` to `zcash_protocol::value::testing::arb_zatoshis`. + - `amount` module (use `zcash_protocol::value` instead). + - `transparent::builder` module (use `zcash_transparent::builder` instead). + - `transparent::pczt` module (use `zcash_transparent::pczt` instead). + - `transparent` module (use `zcash_transparent` instead). + - `Amount` (use `zcash_protocol::value::ZatBalance` instead). + - `Outpoint` (use `zcash_transparent::bundle::Outpoint` instead). + - `OutputDescription` (use `sapling_crypto::bundle::OutputDescription` instead). + - `SpendDescription` (use `sapling_crypto::bundle::SpendDescription` instead). + - `TxIn` (use `zcash_transparent::bundle::TxIn` instead). + - `TxOut` (use `zcash_transparent::bundle::TxOut` instead). + - `sighash`: + - `SIGHASH_ALL` (use `zcash_transparent::sighash::SIGHASH_ALL` instead). + - `SIGHASH_NONE` (use `zcash_transparent::sighash::SIGHASH_NONE` instead). + - `SIGHASH_SINGLE` (use `zcash_transparent::sighash::SIGHASH_SINGLE` instead). + - `SIGHASH_MASK` (use `zcash_transparent::sighash::SIGHASH_MASK` instead). + - `SIGHASH_ANYONECANPAY` (use `zcash_transparent::sighash::SIGHASH_ANYONECANPAY` instead). + - `SighashType` (use `zcash_transparent::sighash::SighashType` instead). +- `zcash_primitives::zip32` module (use the `zip32` crate instead). ## [0.26.1] - 2025-10-18 From 8d5fcc491d0e2c4bff62e7b6057ca7351f04aee4 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 20 Nov 2025 17:20:20 +0000 Subject: [PATCH 028/263] zcash_transparent: Support appending external sigs to PCZT inputs --- zcash_transparent/CHANGELOG.md | 10 +++ zcash_transparent/src/pczt/signer.rs | 112 +++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/zcash_transparent/CHANGELOG.md b/zcash_transparent/CHANGELOG.md index 3b93b867db..8c9c35cb91 100644 --- a/zcash_transparent/CHANGELOG.md +++ b/zcash_transparent/CHANGELOG.md @@ -10,8 +10,18 @@ workspace. ## [Unreleased] +### Added +- `zcash_transparent::pczt`: + - `Input::with_signable_input` + - `Input::append_signature` + ### Changed - MSRV is now 1.85.1. +- `zcash_transparent::pczt`: + - `SignerError` has added variants: + - `InvalidExternalSignature` + - `MissingPreimage` + - `UnsupportedPubkey` ## [0.6.1] - 2025-10-27 diff --git a/zcash_transparent/src/pczt/signer.rs b/zcash_transparent/src/pczt/signer.rs index 8213f8af52..d1dfa7e8a7 100644 --- a/zcash_transparent/src/pczt/signer.rs +++ b/zcash_transparent/src/pczt/signer.rs @@ -8,6 +8,26 @@ use crate::{ }; impl super::Input { + /// Helper to prepare a [`SignableInput`] for this input. + /// + /// This can be used to calculate the sighash for this input within its transaction, + /// to produce a signature externally suitable for passing to [`Self::append_signature`]. + pub fn with_signable_input(&self, index: usize, f: F) -> T + where + F: FnOnce(SignableInput) -> T, + { + // For P2PKH, `script_code` is always the same as `script_pubkey`. + let script_code = self.redeem_script.as_ref().unwrap_or(&self.script_pubkey); + + f(SignableInput { + hash_type: self.sighash_type, + index, + script_code: &Script::from(script_code), + script_pubkey: &Script::from(&self.script_pubkey), + value: self.value, + }) + } + /// Signs the transparent spend with the given spend authorizing key. /// /// It is the caller's responsibility to perform any semantic validity checks on the @@ -81,11 +101,103 @@ impl super::Input { Ok(()) } + + /// Appends the given signature to the transparent spend. + /// + /// It is the caller's responsibility to perform any semantic validity checks on the + /// PCZT (for example, comfirming that the change amounts are correct) before calling + /// this method. + /// + /// Returns an error if the signature does not match any pubkey involved with spend + /// control of the input's spent coin. The supported script formats are: + /// - P2PKH + /// - The [`Input::hash160_preimages`] field must contan a mapping from the `pubkeyhash` to + /// the pubkey. + /// - P2MS + /// - P2PK + /// + /// [`Input::hash160_preimages`]: super::Input::hash160_preimages + pub fn append_signature( + &mut self, + index: usize, + calculate_sighash: F, + sig: secp256k1::ecdsa::Signature, + secp: &secp256k1::Secp256k1, + ) -> Result<(), SignerError> + where + F: FnOnce(SignableInput) -> [u8; 32], + { + // For P2PKH, `script_code` is always the same as `script_pubkey`. + let script_code = self.redeem_script.as_ref().unwrap_or(&self.script_pubkey); + let script_kind = script_code + .refine() + .ok() + .as_ref() + .and_then(solver::standard); + + fn to_pubkey(data: &[u8]) -> Result<[u8; 33], SignerError> { + data.try_into().map_err(|_| SignerError::UnsupportedPubkey) + } + + // Extract all candidate pubkeys. + let pubkeys = match script_kind { + Some(solver::ScriptKind::PubKeyHash { hash }) => { + let data = self + .hash160_preimages() + .get(&hash) + .ok_or(SignerError::MissingPreimage)?; + to_pubkey(data).map(|pubkey| vec![pubkey]) + } + Some(solver::ScriptKind::MultiSig { pubkeys, .. }) => pubkeys + .iter() + .map(|data| to_pubkey(data.as_slice())) + .collect::, _>>(), + Some(solver::ScriptKind::PubKey { data }) => { + to_pubkey(data.as_slice()).map(|pubkey| vec![pubkey]) + } + // This spending key isn't involved with the input in any way we can detect. + _ => Err(SignerError::WrongSpendingKey), + }?; + + let sighash = calculate_sighash(SignableInput { + hash_type: self.sighash_type, + index, + script_code: &Script::from(script_code), + script_pubkey: &Script::from(&self.script_pubkey), + value: self.value, + }); + let msg = secp256k1::Message::from_digest(sighash); + + // Find the pubkey that the signature validates with. + for pubkey in pubkeys { + let pk = secp256k1::PublicKey::from_slice(&pubkey) + .map_err(|_| SignerError::UnsupportedPubkey)?; + + if secp.verify_ecdsa(&msg, &sig, &pk).is_ok() { + // Signature has to have the SighashType appended to it. + let mut sig_bytes: Vec = sig.serialize_der()[..].to_vec(); + sig_bytes.extend([self.sighash_type.encode()]); + + self.partial_signatures.insert(pubkey, sig_bytes); + + return Ok(()); + } + } + + Err(SignerError::InvalidExternalSignature) + } } /// Errors that can occur while signing a transparent input in a PCZT. #[derive(Debug)] pub enum SignerError { + /// A provided external signature was not valid for any detected pubkey involved with + /// spend control of the input's spent coin. + InvalidExternalSignature, + /// A required entry in one of the preimage maps is missing. + MissingPreimage, + /// A pubkey within the transparent input uses an unsupported format. + UnsupportedPubkey, /// The provided `sk` does not match any pubkey involved with spend control of the /// input's spent coin. WrongSpendingKey, From feefa606fd83a7b142c512cf77bf1758a68bc80d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 20 Nov 2025 17:21:21 +0000 Subject: [PATCH 029/263] pczt: Support appending external signatures to inputs --- Cargo.lock | 18 ++-- Cargo.toml | 4 +- pczt/CHANGELOG.md | 10 ++ pczt/src/roles/signer/mod.rs | 173 +++++++++++++++++++++++++----- supply-chain/audits.toml | 34 ++++-- supply-chain/imports.lock | 33 +++--- zcash_client_backend/CHANGELOG.md | 1 + zcash_client_sqlite/CHANGELOG.md | 3 + zcash_keys/CHANGELOG.md | 1 + zcash_primitives/CHANGELOG.md | 1 + zcash_proofs/CHANGELOG.md | 1 + 11 files changed, 216 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47ad11a241..d70b89aed1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1979,9 +1979,9 @@ dependencies = [ [[package]] name = "halo2_gadgets" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73a5e510d58a07d8ed238a5a8a436fe6c2c79e1bb2611f62688bc65007b4e6e7" +checksum = "45824ce0dd12e91ec0c68ebae2a7ed8ae19b70946624c849add59f1d1a62a143" dependencies = [ "arrayvec", "bitvec", @@ -2017,14 +2017,15 @@ dependencies = [ [[package]] name = "halo2_proofs" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b867a8d9bbb85fca76fff60652b5cd19b853a1c4d0665cb89bee68b18d2caf0" +checksum = "05713f117155643ce10975e0bee44a274bcda2f4bb5ef29a999ad67c1fa8d4d3" dependencies = [ "blake2b_simd", "ff", "group", "halo2_legacy_pdqsort", + "indexmap 1.9.3", "maybe-rayon", "pasta_curves", "rand_core 0.6.4", @@ -2927,9 +2928,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchard" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1ef66fcf99348242a20d582d7434da381a867df8dc155b3a980eca767c56137" +checksum = "6c01cd4ea711aab5f263f2b7aa6966687a2d6c7df4f78eb1b97a66a7a4e78e3b" dependencies = [ "aes", "bitvec", @@ -2950,6 +2951,7 @@ dependencies = [ "pasta_curves", "proptest", "rand 0.8.5", + "rand_core 0.6.4", "reddsa", "serde", "sinsemilla", @@ -4054,9 +4056,9 @@ dependencies = [ [[package]] name = "sapling-crypto" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d3c081c83f1dc87403d9d71a06f52301c0aa9ea4c17da2a3435bbf493ffba4" +checksum = "5433ab8c1cd52dfad3b903143e371d5bdd514ab7952f71414e6d66a5da8223cd" dependencies = [ "aes", "bellman", diff --git a/Cargo.toml b/Cargo.toml index 7fd4f9cfca..b5d1394abe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,10 +64,10 @@ blake2s_simd = { version = "1", default-features = false } bls12_381 = "0.8" jubjub = "0.10" redjubjub = { version = "0.8", default-features = false } -sapling = { package = "sapling-crypto", version = "0.5", default-features = false } +sapling = { package = "sapling-crypto", version = "0.6", default-features = false } # - Orchard -orchard = { version = "0.11", default-features = false } +orchard = { version = "0.12", default-features = false } pasta_curves = "0.5" # - Transparent diff --git a/pczt/CHANGELOG.md b/pczt/CHANGELOG.md index 6e225ef0cb..c86001c03d 100644 --- a/pczt/CHANGELOG.md +++ b/pczt/CHANGELOG.md @@ -10,6 +10,16 @@ workspace. ## [Unreleased] +### Added +- `pczt::roles::signer`: + - `Signer::sighash` + - `Signer::append_transparent_signature` + - `Signer::apply_sapling_signature` + - `Signer::apply_orchard_signature` + +### Changed +- Migrated to `orchard 0.12`, `sapling-crypto 0.6`. + ## [0.5.0] - 2025-11-05 ### Changed diff --git a/pczt/src/roles/signer/mod.rs b/pczt/src/roles/signer/mod.rs index 7fcd603ec3..3b01244358 100644 --- a/pczt/src/roles/signer/mod.rs +++ b/pczt/src/roles/signer/mod.rs @@ -14,6 +14,7 @@ //! - A source of randomness. use blake2b_simd::Hash as Blake2bHash; +use orchard::primitives::redpallas; use rand_core::OsRng; use ::transparent::sighash::{SIGHASH_ANYONECANPAY, SIGHASH_NONE, SIGHASH_SINGLE}; @@ -50,7 +51,7 @@ pub struct Signer { tx_data: TransactionData, txid_parts: TxDigests, shielded_sighash: [u8; 32], - secp: secp256k1::Secp256k1, + secp: secp256k1::Secp256k1, } impl Signer { @@ -78,10 +79,7 @@ impl Signer { version_group_id, })), }?; - let shielded_sighash = v5_signature_hash(&tx_data, &SignableInput::Shielded, &txid_parts) - .as_ref() - .try_into() - .expect("correct length"); + let shielded_sighash = sighash(&tx_data, &SignableInput::Shielded, &txid_parts); Ok(Self { global, @@ -91,7 +89,38 @@ impl Signer { tx_data, txid_parts, shielded_sighash, - secp: secp256k1::Secp256k1::signing_only(), + secp: secp256k1::Secp256k1::new(), + }) + } + + /// Calculates the signature digest that must be signed to authorize shielded spends. + /// + /// This can be used to produce a signature externally suitable for passing to e.g. + /// [`Self::apply_orchard_signature`].} + pub fn shielded_sighash(&self) -> [u8; 32] { + self.shielded_sighash + } + + /// Calculates the signature digest that must be signed to authorize the transparent + /// spend at the given index. + /// + /// This can be used to produce a signature externally suitable for passing to e.g. + /// [`Self::append_transparent_signature`].} + /// + /// Returns an error if `index` is invalid for this PCZT. + pub fn transparent_sighash(&self, index: usize) -> Result<[u8; 32], Error> { + let input = self + .transparent + .inputs() + .get(index) + .ok_or(Error::InvalidIndex)?; + + input.with_signable_input(index, |signable_input| { + Ok(sighash( + &self.tx_data, + &SignableInput::Transparent(signable_input), + &self.txid_parts, + )) }) } @@ -105,6 +134,49 @@ impl Signer { index: usize, sk: &secp256k1::SecretKey, ) -> Result<(), Error> { + self.generate_or_append_transparent_signature(index, |input, tx_data, txid_parts, secp| { + input.sign( + index, + |input| sighash(tx_data, &SignableInput::Transparent(input), txid_parts), + sk, + secp, + ) + }) + } + + /// Appends the given signature to the transparent spend. + /// + /// It is the caller's responsibility to perform any semantic validity checks on the + /// PCZT (for example, comfirming that the change amounts are correct) before calling + /// this method. + pub fn append_transparent_signature( + &mut self, + index: usize, + signature: secp256k1::ecdsa::Signature, + ) -> Result<(), Error> { + self.generate_or_append_transparent_signature(index, |input, tx_data, txid_parts, secp| { + input.append_signature( + index, + |input| sighash(tx_data, &SignableInput::Transparent(input), txid_parts), + signature, + secp, + ) + }) + } + + fn generate_or_append_transparent_signature( + &mut self, + index: usize, + f: F, + ) -> Result<(), Error> + where + F: FnOnce( + &mut transparent::pczt::Input, + &TransactionData, + &TxDigests, + &secp256k1::Secp256k1, + ) -> Result<(), transparent::pczt::SignerError>, + { let input = self .transparent .inputs_mut() @@ -114,23 +186,8 @@ impl Signer { // Check consistency of the input being signed. // TODO - input - .sign( - index, - |input| { - v5_signature_hash( - &self.tx_data, - &SignableInput::Transparent(input), - &self.txid_parts, - ) - .as_ref() - .try_into() - .unwrap() - }, - sk, - &self.secp, - ) - .map_err(Error::TransparentSign)?; + // Generate or apply the signature. + f(input, &self.tx_data, &self.txid_parts, &self.secp).map_err(Error::TransparentSign)?; // Update transaction modifiability: // - If the Signer added a signature that does not use `SIGHASH_ANYONECANPAY`, the @@ -170,6 +227,30 @@ impl Signer { index: usize, ask: &sapling::keys::SpendAuthorizingKey, ) -> Result<(), Error> { + self.generate_or_apply_sapling_signature(index, |spend, shielded_sighash| { + spend.sign(shielded_sighash, ask, OsRng) + }) + } + + /// Applies the given signature to the Sapling spend. + /// + /// It is the caller's responsibility to perform any semantic validity checks on the + /// PCZT (for example, comfirming that the change amounts are correct) before calling + /// this method. + pub fn apply_sapling_signature( + &mut self, + index: usize, + signature: redjubjub::Signature, + ) -> Result<(), Error> { + self.generate_or_apply_sapling_signature(index, |spend, shielded_sighash| { + spend.apply_signature(shielded_sighash, signature) + }) + } + + fn generate_or_apply_sapling_signature(&mut self, index: usize, f: F) -> Result<(), Error> + where + F: FnOnce(&mut sapling::pczt::Spend, [u8; 32]) -> Result<(), sapling::pczt::SignerError>, + { let spend = self .sapling .spends_mut() @@ -187,9 +268,8 @@ impl Signer { } .map_err(Error::SaplingVerify)?; - spend - .sign(self.shielded_sighash, ask, OsRng) - .map_err(Error::SaplingSign)?; + // Generate or apply the signature. + f(spend, self.shielded_sighash).map_err(Error::SaplingSign)?; // Update transaction modifiability: all transaction effects have been committed // to by the signature. @@ -212,6 +292,30 @@ impl Signer { index: usize, ask: &orchard::keys::SpendAuthorizingKey, ) -> Result<(), Error> { + self.generate_or_apply_orchard_signature(index, |spend, shielded_sighash| { + spend.sign(shielded_sighash, ask, OsRng) + }) + } + + /// Applies the given signature to the Orchard spend. + /// + /// It is the caller's responsibility to perform any semantic validity checks on the + /// PCZT (for example, comfirming that the change amounts are correct) before calling + /// this method. + pub fn apply_orchard_signature( + &mut self, + index: usize, + signature: redpallas::Signature, + ) -> Result<(), Error> { + self.generate_or_apply_orchard_signature(index, |action, shielded_sighash| { + action.apply_signature(shielded_sighash, signature) + }) + } + + fn generate_or_apply_orchard_signature(&mut self, index: usize, f: F) -> Result<(), Error> + where + F: FnOnce(&mut orchard::pczt::Action, [u8; 32]) -> Result<(), orchard::pczt::SignerError>, + { let action = self .orchard .actions_mut() @@ -230,9 +334,8 @@ impl Signer { } .map_err(Error::OrchardVerify)?; - action - .sign(self.shielded_sighash, ask, OsRng) - .map_err(Error::OrchardSign)?; + // Generate or apply the signature. + f(action, self.shielded_sighash).map_err(Error::OrchardSign)?; // Update transaction modifiability: all transaction effects have been committed // to by the signature. @@ -310,6 +413,18 @@ impl Authorization for EffectsOnly { type TzeAuth = core::convert::Infallible; } +/// Helper to produce the correct sighash for a PCZT. +fn sighash( + tx_data: &TransactionData, + signable_input: &SignableInput, + txid_parts: &TxDigests, +) -> [u8; 32] { + v5_signature_hash(tx_data, signable_input, txid_parts) + .as_ref() + .try_into() + .expect("correct length") +} + /// Errors that can occur while creating signatures for a PCZT. #[derive(Debug)] pub enum Error { diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 9eadebec94..192b0a61fa 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1846,7 +1846,7 @@ end = "2025-12-16" [[trusted.halo2_gadgets]] criteria = ["safe-to-deploy", "crypto-reviewed"] -user-id = 1244 # ebfull +user-id = 1244 start = "2022-05-10" end = "2025-04-22" @@ -1862,15 +1862,21 @@ user-id = 6289 # Jack Grigg (str4d) start = "2024-12-13" end = "2025-12-16" +[[trusted.halo2_proofs]] +criteria = "safe-to-deploy" +user-id = 6289 # Jack Grigg (str4d) +start = "2022-01-20" +end = "2026-12-05" + [[trusted.halo2_proofs]] criteria = ["safe-to-deploy", "crypto-reviewed"] -user-id = 1244 # ebfull +user-id = 1244 start = "2022-05-10" end = "2025-04-22" [[trusted.incrementalmerkletree]] criteria = "safe-to-deploy" -user-id = 1244 # ebfull +user-id = 1244 start = "2021-06-24" end = "2025-04-22" @@ -1898,6 +1904,12 @@ user-id = 6289 # Jack Grigg (str4d) start = "2021-09-03" end = "2025-12-16" +[[trusted.orchard]] +criteria = "safe-to-deploy" +user-id = 6289 # Jack Grigg (str4d) +start = "2021-01-07" +end = "2026-12-05" + [[trusted.orchard]] criteria = "safe-to-deploy" user-id = 169181 # Kris Nuttycombe (nuttycom) @@ -1906,7 +1918,7 @@ end = "2025-08-12" [[trusted.orchard]] criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"] -user-id = 1244 # ebfull +user-id = 1244 start = "2022-10-19" end = "2025-04-22" @@ -1940,6 +1952,12 @@ user-id = 199950 # Daira-Emma Hopwood (daira) start = "2023-03-30" end = "2026-02-21" +[[trusted.sapling-crypto]] +criteria = "safe-to-deploy" +user-id = 6289 # Jack Grigg (str4d) +start = "2024-01-26" +end = "2026-12-05" + [[trusted.sapling-crypto]] criteria = "safe-to-deploy" user-id = 169181 # Kris Nuttycombe (nuttycom) @@ -2110,7 +2128,7 @@ end = "2025-07-19" [[trusted.zcash_address]] criteria = "safe-to-deploy" -user-id = 1244 # ebfull +user-id = 1244 start = "2022-10-19" end = "2025-04-22" @@ -2152,7 +2170,7 @@ end = "2026-06-02" [[trusted.zcash_encoding]] criteria = "safe-to-deploy" -user-id = 1244 # ebfull +user-id = 1244 start = "2022-10-19" end = "2025-04-22" @@ -2176,7 +2194,7 @@ end = "2025-04-23" [[trusted.zcash_history]] criteria = "safe-to-deploy" -user-id = 1244 # ebfull +user-id = 1244 start = "2020-03-04" end = "2025-04-22" @@ -2218,7 +2236,7 @@ end = "2026-10-24" [[trusted.zcash_primitives]] criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"] -user-id = 1244 # ebfull +user-id = 1244 start = "2019-10-08" end = "2025-04-22" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 0dccba6ae0..113bbe05ff 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -30,8 +30,8 @@ user-login = "str4d" user-name = "Jack Grigg" [[publisher.halo2_gadgets]] -version = "0.3.1" -when = "2024-12-16" +version = "0.4.0" +when = "2025-12-04" user-id = 6289 user-login = "str4d" user-name = "Jack Grigg" @@ -51,10 +51,11 @@ user-login = "str4d" user-name = "Jack Grigg" [[publisher.halo2_proofs]] -version = "0.3.0" -when = "2023-03-22" -user-id = 1244 -user-login = "ebfull" +version = "0.3.2" +when = "2025-12-04" +user-id = 6289 +user-login = "str4d" +user-name = "Jack Grigg" [[publisher.incrementalmerkletree]] version = "0.8.2" @@ -78,11 +79,11 @@ user-login = "str4d" user-name = "Jack Grigg" [[publisher.orchard]] -version = "0.11.0" -when = "2025-02-21" -user-id = 169181 -user-login = "nuttycom" -user-name = "Kris Nuttycombe" +version = "0.12.0" +when = "2025-12-05" +user-id = 6289 +user-login = "str4d" +user-name = "Jack Grigg" [[publisher.pczt]] version = "0.5.0" @@ -92,11 +93,11 @@ user-login = "nuttycom" user-name = "Kris Nuttycombe" [[publisher.sapling-crypto]] -version = "0.5.0" -when = "2025-02-21" -user-id = 169181 -user-login = "nuttycom" -user-name = "Kris Nuttycombe" +version = "0.6.0" +when = "2025-12-05" +user-id = 6289 +user-login = "str4d" +user-name = "Jack Grigg" [[publisher.schemerz]] version = "0.2.0" diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 833a47eea9..ef7d292e62 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -11,6 +11,7 @@ workspace. ## [Unreleased] ### Changed +- Migrated to `orchard 0.12`, `sapling-crypto 0.6`. - `zcash_client_backend::wallet::OvkPolicy` has been substantially modified to reflect the view that a single outgoing viewing key should be uniformly applied to encrypt all external transaction outputs, irrespective of which diff --git a/zcash_client_sqlite/CHANGELOG.md b/zcash_client_sqlite/CHANGELOG.md index 817bbf3e5b..490075735e 100644 --- a/zcash_client_sqlite/CHANGELOG.md +++ b/zcash_client_sqlite/CHANGELOG.md @@ -10,6 +10,9 @@ workspace. ## [Unreleased] +### Changed +- Migrated to `orchard 0.12`, `sapling-crypto 0.6`. + ## [0.18.10, 0.19.1] - 2025-11-25 ### Fixed diff --git a/zcash_keys/CHANGELOG.md b/zcash_keys/CHANGELOG.md index 6f6c9a2c00..43e556bf01 100644 --- a/zcash_keys/CHANGELOG.md +++ b/zcash_keys/CHANGELOG.md @@ -15,6 +15,7 @@ workspace. ### Changed - MSRV is now 1.85.1. +- Migrated to `orchard 0.12`, `sapling-crypto 0.6`. ## [0.12.0] - 2025-10-13 diff --git a/zcash_primitives/CHANGELOG.md b/zcash_primitives/CHANGELOG.md index 27a5345ec8..9b4b7c08a2 100644 --- a/zcash_primitives/CHANGELOG.md +++ b/zcash_primitives/CHANGELOG.md @@ -12,6 +12,7 @@ workspace. ### Changed - MSRV is now 1.85.1. +- Migrated to `orchard 0.12`, `sapling-crypto 0.6`. ### Removed - `zcash_primitives::consensus` module (use `zcash_protocol::consensus` instead). diff --git a/zcash_proofs/CHANGELOG.md b/zcash_proofs/CHANGELOG.md index d01cf1a297..e6dc6bebe4 100644 --- a/zcash_proofs/CHANGELOG.md +++ b/zcash_proofs/CHANGELOG.md @@ -12,6 +12,7 @@ workspace. ### Changed - MSRV is now 1.85.1. +- Migrated to `sapling-crypto 0.6`. ## [0.26.1] - 2025-10-18 From 0f343cce38720283d369096162282afc2c30a171 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 3 Dec 2025 17:19:27 -0700 Subject: [PATCH 030/263] zcash_client_sqlite: Add columns to `v_tx_outputs` This adds the following columns to the `v_tx_outputs` view: * transaction_id - the database-internal transaction identifier, which is needed to make efficient joins between `v_tx_outputs` and other tables * mined_height - the block height at which the transaction that produceed the output was mined, if any; this is useful for computing the confirmation depth for a given received output. * recipient_key_scope - the key scope that received the output, which is needed in order to compute the number of confirmations required before the output may be spent. --- zcash_client_sqlite/CHANGELOG.md | 6 + zcash_client_sqlite/src/wallet/db.rs | 48 +++-- zcash_client_sqlite/src/wallet/encoding.rs | 11 ++ .../src/wallet/init/migrations.rs | 4 +- .../migrations/v_tx_outputs_key_scopes.rs | 164 ++++++++++++++++++ 5 files changed, 219 insertions(+), 14 deletions(-) create mode 100644 zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs diff --git a/zcash_client_sqlite/CHANGELOG.md b/zcash_client_sqlite/CHANGELOG.md index 490075735e..84c2eb256a 100644 --- a/zcash_client_sqlite/CHANGELOG.md +++ b/zcash_client_sqlite/CHANGELOG.md @@ -10,6 +10,12 @@ workspace. ## [Unreleased] +### Added +- The following columns have been added to the exposed `v_tx_outputs` view: + - `transaction_id` + - `mined_height` + - `recipient_key_scope` + ### Changed - Migrated to `orchard 0.12`, `sapling-crypto 0.6`. diff --git a/zcash_client_sqlite/src/wallet/db.rs b/zcash_client_sqlite/src/wallet/db.rs index 998d92b8b0..148ca54e16 100644 --- a/zcash_client_sqlite/src/wallet/db.rs +++ b/zcash_client_sqlite/src/wallet/db.rs @@ -1081,7 +1081,12 @@ GROUP BY notes.account_id, notes.transaction_id"; /// and as change. /// /// # Columns -/// - `txid`: The id of the transaction in which the output was sent or received. +/// - `transaction_id`: The database-internal identifier for the transaction that produced this +/// output. This is intended for use when it is necessary to perform efficient joins against +/// other tables and views. It should not ever be exposed to end-users. +/// - `txid`: The byte representation of the consensus transaction ID for the transaction that +/// produced thid outout. This byte vector must be reversed and hex-encoded for display to +/// users. /// - `output_pool`: The value pool for the transaction; valid values for this are: /// - 0: Transparent /// - 2: Sapling @@ -1089,6 +1094,11 @@ GROUP BY notes.account_id, notes.transaction_id"; /// - `output_index`: The index of the output within the transaction bundle associated with /// the `output_pool` value; that is, within `vout` for transparent, the vector of /// Sapling `OutputDescription` values, or the vector of Orchard actions. +/// - `tx_mined_height`: An optional value identifying the block height at which the transaction that +/// produced this output was mined, or NULL if the transaction is unmined. +/// - `tx_trust_status`: A flag indicating whether the transaction that produced these outputs +/// should be considered "trusted". When set to `1`, outputs of this transaction will be considered +/// spendable with `trusted` confirmations instead of `untrusted` confirmations. /// - `from_account_uuid`: The UUID of the wallet account that created the output, if the wallet /// spent notes in creating the transaction. Note that if multiple accounts in the wallet /// contributed funds in creating the associated transaction, redundant rows will exist in the @@ -1110,11 +1120,16 @@ GROUP BY notes.account_id, notes.transaction_id"; /// - `memo`: The binary content of the memo associated with the output, if the output is a /// shielded output and the memo was received by the wallet, sent by the wallet or was able to be /// decrypted with the wallet's outgoing viewing key. +/// - `recipient_key_scope`: the ZIP 32 key scope of the key that received or decrypted this +/// output, encoded as `0` for external scope, `1` for internal scope, and `2` for ephemeral +/// scope. pub(super) const VIEW_TX_OUTPUTS: &str = " CREATE VIEW v_tx_outputs AS WITH unioned AS ( -- select all outputs received by the wallet - SELECT transactions.txid AS txid, + SELECT transactions.id_tx AS transaction_id, + transactions.txid AS txid, + transactions.mined_height AS mined_height, ro.pool AS output_pool, ro.output_index AS output_index, from_account.uuid AS from_account_uuid, @@ -1123,7 +1138,8 @@ WITH unioned AS ( a.diversifier_index_be AS diversifier_index_be, ro.value AS value, ro.is_change AS is_change, - ro.memo AS memo + ro.memo AS memo, + a.key_scope AS recipient_key_scope FROM v_received_outputs ro JOIN transactions ON transactions.id_tx = ro.transaction_id @@ -1135,7 +1151,9 @@ WITH unioned AS ( LEFT JOIN accounts to_account ON to_account.id = ro.account_id UNION ALL -- select all outputs sent from the wallet to external recipients - SELECT transactions.txid AS txid, + SELECT transactions.id_tx AS transaction_id, + transactions.txid AS txid, + transactions.mined_height AS mined_height, sent_notes.output_pool AS output_pool, sent_notes.output_index AS output_index, from_account.uuid AS from_account_uuid, @@ -1144,7 +1162,8 @@ WITH unioned AS ( NULL AS diversifier_index_be, sent_notes.value AS value, 0 AS is_change, - sent_notes.memo AS memo + sent_notes.memo AS memo, + NULL AS recipient_key_scope FROM sent_notes JOIN transactions ON transactions.id_tx = sent_notes.transaction_id @@ -1154,17 +1173,20 @@ WITH unioned AS ( ) -- merge duplicate rows while retaining maximum information SELECT - txid, + transaction_id, + MAX(txid), + MAX(mined_height) AS mined_height, output_pool, output_index, - max(from_account_uuid) AS from_account_uuid, - max(to_account_uuid) AS to_account_uuid, - max(to_address) AS to_address, - max(value) AS value, - max(is_change) AS is_change, - max(memo) AS memo + MAX(from_account_uuid) AS from_account_uuid, + MAX(to_account_uuid) AS to_account_uuid, + MAX(to_address) AS to_address, + MAX(value) AS value, + MAX(is_change) AS is_change, + MAX(memo) AS memo, + MAX(recipient_key_scope) AS recipient_key_scope FROM unioned -GROUP BY txid, output_pool, output_index"; +GROUP BY transaction_id, output_pool, output_index"; pub(super) fn view_sapling_shard_scan_ranges(params: &P) -> String { format!( diff --git a/zcash_client_sqlite/src/wallet/encoding.rs b/zcash_client_sqlite/src/wallet/encoding.rs index f83bb0fd8d..f45e8502dc 100644 --- a/zcash_client_sqlite/src/wallet/encoding.rs +++ b/zcash_client_sqlite/src/wallet/encoding.rs @@ -42,6 +42,17 @@ pub(crate) fn pool_code(pool_type: PoolType) -> i64 { } } +pub(crate) fn parse_pool_code(code: i64) -> Result { + match code { + 0i64 => Ok(PoolType::Transparent), + 2i64 => Ok(PoolType::SAPLING), + 3i64 => Ok(PoolType::ORCHARD), + _ => Err(SqliteClientError::CorruptedData(format!( + "Invalid pool code: {code}" + ))), + } +} + pub(crate) fn account_kind_code(value: &AccountSource) -> u32 { match value { AccountSource::Derived { .. } => 0, diff --git a/zcash_client_sqlite/src/wallet/init/migrations.rs b/zcash_client_sqlite/src/wallet/init/migrations.rs index c63ee2075d..a643107243 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations.rs @@ -48,6 +48,7 @@ mod v_transactions_net; mod v_transactions_note_uniqueness; mod v_transactions_shielding_balance; mod v_transactions_transparent_history; +mod v_tx_outputs_key_scopes; mod v_tx_outputs_return_addrs; mod v_tx_outputs_use_legacy_false; mod wallet_summaries; @@ -215,6 +216,7 @@ pub(super) fn all_migrations< Box::new(v_received_output_spends_account::Migration), Box::new(add_transaction_trust_marker::Migration), Box::new(account_delete_cascade::Migration), + Box::new(v_tx_outputs_key_scopes::Migration), ] } @@ -355,7 +357,7 @@ pub const V_0_18_5: &[Uuid] = &[ pub const V_0_19_0: &[Uuid] = &[account_delete_cascade::MIGRATION_ID]; /// Leaf migrations as of the current repository state. -pub const CURRENT_LEAF_MIGRATIONS: &[Uuid] = &[account_delete_cascade::MIGRATION_ID]; +pub const CURRENT_LEAF_MIGRATIONS: &[Uuid] = &[v_tx_outputs_key_scopes::MIGRATION_ID]; pub(super) fn verify_network_compatibility( conn: &rusqlite::Connection, diff --git a/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs b/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs new file mode 100644 index 0000000000..03b103f048 --- /dev/null +++ b/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs @@ -0,0 +1,164 @@ +//! This migration adds missing key scope information to the `v_received_outputs` and +//! `v_tx_outputs` views. +use std::collections::HashSet; + +use schemerz_rusqlite::RusqliteMigration; +use uuid::Uuid; + +use crate::wallet::init::{WalletMigrationError, migrations::account_delete_cascade}; + +pub(super) const MIGRATION_ID: Uuid = Uuid::from_u128(0x97ac36a9_196f_4dd9_993d_722bde95bebc); + +const DEPENDENCIES: &[Uuid] = &[account_delete_cascade::MIGRATION_ID]; + +pub(super) struct Migration; + +impl schemerz::Migration for Migration { + fn id(&self) -> Uuid { + MIGRATION_ID + } + + fn dependencies(&self) -> HashSet { + DEPENDENCIES.iter().copied().collect() + } + + fn description(&self) -> &'static str { + "Adds `ON DELETE CASCADE` to foreign keys to support account deletion." + } +} + +impl RusqliteMigration for Migration { + type Error = WalletMigrationError; + + fn up(&self, conn: &rusqlite::Transaction) -> Result<(), Self::Error> { + conn.execute_batch( + r#" + DROP VIEW v_tx_outputs; + CREATE VIEW v_tx_outputs AS + WITH unioned AS ( + -- select all outputs received by the wallet + SELECT transactions.id_tx AS transaction_id, + transactions.txid AS txid, + transactions.mined_height AS mined_height, + ro.pool AS output_pool, + ro.output_index AS output_index, + from_account.uuid AS from_account_uuid, + to_account.uuid AS to_account_uuid, + a.address AS to_address, + a.diversifier_index_be AS diversifier_index_be, + ro.value AS value, + ro.is_change AS is_change, + ro.memo AS memo, + a.key_scope AS recipient_key_scope + FROM v_received_outputs ro + JOIN transactions + ON transactions.id_tx = ro.transaction_id + LEFT JOIN addresses a ON a.id = ro.address_id + -- join to the sent_notes table to obtain `from_account_id` + LEFT JOIN sent_notes ON sent_notes.id = ro.sent_note_id + -- join on the accounts table to obtain account UUIDs + LEFT JOIN accounts from_account ON from_account.id = sent_notes.from_account_id + LEFT JOIN accounts to_account ON to_account.id = ro.account_id + UNION ALL + -- select all outputs sent from the wallet to external recipients + SELECT transactions.id_tx AS transaction_id, + transactions.txid AS txid, + transactions.mined_height AS mined_height, + sent_notes.output_pool AS output_pool, + sent_notes.output_index AS output_index, + from_account.uuid AS from_account_uuid, + NULL AS to_account_uuid, + sent_notes.to_address AS to_address, + NULL AS diversifier_index_be, + sent_notes.value AS value, + 0 AS is_change, + sent_notes.memo AS memo, + NULL AS recipient_key_scope + FROM sent_notes + JOIN transactions + ON transactions.id_tx = sent_notes.transaction_id + LEFT JOIN v_received_outputs ro ON ro.sent_note_id = sent_notes.id + -- join on the accounts table to obtain account UUIDs + LEFT JOIN accounts from_account ON from_account.id = sent_notes.from_account_id + ) + -- merge duplicate rows while retaining maximum information + SELECT + transaction_id, + MAX(txid), + MAX(mined_height) AS mined_height, + output_pool, + output_index, + MAX(from_account_uuid) AS from_account_uuid, + MAX(to_account_uuid) AS to_account_uuid, + MAX(to_address) AS to_address, + MAX(value) AS value, + MAX(is_change) AS is_change, + MAX(memo) AS memo, + MAX(recipient_key_scope) AS recipient_key_scope + FROM unioned + GROUP BY transaction_id, output_pool, output_index; + "#, + )?; + + Ok(()) + } + + fn down(&self, _transaction: &rusqlite::Transaction) -> Result<(), Self::Error> { + Err(WalletMigrationError::CannotRevert(MIGRATION_ID)) + } +} + +#[cfg(test)] +mod tests { + use zcash_client_backend::data_api::testing::{pool::dsl::TestDsl, sapling::SaplingPoolTester}; + use zcash_protocol::{PoolType, value::Zatoshis}; + + use crate::{ + error::SqliteClientError, + testing::{BlockCache, db::TestDbFactory}, + wallet::{KeyScope, encoding::parse_pool_code, init::migrations::tests::test_migrate}, + }; + + #[test] + fn migrate() { + test_migrate(&[super::MIGRATION_ID]); + } + + #[test] + fn v_tx_outputs_validity() { + let dsf = TestDbFactory::default(); + let cache = BlockCache::new(); + let mut st = + TestDsl::with_sapling_birthday_account(dsf, cache).build::(); + + // Add funds to the wallet in a single note + let (h, _, _) = st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(60000)); + + let mut stmt = st.wallet().conn().prepare( + "SELECT transaction_id, output_pool, output_index, value, recipient_key_scope FROM v_tx_outputs" + ).unwrap(); + + let results = stmt + .query_and_then::<_, SqliteClientError, _, _>([], |row| { + let txid = row.get::<_, i64>("transaction_id")?; + let pool = parse_pool_code(row.get("output_pool")?)?; + let output_index = row.get::<_, u32>("output_index")?; + let value = row.get::<_, u32>("value")?; + let recipient_key_scope = row + .get::<_, Option>("recipient_key_scope")? + .map(KeyScope::decode) + .transpose()?; + + Ok((txid, pool, output_index, value, recipient_key_scope)) + }) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(results.len(), 1); + let (_, pool, _, value, recipient_key_scope) = results[0]; + assert_eq!(pool, PoolType::SAPLING); + assert_eq!(value, 60000); + assert_eq!(recipient_key_scope, Some(KeyScope::EXTERNAL)); + } +} From 8dfd88ced662561ccbda0ada786bd7c9223e34c4 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Fri, 5 Dec 2025 10:03:12 -0700 Subject: [PATCH 031/263] zcash_client_backend: Add `ConfirmationsPolicy::confirmations_until_spendable` --- zcash_client_backend/CHANGELOG.md | 3 + zcash_client_backend/src/data_api/wallet.rs | 84 +++++++++++++++ zcash_client_sqlite/src/wallet.rs | 31 +++--- zcash_client_sqlite/src/wallet/common.rs | 102 +++++++----------- .../migrations/v_tx_outputs_key_scopes.rs | 2 +- 5 files changed, 146 insertions(+), 76 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index ef7d292e62..867669a5ec 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -10,6 +10,9 @@ workspace. ## [Unreleased] +### Added +- `zcash_client_backend::data_api::wallet::ConfirmationsPolicy::confirmations_until_spendable` + ### Changed - Migrated to `orchard 0.12`, `sapling-crypto 0.6`. - `zcash_client_backend::wallet::OvkPolicy` has been substantially modified diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 66bf6a6245..9c6adfe76c 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -512,6 +512,90 @@ impl ConfirmationsPolicy { pub fn allow_zero_conf_shielding(&self) -> bool { self.allow_zero_conf_shielding } + + /// Returns the number of confirmations until a transaction output is considered spendable, + /// given information about the output and the inputs to the transaction that produced it. + /// + /// # Parameters + /// - `target_height`: The minimum height at which the output will be potentially spent. + /// - `pool_type`: The Zcash pool that the output was received into. + /// - `receiving_key_scope`: The ZIP 32 [`Scope`] of the key that received the output, + /// or `None` if the scope is unknown or corresponds to the ephemeral transparent + /// key scope. + /// - `mined_height`: The block height at which the transaction that produced the output was + /// mined, if any. + /// - `tx_trusted`: A boolean flag indicating whether the received transaction has been + /// explicitly marked as trusted by the user. + /// - `max_shielding_input_height`: For outputs that are the result of wallet-internal + /// shielding transactions, the maximum height at which any transparent input to that + /// transaction was received. + /// - `tx_shielding_inputs_trusted`: For outputs that are the result of wallet-internal + /// shielding transactions, a flag indicating whether all transparent inputs to that + /// transaction have been explicitly marked as trusted by the user. + #[allow(clippy::too_many_arguments)] + pub fn confirmations_until_spendable( + &self, + target_height: TargetHeight, + pool_type: PoolType, + receiving_key_scope: Option, + mined_height: Option, + tx_trusted: bool, + max_shielding_input_height: Option, + tx_shielding_inputs_trusted: bool, + ) -> u32 { + // Trusted outputs of transactions mined at heights greater than `trusted_height` will not + // be treated as spendable. + let trusted_height = target_height.saturating_sub(u32::from(self.trusted)); + // Untrusted outputs of transactions mined at heights greater than `untrusted_height` will + // not be treated as spendable. + let untrusted_height = target_height.saturating_sub(u32::from(self.untrusted)); + + // Calculate the possible options for confirmations. + // - If the output's tx is unmined, we are constantly waiting for the maximum number of + // confirmations. + // - If the output's tx is mined, the required number of confirmations decreases to a floor + // of zero. + let confs_for_trusted = + mined_height.map_or(u32::from(self.trusted), |h| h - trusted_height); + let confs_for_untrusted = + mined_height.map_or(u32::from(self.untrusted), |h| h - untrusted_height); + match pool_type { + PoolType::Transparent => { + #[cfg(feature = "transparent-inputs")] + let zc_shielding = self.allow_zero_conf_shielding; + #[cfg(not(feature = "transparent-inputs"))] + let zc_shielding = false; + + if zc_shielding { + 0 + } else if tx_trusted || receiving_key_scope == Some(Scope::Internal) { + confs_for_trusted + } else { + confs_for_untrusted + } + } + PoolType::Shielded(_) => { + if tx_trusted { + confs_for_trusted + } else if receiving_key_scope == Some(Scope::Internal) { + // If the note was the output of a shielding transaction, we use the mined + // height of the transparent source funds & their trust status instead of the + // height at which the shielding transaction was mined. + if let Some(h) = max_shielding_input_height { + if tx_shielding_inputs_trusted { + h - trusted_height + } else { + h - untrusted_height + } + } else { + confs_for_trusted + } + } else { + confs_for_untrusted + } + } + } + } } /// Select transaction inputs, compute fees, and construct a proposal for a transaction or series diff --git a/zcash_client_sqlite/src/wallet.rs b/zcash_client_sqlite/src/wallet.rs index e43a402b8f..ab77769a5c 100644 --- a/zcash_client_sqlite/src/wallet.rs +++ b/zcash_client_sqlite/src/wallet.rs @@ -2144,8 +2144,6 @@ pub(crate) fn get_wallet_summary( let trusted_height = target_height.saturating_sub(u32::from(confirmations_policy.trusted())); - let untrusted_height = - target_height.saturating_sub(u32::from(confirmations_policy.untrusted())); let any_spendable = anchor_height.map_or(Ok(false), |h| is_any_spendable(tx, h, table_prefix))?; @@ -2153,8 +2151,10 @@ pub(crate) fn get_wallet_summary( let mut stmt_select_notes = tx.prepare_cached(&format!( "SELECT accounts.uuid, rn.id, rn.value, rn.is_change, rn.recipient_key_scope, scan_state.max_priority, - t.mined_height AS mined_height, - MAX(tt.mined_height) AS max_shielding_input_height + t.mined_height, + IFNULL(t.trust_status, 0) AS trust_status, + MAX(tt.mined_height) AS max_shielding_input_height, + MIN(IFNULL(tt.trust_status, 0)) AS min_shielding_input_trust FROM {table_prefix}_received_notes rn INNER JOIN accounts ON accounts.id = rn.account_id INNER JOIN transactions t ON t.id_tx = rn.transaction_id @@ -2213,25 +2213,28 @@ pub(crate) fn get_wallet_summary( .get::<_, Option>("mined_height")? .map(BlockHeight::from); + let tx_trusted = row.get::<_, bool>("trust_status")?; + let max_shielding_input_height = row .get::<_, Option>("max_shielding_input_height")? .map(BlockHeight::from); + let tx_shielding_inputs_trusted = row.get::<_, bool>("min_shielding_input_trust")?; + // A note is spendable if we have enough chain tip information to construct witnesses, // the shard that its witness resides in is sufficiently scanned that we can construct // the witness for the note, and the note has enough confirmations to be spent. let is_spendable = any_spendable && max_priority <= ScanPriority::Scanned - && match recipient_key_scope { - Some(KeyScope::INTERNAL) => { - // The note was has at least `trusted` confirmations. - received_height.iter().any(|h| h <= &trusted_height) && - // And, if the note was the output of a shielding transaction, its - // transparent inputs have at least `untrusted` confirmations. - max_shielding_input_height.iter().all(|h| h <= &untrusted_height) - } - _ => received_height.iter().any(|h| h <= &untrusted_height), - }; + && confirmations_policy.confirmations_until_spendable( + target_height, + PoolType::Shielded(protocol), + recipient_key_scope.and_then(|k| zip32::Scope::try_from(k).ok()), + received_height, + tx_trusted, + max_shielding_input_height, + tx_shielding_inputs_trusted, + ) == 0; let is_pending_change = is_change && received_height.iter().all(|h| h > &trusted_height); diff --git a/zcash_client_sqlite/src/wallet/common.rs b/zcash_client_sqlite/src/wallet/common.rs index 757413a362..25f7193ebf 100644 --- a/zcash_client_sqlite/src/wallet/common.rs +++ b/zcash_client_sqlite/src/wallet/common.rs @@ -3,7 +3,6 @@ use incrementalmerkletree::Position; use rusqlite::{Connection, Row, named_params, types::Value}; use std::{num::NonZeroU64, rc::Rc}; -use zip32::Scope; use zcash_client_backend::{ data_api::{ @@ -456,13 +455,9 @@ where }, )?; - let trusted_height = target_height.saturating_sub(u32::from(confirmations_policy.trusted())); - let untrusted_height = - target_height.saturating_sub(u32::from(confirmations_policy.untrusted())); - row_results .map(|t| match t? { - (Some(note), max_shard_priority, trusted, tx_shielding_inputs_trusted) => { + (Some(note), max_shard_priority, tx_trusted, tx_shielding_inputs_trusted) => { let shard_scanned = max_shard_priority .iter() .any(|p| *p <= ScanPriority::Scanned); @@ -472,27 +467,15 @@ where .zip(note_request.anchor_height()) .is_some_and(|(h, ah)| h <= ah); - let has_confirmations = match (note.mined_height(), note.spending_key_scope()) { - (None, _) => false, - (Some(received_height), Scope::Internal) => { - // The note has the required number of confirmations for a trusted note. - received_height <= trusted_height && - // if the note was the output of a shielding transaction - note.max_shielding_input_height().iter().all(|h| { - // its inputs have at least `untrusted` confirmations - h <= &untrusted_height || - // or its inputs are trusted and have at least `trusted` confirmations - (h <= &trusted_height && tx_shielding_inputs_trusted) - }) - } - (Some(received_height), Scope::External) => { - // The note has the required number of confirmations for an untrusted note. - received_height <= untrusted_height || - // or it is the output of an explicitly trusted tx and has at least - // `trusted` confirmations - (received_height <= trusted_height && trusted) - } - }; + let has_confirmations = confirmations_policy.confirmations_until_spendable( + target_height, + PoolType::Shielded(protocol), + Some(note.spending_key_scope()), + note.mined_height(), + tx_trusted, + note.max_shielding_input_height(), + tx_shielding_inputs_trusted, + ) == 0; match ( note_request, @@ -637,50 +620,47 @@ where ], |row| { let tx_trust_status = row.get::<_, bool>("trust_status")?; + let max_shielding_input_height = row + .get::<_, Option>("max_shielding_input_height")? + .map(BlockHeight::from); let tx_shielding_inputs_trusted = row.get::<_, bool>("min_shielding_input_trust")?; let note = to_spendable_note(params, row)?; - Ok(note.map(|n| (n, tx_trust_status, tx_shielding_inputs_trusted))) + Ok(note.map(|n| { + ( + n, + tx_trust_status, + max_shielding_input_height, + tx_shielding_inputs_trusted, + ) + })) }, )?; - let trusted_height = target_height.saturating_sub(u32::from(confirmations_policy.trusted())); - let untrusted_height = - target_height.saturating_sub(u32::from(confirmations_policy.untrusted())); - notes .filter_map(|result_maybe_note| { let result_note = result_maybe_note.transpose()?; result_note - .map(|(note, trusted, tx_shielding_inputs_trusted)| { - let received_height = note - .mined_height() - .expect("mined height checked to be non-null"); - - let has_confirmations = match note.spending_key_scope() { - Scope::Internal => { - // The note was has at least `trusted` confirmations. - received_height <= trusted_height && - // And, if the note was the output of a shielding transaction, its - // transparent inputs have at least `untrusted` confirmations. - note.max_shielding_input_height().iter().all(|h| { - // its inputs have at least `untrusted` confirmations - h <= &untrusted_height || - // or its inputs are trusted and have at least `trusted` confirmations - (h <= &trusted_height && tx_shielding_inputs_trusted) - }) - } - Scope::External => { - // The note has the required number of confirmations for an untrusted note. - received_height <= untrusted_height || - // or it is the output of an explicitly trusted tx and has at least - // `trusted` confirmations - (received_height <= trusted_height && trusted) - } - }; - - has_confirmations.then_some(note) - }) + .map( + |( + note, + tx_trusted, + max_shielding_input_height, + tx_shielding_inputs_trusted, + )| { + let has_confirmations = confirmations_policy.confirmations_until_spendable( + target_height, + PoolType::Shielded(protocol), + Some(note.spending_key_scope()), + note.mined_height(), + tx_trusted, + max_shielding_input_height, + tx_shielding_inputs_trusted, + ) == 0; + + has_confirmations.then_some(note) + }, + ) .transpose() }) .collect::, _>>() diff --git a/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs b/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs index 03b103f048..fac2bbd5df 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs @@ -132,7 +132,7 @@ mod tests { TestDsl::with_sapling_birthday_account(dsf, cache).build::(); // Add funds to the wallet in a single note - let (h, _, _) = st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(60000)); + let (_h, _, _) = st.add_a_single_note_checking_balance(Zatoshis::const_from_u64(60000)); let mut stmt = st.wallet().conn().prepare( "SELECT transaction_id, output_pool, output_index, value, recipient_key_scope FROM v_tx_outputs" From 108e1724f43b40d9e9529a039fbce0bc1e7a2e6e Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Fri, 21 Nov 2025 13:45:01 -0700 Subject: [PATCH 032/263] zcash_client_backend: Add `WalletRead::get_received_outputs` Fixes #2045 --- zcash_client_backend/CHANGELOG.md | 2 + zcash_client_backend/src/data_api.rs | 64 ++++++++++++++- zcash_client_backend/src/data_api/testing.rs | 15 +++- .../src/data_api/testing/pool.rs | 17 +++- zcash_client_memory/src/wallet_read.rs | 12 ++- zcash_client_sqlite/src/lib.rs | 20 ++++- zcash_client_sqlite/src/wallet.rs | 80 ++++++++++++++++++- zcash_client_sqlite/src/wallet/db.rs | 41 +++++----- .../migrations/v_tx_outputs_key_scopes.rs | 41 +++++----- 9 files changed, 241 insertions(+), 51 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 867669a5ec..178d8efff7 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -11,6 +11,7 @@ workspace. ## [Unreleased] ### Added +- `zcash_client_backend::data_api::ReceivedTransactionOutput` - `zcash_client_backend::data_api::wallet::ConfirmationsPolicy::confirmations_until_spendable` ### Changed @@ -32,6 +33,7 @@ workspace. key that will be used to encrypt any wallet-internal change outputs that would otherwise only be recoverable using the wallet's internal IVK. +- `zcash_client_backend::data_api::WalletRead` has added method `get_received_outputs. ## [0.21.0] - 2025-11-05 diff --git a/zcash_client_backend/src/data_api.rs b/zcash_client_backend/src/data_api.rs index 95a3290170..714a7961f4 100644 --- a/zcash_client_backend/src/data_api.rs +++ b/zcash_client_backend/src/data_api.rs @@ -83,7 +83,7 @@ use zcash_keys::{ }; use zcash_primitives::{block::BlockHash, transaction::Transaction}; use zcash_protocol::{ - ShieldedProtocol, TxId, + PoolType, ShieldedProtocol, TxId, consensus::BlockHeight, memo::{Memo, MemoBytes}, value::{BalanceError, Zatoshis}, @@ -1897,6 +1897,17 @@ pub trait WalletRead { /// transaction data requests, such as when it is necessary to fill in purely-transparent /// transaction history by walking the chain backwards via transparent inputs. fn transaction_data_requests(&self) -> Result, Self::Error>; + + /// Returns a vector of [`ReceivedTransactionOutput`] values describing the outputs of the + /// specified transaction that were received by the wallet. The number of confirmations until + /// each received output will be considered spendable is determined based upon the specified + /// target height and confirmations policy. + fn get_received_outputs( + &self, + txid: TxId, + target_height: TargetHeight, + confirmations_policy: ConfirmationsPolicy, + ) -> Result, Self::Error>; } /// Read-only operations required for testing light wallet functions. @@ -2469,6 +2480,57 @@ impl<'a, AccountId> SentTransaction<'a, AccountId> { } } +/// High-level information about the output of a transaction received by the wallet. +/// +/// This type is capable of representing both shielded and transparent outputs. It does not +/// internally store the transaction ID, so it must be interpreted in the context of a caller +/// having requested output information for a specific transaction. +pub struct ReceivedTransactionOutput { + pool_type: PoolType, + output_index: usize, + value: Zatoshis, + confirmations_until_spendable: u32, +} + +impl ReceivedTransactionOutput { + /// Constructs a [`ReceivedTransactionOutput`] from its constituent parts. + pub fn from_parts( + pool_type: PoolType, + output_index: usize, + value: Zatoshis, + confirmations_until_spendable: u32, + ) -> Self { + Self { + pool_type, + output_index, + value, + confirmations_until_spendable, + } + } + + /// Returns the pool in which the output value was received. + pub fn pool_type(&self) -> PoolType { + self.pool_type + } + + /// Returns the index of the output among the transaction's outputs to the associated pool. + pub fn output_index(&self) -> usize { + self.output_index + } + + /// Returns the value of the output. + pub fn value(&self) -> Zatoshis { + self.value + } + + /// Returns the number of confirmations required for the output to be treated as spendable, + /// given a [`ConfirmationsPolicy`] that was specified at the time of the request for this + /// data. + pub fn confirmations_until_spendable(&self) -> u32 { + self.confirmations_until_spendable + } +} + /// An output of a transaction generated by the wallet. /// /// This type is capable of representing both shielded and transparent outputs. diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index 6f34c5bc24..c2c8731cfc 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -47,9 +47,9 @@ use zip321::Payment; use super::{ Account, AccountBalance, AccountBirthday, AccountMeta, AccountPurpose, AccountSource, AddressInfo, BlockMetadata, DecryptedTransaction, InputSource, NoteFilter, NullifierQuery, - ReceivedNotes, SAPLING_SHARD_HEIGHT, ScannedBlock, SeedRelevance, SentTransaction, - TransactionDataRequest, TransactionStatus, WalletCommitmentTrees, WalletRead, WalletSummary, - WalletTest, WalletWrite, Zip32Derivation, + ReceivedNotes, ReceivedTransactionOutput, SAPLING_SHARD_HEIGHT, ScannedBlock, SeedRelevance, + SentTransaction, TransactionDataRequest, TransactionStatus, WalletCommitmentTrees, WalletRead, + WalletSummary, WalletTest, WalletWrite, Zip32Derivation, chain::{BlockSource, ChainState, CommitmentTreeRoot, ScanSummary, scan_cached_blocks}, error::Error, scanning::ScanRange, @@ -2781,6 +2781,15 @@ impl WalletRead for MockWalletDb { fn transaction_data_requests(&self) -> Result, Self::Error> { Ok(vec![]) } + + fn get_received_outputs( + &self, + _txid: TxId, + _target_height: TargetHeight, + _confirmations_policy: ConfirmationsPolicy, + ) -> Result, Self::Error> { + Ok(vec![]) + } } impl WalletWrite for MockWalletDb { diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index d9bb512baa..d278566b45 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -391,13 +391,28 @@ pub fn zip_315_confirmations_test_steps( let txid = r.txids()[0]; // Mark the external input as explicitly trusted, if so requested - if input_trust == InputTrust::ExternalTrusted { + let trusted = input_trust == InputTrust::ExternalTrusted; + if trusted { st.wallet_mut().set_tx_trust(txid, true).unwrap(); } let add_confirmation = |i: u32| { let (h, _) = st.generate_empty_block(); st.scan_cached_blocks(h, 1); + let outputs = st + .wallet() + .get_received_outputs(txid, TargetHeight::from(h + 1), confirmations_policy) + .unwrap(); + assert_eq!(outputs.len(), 1); + assert_eq!( + outputs[0].confirmations_until_spendable(), + u32::from(if trusted { + confirmations_policy.trusted() + } else { + confirmations_policy.untrusted() + }) + .saturating_sub(i + 1) + ); ConfirmationStep { i, confirmation_requirement: min_confirmations, diff --git a/zcash_client_memory/src/wallet_read.rs b/zcash_client_memory/src/wallet_read.rs index ff95498fae..e13f023346 100644 --- a/zcash_client_memory/src/wallet_read.rs +++ b/zcash_client_memory/src/wallet_read.rs @@ -7,7 +7,8 @@ use nonempty::NonEmpty; use secrecy::{ExposeSecret, SecretVec}; use shardtree::store::ShardStore as _; use zcash_client_backend::data_api::{ - AddressInfo, BlockMetadata, NullifierQuery, WalletRead, WalletSummary, Zip32Derivation, + AddressInfo, BlockMetadata, NullifierQuery, ReceivedTransactionOutput, WalletRead, + WalletSummary, Zip32Derivation, scanning::ScanRange, wallet::{ConfirmationsPolicy, TargetHeight}, }; @@ -738,6 +739,15 @@ impl WalletRead for MemoryWalletDb

{ fn utxo_query_height(&self, _account: Self::AccountId) -> Result { todo!() } + + fn get_received_outputs( + &self, + _txid: TxId, + _target_height: TargetHeight, + _confirmations_policy: ConfirmationsPolicy, + ) -> Result, Self::Error> { + todo!() + } } /// Copied from zcash_client_sqlite::wallet::seed_matches_derived_account diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index 7798bd1df2..c5348913a8 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -58,9 +58,9 @@ use zcash_client_backend::{ data_api::{ self, Account, AccountBirthday, AccountMeta, AccountPurpose, AccountSource, AddressInfo, BlockMetadata, DecryptedTransaction, InputSource, NoteFilter, NullifierQuery, - ReceivedNotes, SAPLING_SHARD_HEIGHT, ScannedBlock, SeedRelevance, SentTransaction, - TargetValue, TransactionDataRequest, WalletCommitmentTrees, WalletRead, WalletSummary, - WalletWrite, Zip32Derivation, + ReceivedNotes, ReceivedTransactionOutput, SAPLING_SHARD_HEIGHT, ScannedBlock, + SeedRelevance, SentTransaction, TargetValue, TransactionDataRequest, WalletCommitmentTrees, + WalletRead, WalletSummary, WalletWrite, Zip32Derivation, chain::{BlockSource, ChainState, CommitmentTreeRoot}, scanning::{ScanPriority, ScanRange}, wallet::{ConfirmationsPolicy, TargetHeight}, @@ -1061,6 +1061,20 @@ impl, P: consensus::Parameters, CL, R> WalletRea Ok(vec![]) } } + + fn get_received_outputs( + &self, + txid: TxId, + target_height: TargetHeight, + confirmations_policy: ConfirmationsPolicy, + ) -> Result, Self::Error> { + wallet::get_received_outputs( + self.conn.borrow(), + txid, + target_height, + confirmations_policy, + ) + } } #[cfg(any(test, feature = "test-dependencies"))] diff --git a/zcash_client_sqlite/src/wallet.rs b/zcash_client_sqlite/src/wallet.rs index ab77769a5c..e632245256 100644 --- a/zcash_client_sqlite/src/wallet.rs +++ b/zcash_client_sqlite/src/wallet.rs @@ -75,7 +75,7 @@ use std::{ use encoding::{ KeyScope, ReceiverFlags, account_kind_code, decode_diversifier_index_be, - encode_diversifier_index_be, memo_repr, pool_code, + encode_diversifier_index_be, memo_repr, parse_pool_code, pool_code, }; use incrementalmerkletree::{Marking, Retention}; use rusqlite::{self, Connection, OptionalExtension, named_params, params}; @@ -89,9 +89,9 @@ use zcash_client_backend::{ DecryptedOutput, data_api::{ Account as _, AccountBalance, AccountBirthday, AccountPurpose, AccountSource, AddressInfo, - AddressSource, BlockMetadata, DecryptedTransaction, Progress, Ratio, SAPLING_SHARD_HEIGHT, - SentTransaction, SentTransactionOutput, TransactionDataRequest, TransactionStatus, - WalletSummary, Zip32Derivation, + AddressSource, BlockMetadata, DecryptedTransaction, Progress, Ratio, + ReceivedTransactionOutput, SAPLING_SHARD_HEIGHT, SentTransaction, SentTransactionOutput, + TransactionDataRequest, TransactionStatus, WalletSummary, Zip32Derivation, scanning::{ScanPriority, ScanRange}, wallet::{ConfirmationsPolicy, TargetHeight}, }, @@ -4765,6 +4765,78 @@ pub(crate) fn get_block_range( .map_err(SqliteClientError::from) } +pub(crate) fn get_received_outputs( + conn: &rusqlite::Connection, + txid: TxId, + target_height: TargetHeight, + confirmations_policy: ConfirmationsPolicy, +) -> Result, SqliteClientError> { + let mut stmt_received_outputs = conn.prepare_cached( + "SELECT + vto.output_pool, + vto.output_index, + vto.recipient_key_scope, + vto.value, + vto.tx_mined_height, + IFNULL(vto.tx_trust_status, 0) AS tx_trust_status, + MAX(tt.mined_height) AS max_shielding_input_height, + MIN(IFNULL(tt.trust_status, 0)) AS min_shielding_input_trust + FROM v_tx_outputs vto + LEFT OUTER JOIN transparent_received_output_spends ros + ON ros.transaction_id = vto.transaction_id + LEFT OUTER JOIN transparent_received_outputs tro + ON tro.id = ros.transparent_received_output_id + LEFT OUTER JOIN transactions tt + ON tt.id_tx = tro.transaction_id + WHERE vto.txid = :txid + GROUP BY vto.output_pool, vto.output_index", + )?; + + let results = stmt_received_outputs + .query_and_then::<_, SqliteClientError, _, _>( + named_params![":txid": txid.as_ref()], + |row| { + let pool_type = parse_pool_code(row.get("output_pool")?)?; + let output_index = row.get("output_index")?; + let value = Zatoshis::from_nonnegative_i64(row.get("value")?)?; + let mined_height = row + .get::<_, Option>("tx_mined_height")? + .map(BlockHeight::from); + let max_shielding_input_height = row + .get::<_, Option>("max_shielding_input_height")? + .map(BlockHeight::from); + let tx_shielding_inputs_trusted = + row.get::<_, bool>("min_shielding_input_trust")?; + let key_scope = row + .get::<_, Option>("recipient_key_scope")? + .map(KeyScope::decode) + .transpose()?; + let tx_trusted = row.get::<_, bool>("tx_trust_status")?; + + let confirmations_until_spendable = confirmations_policy + .confirmations_until_spendable( + target_height, + pool_type, + key_scope.and_then(|s| zip32::Scope::try_from(s).ok()), + mined_height, + tx_trusted, + max_shielding_input_height, + tx_shielding_inputs_trusted, + ); + + Ok(ReceivedTransactionOutput::from_parts( + pool_type, + output_index, + value, + confirmations_until_spendable, + )) + }, + )? + .collect::, _>>()?; + + Ok(results) +} + #[cfg(any(test, feature = "test-dependencies"))] pub mod testing { use incrementalmerkletree::Position; diff --git a/zcash_client_sqlite/src/wallet/db.rs b/zcash_client_sqlite/src/wallet/db.rs index 148ca54e16..7513c883a7 100644 --- a/zcash_client_sqlite/src/wallet/db.rs +++ b/zcash_client_sqlite/src/wallet/db.rs @@ -1127,9 +1127,10 @@ pub(super) const VIEW_TX_OUTPUTS: &str = " CREATE VIEW v_tx_outputs AS WITH unioned AS ( -- select all outputs received by the wallet - SELECT transactions.id_tx AS transaction_id, - transactions.txid AS txid, - transactions.mined_height AS mined_height, + SELECT t.id_tx AS transaction_id, + t.txid AS txid, + t.mined_height AS mined_height, + IFNULL(t.trust_status, 0) AS trust_status, ro.pool AS output_pool, ro.output_index AS output_index, from_account.uuid AS from_account_uuid, @@ -1141,8 +1142,8 @@ WITH unioned AS ( ro.memo AS memo, a.key_scope AS recipient_key_scope FROM v_received_outputs ro - JOIN transactions - ON transactions.id_tx = ro.transaction_id + JOIN transactions t + ON t.id_tx = ro.transaction_id LEFT JOIN addresses a ON a.id = ro.address_id -- join to the sent_notes table to obtain `from_account_id` LEFT JOIN sent_notes ON sent_notes.id = ro.sent_note_id @@ -1151,9 +1152,10 @@ WITH unioned AS ( LEFT JOIN accounts to_account ON to_account.id = ro.account_id UNION ALL -- select all outputs sent from the wallet to external recipients - SELECT transactions.id_tx AS transaction_id, - transactions.txid AS txid, - transactions.mined_height AS mined_height, + SELECT t.id_tx AS transaction_id, + t.txid AS txid, + t.mined_height AS mined_height, + IFNULL(t.trust_status, 0) AS trust_status, sent_notes.output_pool AS output_pool, sent_notes.output_index AS output_index, from_account.uuid AS from_account_uuid, @@ -1165,8 +1167,8 @@ WITH unioned AS ( sent_notes.memo AS memo, NULL AS recipient_key_scope FROM sent_notes - JOIN transactions - ON transactions.id_tx = sent_notes.transaction_id + JOIN transactions t + ON t.id_tx = sent_notes.transaction_id LEFT JOIN v_received_outputs ro ON ro.sent_note_id = sent_notes.id -- join on the accounts table to obtain account UUIDs LEFT JOIN accounts from_account ON from_account.id = sent_notes.from_account_id @@ -1174,17 +1176,18 @@ WITH unioned AS ( -- merge duplicate rows while retaining maximum information SELECT transaction_id, - MAX(txid), - MAX(mined_height) AS mined_height, + MAX(txid) AS txid, + MAX(mined_height) AS tx_mined_height, + MIN(trust_status) AS tx_trust_status, output_pool, output_index, - MAX(from_account_uuid) AS from_account_uuid, - MAX(to_account_uuid) AS to_account_uuid, - MAX(to_address) AS to_address, - MAX(value) AS value, - MAX(is_change) AS is_change, - MAX(memo) AS memo, - MAX(recipient_key_scope) AS recipient_key_scope + MAX(from_account_uuid) AS from_account_uuid, + MAX(to_account_uuid) AS to_account_uuid, + MAX(to_address) AS to_address, + MAX(value) AS value, + MAX(is_change) AS is_change, + MAX(memo) AS memo, + MAX(recipient_key_scope) AS recipient_key_scope FROM unioned GROUP BY transaction_id, output_pool, output_index"; diff --git a/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs b/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs index fac2bbd5df..a08150e90d 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations/v_tx_outputs_key_scopes.rs @@ -37,9 +37,10 @@ impl RusqliteMigration for Migration { CREATE VIEW v_tx_outputs AS WITH unioned AS ( -- select all outputs received by the wallet - SELECT transactions.id_tx AS transaction_id, - transactions.txid AS txid, - transactions.mined_height AS mined_height, + SELECT t.id_tx AS transaction_id, + t.txid AS txid, + t.mined_height AS mined_height, + IFNULL(t.trust_status, 0) AS trust_status, ro.pool AS output_pool, ro.output_index AS output_index, from_account.uuid AS from_account_uuid, @@ -51,8 +52,8 @@ impl RusqliteMigration for Migration { ro.memo AS memo, a.key_scope AS recipient_key_scope FROM v_received_outputs ro - JOIN transactions - ON transactions.id_tx = ro.transaction_id + JOIN transactions t + ON t.id_tx = ro.transaction_id LEFT JOIN addresses a ON a.id = ro.address_id -- join to the sent_notes table to obtain `from_account_id` LEFT JOIN sent_notes ON sent_notes.id = ro.sent_note_id @@ -61,9 +62,10 @@ impl RusqliteMigration for Migration { LEFT JOIN accounts to_account ON to_account.id = ro.account_id UNION ALL -- select all outputs sent from the wallet to external recipients - SELECT transactions.id_tx AS transaction_id, - transactions.txid AS txid, - transactions.mined_height AS mined_height, + SELECT t.id_tx AS transaction_id, + t.txid AS txid, + t.mined_height AS mined_height, + IFNULL(t.trust_status, 0) AS trust_status, sent_notes.output_pool AS output_pool, sent_notes.output_index AS output_index, from_account.uuid AS from_account_uuid, @@ -75,8 +77,8 @@ impl RusqliteMigration for Migration { sent_notes.memo AS memo, NULL AS recipient_key_scope FROM sent_notes - JOIN transactions - ON transactions.id_tx = sent_notes.transaction_id + JOIN transactions t + ON t.id_tx = sent_notes.transaction_id LEFT JOIN v_received_outputs ro ON ro.sent_note_id = sent_notes.id -- join on the accounts table to obtain account UUIDs LEFT JOIN accounts from_account ON from_account.id = sent_notes.from_account_id @@ -84,17 +86,18 @@ impl RusqliteMigration for Migration { -- merge duplicate rows while retaining maximum information SELECT transaction_id, - MAX(txid), - MAX(mined_height) AS mined_height, + MAX(txid) AS txid, + MAX(mined_height) AS tx_mined_height, + MIN(trust_status) AS tx_trust_status, output_pool, output_index, - MAX(from_account_uuid) AS from_account_uuid, - MAX(to_account_uuid) AS to_account_uuid, - MAX(to_address) AS to_address, - MAX(value) AS value, - MAX(is_change) AS is_change, - MAX(memo) AS memo, - MAX(recipient_key_scope) AS recipient_key_scope + MAX(from_account_uuid) AS from_account_uuid, + MAX(to_account_uuid) AS to_account_uuid, + MAX(to_address) AS to_address, + MAX(value) AS value, + MAX(is_change) AS is_change, + MAX(memo) AS memo, + MAX(recipient_key_scope) AS recipient_key_scope FROM unioned GROUP BY transaction_id, output_pool, output_index; "#, From e74064ce6906a7dcd9ceca0087e7c03f8251a122 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 8 Dec 2025 08:52:29 -0700 Subject: [PATCH 033/263] Apply suggestions from code review Co-authored-by: Jack Grigg --- zcash_client_sqlite/CHANGELOG.md | 3 ++- zcash_client_sqlite/src/wallet/db.rs | 2 +- zcash_client_sqlite/src/wallet/init/migrations.rs | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/zcash_client_sqlite/CHANGELOG.md b/zcash_client_sqlite/CHANGELOG.md index 84c2eb256a..717aee3615 100644 --- a/zcash_client_sqlite/CHANGELOG.md +++ b/zcash_client_sqlite/CHANGELOG.md @@ -13,7 +13,8 @@ workspace. ### Added - The following columns have been added to the exposed `v_tx_outputs` view: - `transaction_id` - - `mined_height` + - `tx_mined_height` + - `tx_trust_status` - `recipient_key_scope` ### Changed diff --git a/zcash_client_sqlite/src/wallet/db.rs b/zcash_client_sqlite/src/wallet/db.rs index 7513c883a7..1f1c8bcd62 100644 --- a/zcash_client_sqlite/src/wallet/db.rs +++ b/zcash_client_sqlite/src/wallet/db.rs @@ -1096,7 +1096,7 @@ GROUP BY notes.account_id, notes.transaction_id"; /// Sapling `OutputDescription` values, or the vector of Orchard actions. /// - `tx_mined_height`: An optional value identifying the block height at which the transaction that /// produced this output was mined, or NULL if the transaction is unmined. -/// - `tx_trust_status`: A flag indicating whether the transaction that produced these outputs +/// - `tx_trust_status`: A flag indicating whether the transaction that produced this output /// should be considered "trusted". When set to `1`, outputs of this transaction will be considered /// spendable with `trusted` confirmations instead of `untrusted` confirmations. /// - `from_account_uuid`: The UUID of the wallet account that created the output, if the wallet diff --git a/zcash_client_sqlite/src/wallet/init/migrations.rs b/zcash_client_sqlite/src/wallet/init/migrations.rs index a643107243..3a119070d2 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations.rs @@ -131,6 +131,8 @@ pub(super) fn all_migrations< // \ \ v_received_output_spends_account / / // \ \ / / / // `------------------- account_delete_cascade ---------------------------------' + // | + // v_tx_outputs_key_scopes // let rng = Rc::new(Mutex::new(rng)); vec![ From 9dd7924631649fc4344e037b4eff64572eff5ba6 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 8 Dec 2025 14:41:07 -0700 Subject: [PATCH 034/263] Squashed 'zcash_client_backend/lightwallet-protocol/' changes from b314868de..23f0768ea 23f0768ea Release lightwallet-protocol v0.4.0 41156c767 Merge pull request #11 from zcash/feature/get_mempool_tx_pools 7c130e883 Add `lightwalletProtocolVersion` field to `LightdInfo` struct. edbb726d7 Apply suggestion from code review 38fddd73b Apply suggestions from code review 0250f2720 Add pool type filtering to `GetMempoolTx` argument. 54ccaadd5 Change semantics of pool-based pruning of compact transactions from "may prune" to "must prune". b0667ec99 Merge pull request #9 from zcash/2025-11-doc-TransparentAddressBlockFilter f3fea7bd4 doc: TransparentAddressBlockFilter doesn't include mempool a67dd323a Merge pull request #8 from zcash/2025-11-lightdinfo-upgrade-info 11da4b7e3 add next upgrade info to LightdInfo structure (GetLightdInfo) 42cd8f720 Transparent data docs update (#7) c0cf957ac Merge pull request #5 from zcash/2025-11-comments 912fc3609 Minor clarification in GetBlockRange documentation. 6b03f2cce Documentation (comments) only d978256a2 Merge pull request #1 from zcash/compact_tx_transparent 7eeb82e7c Merge pull request #4 from zcash/add_changelog a95359dc9 Apply suggestions from code review 592b637a8 Add transparent data to the `CompactBlock` format. 9d1fb2c41 Add a CHANGELOG.md that documents the evolution of the light client protocol. 180717dfa Merge pull request #3 from zcash/merge_librustzcash_history 450bd4181 Merge the history of the .proto files from `librustzcash` for complete history preservation. a4859d11d Move protobuf files into place for use in `zcash/lightwallet-protocol` 2e66cdd9e Update zcash_client_backend/proto/service.proto eda012519 fix comment f838d10ad Add gRPC LightdInfo Donation Address db12c0415 Merge pull request #1473 from nuttycom/wallet/enrichment_queue 698feba96 Apply suggestions from code review 20ce57ab3 zcash_client_backend: Add `block_height` argument to `decrypt_and_store_transaction` a6dea1da8 Merge pull request #1482 from zancas/doc_tweak 4d2d45fc9 fix incorrect doc-comment e826f4740 update CompactBlock doc-comment, to cover non-Sapling shielded notes, and addresses e9a6c00bf Various documentation improvements 988bc7214 Merge pull request #872 from nuttycom/feature/pre_dag_sync-suggest_scan_ranges 58d07d469 Implement `suggest_scan_ranges` and `update_chain_tip` a9222b338 Address comments from code review. e20310857 Rename proto::compact::{BlockMetadata => ChainMetadata} ac63418c5 Reorganize Sapling and Orchard note commitment tree sizes in CompactBlock. 0fdca14f1 zcash_client_backend: Add note commitment tree sizes to `CompactBlock` serialization. 2a0c2b8b7 zcash_client_backend: Add gRPC bindings behind feature flag 1342f0480 zcash_client_backend: Address compact_formats.proto comments 68aa4e01b zcash_client_backend: Bring in latest `compact_formats.proto` e712eb1bc Add prevHash field to CompactBlock 440384c3e Build protobufs for compact formats git-subtree-dir: zcash_client_backend/lightwallet-protocol git-subtree-split: 23f0768ea4471b63285f3c0e9b6fbb361674aa2b --- CHANGELOG.md | 171 ++++++++++++++++++++++++++++++++ walletrpc/compact_formats.proto | 73 +++++++++++--- walletrpc/service.proto | 114 +++++++++++++++------ 3 files changed, 314 insertions(+), 44 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..59a13060ff --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,171 @@ +# Changelog +All notable changes to this library will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this library adheres to Rust's notion of +[Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## [v0.4.0] - 2025-12-03 + +### Added +- `compact_formats.CompactTxIn` +- `compact_formats.TxOut` +- `service.PoolType` +- `service.LightdInfo` has added fields `upgradeName`, `upgradeHeight`, and + `lightwalletProtocolVersion` +- `compact_formats.CompactTx` has added fields `vin` and `vout`, + which may be used to represent transparent transaction input and output data. +- `service.BlockRange` has added field `poolTypes`, which allows + the caller of service methods that take this type as input to cause returned + data to be filtered to include information only for the specified protocols. + For backwards compatibility, when this field is set the default (empty) value, + servers should return Sapling and Orchard data. This field is to be ignored + when the type is used as part of a `service.TransparentAddressBlockFilter`. + +### Changed +- The `hash` field of `compact_formats.CompactTx` has been renamed to `txid`. + This is a serialization-compatible clarification, as the index of this field + in the .proto type does not change. +- `service.Exclude` has been renamed to `service.GetMempoolTxRequest` and has + an added `poolTypes` field, which allows the caller of this method to specify + which pools the resulting `CompactTx` values should contain data for. + +### Deprecated +- `service.CompactTxStreamer`: + - The `GetBlockNullifiers` and `GetBlockRangeNullifiers` methods are + deprecated. + +## [v0.3.6] - 2025-05-20 + +### Added +- `service.LightdInfo` has added field `donationAddress` +- `service.CompactTxStreamer.GetTaddressTransactions`. This duplicates + the `GetTaddressTxids` method, but is more accurately named. + +### Deprecated +- `service.CompactTxStreamer.GetTaddressTxids`. Use `GetTaddressTransactions` + instead. + +## [v0.3.5] - 2023-07-03 + +### Added +- `compact_formats.ChainMetadata` +- `service.ShieldedProtocol` +- `service.GetSubtreeRootsArg` +- `service.SubtreeRoot` +- `service.CompactTxStreamer.GetBlockNullifiers` +- `service.CompactTxStreamer.GetBlockRangeNullifiers` +- `service.CompactTxStreamer.SubtreeRoots` + +### Changed +- `compact_formats.CompactBlock` has added field `chainMetadata` +- `compact_formats.CompactSaplingOutput.epk` has been renamed to `ephemeralKey` + +## [v0.3.4] - UNKNOWN + +### Added +- `service.CompactTxStreamer.GetLatestTreeState` + +## [v0.3.3] - 2022-04-02 + +### Added +- `service.TreeState` has added field `orchardTree` + +### Changed +- `service.TreeState.tree` has been renamed to `saplingTree` + +## [v0.3.2] - 2021-12-09 + +### Changed +- `compact_formats.CompactOrchardAction.encCiphertext` has been renamed to + `CompactOrchardAction.ciphertext` + +## [v0.3.1] - 2021-12-09 + +### Added +- `compact_formats.CompactOrchardAction` +- `service.CompactTxStreamer.GetMempoolTx` (removed in 0.3.0) has been reintroduced. +- `service.Exclude` (removed in 0.3.0) has been reintroduced. + +### Changed +- `compact_formats.CompactSpend` has been renamed `CompactSaplingSpend` +- `compact_formats.CompactOutput` has been renamed `CompactSaplingOutput` + +## [v0.3.0] - 2021-07-23 + +### Added +- `service.CompactTxStreamer.GetMempoolStream` + +### Removed +- `service.CompactTxStreamer.GetMempoolTx` has been replaced by `GetMempoolStream` +- `service.Exclude` has been removed as it is now unused. + +## [v0.2.4] - 2021-01-14 + +### Changed +- `service.GetAddressUtxosArg.address` has been replaced by the + repeated field `addresses`. This is a [conditionally-safe](https://protobuf.dev/programming-guides/proto3/#conditionally-safe-changes) + format change. +- `service.GetAddressUtxosReply` has added field `address` + +## [v0.2.3] - 2021-01-14 + +### Added +- `service.LightdInfo` has added fields: + - `estimatedHeight` + - `zcashdBuild` + - `zcashdSubversion` + +## [v0.2.2] - 2020-10-22 + +### Added +- `service.TreeState` +- `service.GetAddressUtxosArg` +- `service.GetAddressUtxosReply` +- `service.GetAddressUtxosReplyList` +- `service.CompactTxStreamer.GetTreeState` +- `service.CompactTxStreamer.GetAddressUtxos` +- `service.CompactTxStreamer.GetAddressUtxosStream` + +## [v0.2.1] - 2020-10-06 + +### Added +- `service.Address` +- `service.AddressList` +- `service.Balance` +- `service.Exclude` +- `service.CompactTxStreamer.GetTaddressBalance` +- `service.CompactTxStreamer.GetTaddressBalanceStream` +- `service.CompactTxStreamer.GetMempoolTx` +- `service.LightdInfo` has added fields: + - `gitCommit` + - `branch` + - `buildDate` + - `buildUser` + +## [v0.2.0] - 2020-04-24 + +### Added +- `service.Duration` +- `service.PingResponse` +- `service.CompactTxStreamer.Ping` + +### Removed +- `service.TransparentAddress` was removed (it was unused in any service API). + +## [v0.1.1] - 2019-11-27 + +### Added +- `service.Empty` +- `service.LightdInfo` +- `service.TransparentAddress` +- `service.TransparentAddressBlockFilter` +- `service.CompactTxStreamer.GetTaddressTxids` +- `service.CompactTxStreamer.GetLightdInfo` +- `service.RawTransaction` has added field `height` + +## [v0.1.0] - 2019-09-19 + +Initial release diff --git a/walletrpc/compact_formats.proto b/walletrpc/compact_formats.proto index c799448cec..c62c7acbb1 100644 --- a/walletrpc/compact_formats.proto +++ b/walletrpc/compact_formats.proto @@ -7,8 +7,8 @@ package cash.z.wallet.sdk.rpc; option go_package = "lightwalletd/walletrpc"; option swift_prefix = ""; -// Remember that proto3 fields are all optional. A field that is not present will be set to its zero value. -// bytes fields of hashes are in canonical little-endian format. +// REMINDER: proto3 fields are all optional. A field that is not present will be set to its zero/false/empty +// value. // Information about the state of the chain as of a given block. message ChainMetadata { @@ -16,34 +16,40 @@ message ChainMetadata { uint32 orchardCommitmentTreeSize = 2; // the size of the Orchard note commitment tree as of the end of this block } -// A compact representation of the shielded data in a Zcash block. +// A compact representation of a Zcash block. // // CompactBlock is a packaging of ONLY the data from a block that's needed to: // 1. Detect a payment to your Shielded address // 2. Detect a spend of your Shielded notes // 3. Update your witnesses to generate new spend proofs. +// 4. Spend UTXOs associated to t-addresses of your wallet. message CompactBlock { uint32 protoVersion = 1; // the version of this wire format, for storage uint64 height = 2; // the height of this block bytes hash = 3; // the ID (hash) of this block, same as in block explorers bytes prevHash = 4; // the ID (hash) of this block's predecessor uint32 time = 5; // Unix epoch time when the block was mined - bytes header = 6; // (hash, prevHash, and time) OR (full header) + bytes header = 6; // full header (as returned by the getblock RPC) repeated CompactTx vtx = 7; // zero or more compact transactions from this block ChainMetadata chainMetadata = 8; // information about the state of the chain as of this block } -// A compact representation of the shielded data in a Zcash transaction. +// A compact representation of a Zcash transaction. // // CompactTx contains the minimum information for a wallet to know if this transaction -// is relevant to it (either pays to it or spends from it) via shielded elements -// only. This message will not encode a transparent-to-transparent transaction. +// is relevant to it (either pays to it or spends from it) via shielded elements. Additionally, +// it can optionally include the minimum necessary data to detect payments to transparent addresses +// related to your wallet. message CompactTx { - // Index and hash will allow the receiver to call out to chain - // explorers or other data structures to retrieve more information - // about this transaction. - uint64 index = 1; // the index within the full block - bytes hash = 2; // the ID (hash) of this transaction, same as in block explorers + // The index of the transaction within the block. + uint64 index = 1; + + // The id of the transaction as defined in + // [§ 7.1.1 ‘Transaction Identifiers’](https://zips.z.cash/protocol/protocol.pdf#txnidentifiers) + // This byte array MUST be in protocol order and MUST NOT be reversed + // or hex-encoded; the byte-reversed and hex-encoded representation is + // exclusively a textual representation of a txid. + bytes txid = 2; // The transaction fee: present if server can provide. In the case of a // stateless server and a transaction with transparent inputs, this will be @@ -55,6 +61,41 @@ message CompactTx { repeated CompactSaplingSpend spends = 4; repeated CompactSaplingOutput outputs = 5; repeated CompactOrchardAction actions = 6; + + // `CompactTxIn` values corresponding to the `vin` entries of the full transaction. + // + // Note: the single null-outpoint input for coinbase transactions is omitted. Light + // clients can test `CompactTx.index == 0` to determine whether a `CompactTx` + // represents a coinbase transaction, as the coinbase transaction is always the + // first transaction in any block. + repeated CompactTxIn vin = 7; + + // A sequence of transparent outputs being created by the transaction. + repeated TxOut vout = 8; +} + +// A compact representation of a transparent transaction input. +message CompactTxIn { + // The id of the transaction that generated the output being spent. This + // byte array must be in protocol order and MUST NOT be reversed or + // hex-encoded. + bytes prevoutTxid = 1; + + // The index of the output being spent in the `vout` array of the + // transaction referred to by `prevoutTxid`. + uint32 prevoutIndex = 2; +} + +// A transparent output being created by the transaction. +// +// This contains identical data to the `TxOut` type in the transaction itself, and +// thus it is not "compact". +message TxOut { + // The value of the output, in Zatoshis. + uint64 value = 1; + + // The script pubkey that must be satisfied in order to spend this output. + bytes scriptPubKey = 2; } // A compact representation of a [Sapling Spend](https://zips.z.cash/protocol/protocol.pdf#spendencodingandconsensus). @@ -62,7 +103,7 @@ message CompactTx { // CompactSaplingSpend is a Sapling Spend Description as described in 7.3 of the Zcash // protocol specification. message CompactSaplingSpend { - bytes nf = 1; // nullifier (see the Zcash protocol specification) + bytes nf = 1; // Nullifier (see the Zcash protocol specification) } // A compact representation of a [Sapling Output](https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus). @@ -70,9 +111,9 @@ message CompactSaplingSpend { // It encodes the `cmu` field, `ephemeralKey` field, and a 52-byte prefix of the // `encCiphertext` field of a Sapling Output Description. Total size is 116 bytes. message CompactSaplingOutput { - bytes cmu = 1; // note commitment u-coordinate - bytes ephemeralKey = 2; // ephemeral public key - bytes ciphertext = 3; // first 52 bytes of ciphertext + bytes cmu = 1; // Note commitment u-coordinate. + bytes ephemeralKey = 2; // Ephemeral public key. + bytes ciphertext = 3; // First 52 bytes of ciphertext. } // A compact representation of an [Orchard Action](https://zips.z.cash/protocol/protocol.pdf#actionencodingandconsensus). diff --git a/walletrpc/service.proto b/walletrpc/service.proto index 0a0989c7d3..d3dc8ba045 100644 --- a/walletrpc/service.proto +++ b/walletrpc/service.proto @@ -8,18 +8,35 @@ option go_package = "lightwalletd/walletrpc"; option swift_prefix = ""; import "compact_formats.proto"; +// An identifier for a Zcash value pool. +enum PoolType { + POOL_TYPE_INVALID = 0; + TRANSPARENT = 1; + SAPLING = 2; + ORCHARD = 3; +} + // A BlockID message contains identifiers to select a block: a height or a // hash. Specification by hash is not implemented, but may be in the future. message BlockID { - uint64 height = 1; - bytes hash = 2; + uint64 height = 1; + bytes hash = 2; } // BlockRange specifies a series of blocks from start to end inclusive. // Both BlockIDs must be heights; specification by hash is not yet supported. +// +// If no pool types are specified, the server should default to the legacy +// behavior of returning only data relevant to the shielded (Sapling and +// Orchard) pools; otherwise, the server should prune `CompactBlocks` returned +// to include only data relevant to the requested pool types. Clients MUST +// verify that the version of the server they are connected to are capable +// of returning pruned and/or transparent data before setting `poolTypes` +// to a non-empty value. message BlockRange { BlockID start = 1; BlockID end = 2; + repeated PoolType poolTypes = 3; } // A TxFilter contains the information needed to identify a particular @@ -93,13 +110,21 @@ message LightdInfo { string zcashdBuild = 13; // example: "v4.1.1-877212414" string zcashdSubversion = 14; // example: "/MagicBean:4.1.1/" string donationAddress = 15; // Zcash donation UA address + string upgradeName = 16; // name of next pending network upgrade, empty if none scheduled + uint64 upgradeHeight = 17; // height of next pending upgrade, zero if none is scheduled + string lightwalletProtocolVersion = 18; // version of https://github.com/zcash/lightwallet-protocol served by this server } -// TransparentAddressBlockFilter restricts the results to the given address -// or block range. +// TransparentAddressBlockFilter restricts the results of the GRPC methods that +// use it to the transactions that involve the given address and were mined in +// the specified block range. Non-default values for both the address and the +// block range must be specified. Mempool transactions are not included. +// +// The `poolTypes` field of the `range` argument should be ignored. +// Implementations MAY consider it an error if any pool types are specified. message TransparentAddressBlockFilter { string address = 1; // t-address - BlockRange range = 2; // start, end heights + BlockRange range = 2; // start, end heights only } // Duration is currently used only for testing, so that the Ping rpc @@ -127,10 +152,23 @@ message Balance { int64 valueZat = 1; } -// The a shortened transaction ID is the prefix in big-endian (hex) format -// (then converted to binary). -message Exclude { - repeated bytes txid = 1; +// Request parameters for the `GetMempoolTx` RPC. +message GetMempoolTxRequest { + // A list of transaction ID byte string suffixes that should be excluded + // from the response. These suffixes may be produced either directly from + // the underlying txid bytes, or, if the source values are encoded txid + // strings, by truncating the hexadecimal representation of each + // transaction ID to an even number of characters, and then hex-decoding + // and then byte-reversing this value to obtain the byte representation. + repeated bytes exclude_txid_suffixes = 1; + // We reserve field number 2 for a potential future `exclude_txid_prefixes` + // field. + reserved 2; + // The server must prune `CompactTx`s returned to include only data + // relevant to the requested pool types. If no pool types are specified, + // the server should default to the legacy behavior of returning only data + // relevant to the shielded (Sapling and Orchard) pools. + repeated PoolType poolTypes = 3; } // The TreeState is derived from the Zcash z_gettreestate rpc. @@ -181,44 +219,63 @@ message GetAddressUtxosReplyList { service CompactTxStreamer { // Return the BlockID of the block at the tip of the best chain rpc GetLatestBlock(ChainSpec) returns (BlockID) {} + // Return the compact block corresponding to the given block identifier rpc GetBlock(BlockID) returns (CompactBlock) {} - // Same as GetBlock except actions contain only nullifiers + + // Same as GetBlock except the returned CompactBlock value contains only + // nullifiers. + // + // Note: this method is deprecated. Implementations should ignore any + // `PoolType::TRANSPARENT` member of the `poolTypes` argument. rpc GetBlockNullifiers(BlockID) returns (CompactBlock) {} - // Return a list of consecutive compact blocks + + // Return a list of consecutive compact blocks in the specified range, + // which is inclusive of `range.end`. + // + // If range.start <= range.end, blocks are returned increasing height order; + // otherwise blocks are returned in decreasing height order. rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {} - // Same as GetBlockRange except actions contain only nullifiers + + // Same as GetBlockRange except the returned CompactBlock values contain + // only nullifiers. + // + // Note: this method is deprecated. Implementations should ignore any + // `PoolType::TRANSPARENT` member of the `poolTypes` argument. rpc GetBlockRangeNullifiers(BlockRange) returns (stream CompactBlock) {} // Return the requested full (not compact) transaction (as from zcashd) rpc GetTransaction(TxFilter) returns (RawTransaction) {} + // Submit the given transaction to the Zcash network rpc SendTransaction(RawTransaction) returns (SendResponse) {} - // Return the transactions corresponding to the given t-address within the given block range - // NB - this method is misnamed, it returns transactions, not transaction IDs. + // Return RawTransactions that match the given transparent address filter. + // + // Note: This function is misnamed, it returns complete `RawTransaction` values, not TxIds. // NOTE: this method is deprecated, please use GetTaddressTransactions instead. rpc GetTaddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {} - // Return the transactions corresponding to the given t-address within the given block range + // Return the transactions corresponding to the given t-address within the given block range. + // Mempool transactions are not included in the results. rpc GetTaddressTransactions(TransparentAddressBlockFilter) returns (stream RawTransaction) {} rpc GetTaddressBalance(AddressList) returns (Balance) {} rpc GetTaddressBalanceStream(stream Address) returns (Balance) {} - // Return the compact transactions currently in the mempool; the results - // can be a few seconds out of date. If the Exclude list is empty, return - // all transactions; otherwise return all *except* those in the Exclude list - // (if any); this allows the client to avoid receiving transactions that it - // already has (from an earlier call to this rpc). The transaction IDs in the - // Exclude list can be shortened to any number of bytes to make the request - // more bandwidth-efficient; if two or more transactions in the mempool - // match a shortened txid, they are all sent (none is excluded). Transactions - // in the exclude list that don't exist in the mempool are ignored. - // - // The a shortened transaction ID is the prefix in big-endian (hex) format - // (then converted to binary). See smoke-test.bash for examples. - rpc GetMempoolTx(Exclude) returns (stream CompactTx) {} + // Returns a stream of the compact transaction representation for transactions + // currently in the mempool. The results of this operation may be a few + // seconds out of date. If the `exclude_txid_suffixes` list is empty, + // return all transactions; otherwise return all *except* those in the + // `exclude_txid_suffixes` list (if any); this allows the client to avoid + // receiving transactions that it already has (from an earlier call to this + // RPC). The transaction IDs in the `exclude_txid_suffixes` list can be + // shortened to any number of bytes to make the request more + // bandwidth-efficient; if two or more transactions in the mempool match a + // txid suffix, none of the matching transactions are excluded. Txid + // suffixes in the exclude list that don't match any transactions in the + // mempool are ignored. + rpc GetMempoolTx(GetMempoolTxRequest) returns (stream CompactTx) {} // Return a stream of current Mempool transactions. This will keep the output stream open while // there are mempool transactions. It will close the returned stream when a new block is mined. @@ -240,6 +297,7 @@ service CompactTxStreamer { // Return information about this lightwalletd instance and the blockchain rpc GetLightdInfo(Empty) returns (LightdInfo) {} + // Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production) rpc Ping(Duration) returns (PingResponse) {} } From b96cb27ed4ed7272965eec76a72f4b3df96704e6 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 8 Dec 2025 17:00:00 -0700 Subject: [PATCH 035/263] zcash_client_backend: Regenerate lightwallet GRPC API types after lightwallet-protocol_v0.4.0 update. --- zcash_client_backend/CHANGELOG.md | 17 ++- zcash_client_backend/build.rs | 8 ++ .../src/proto/compact_formats.rs | 71 +++++++--- zcash_client_backend/src/proto/service.rs | 134 ++++++++++++++---- 4 files changed, 187 insertions(+), 43 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 178d8efff7..7e187f0cf0 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -13,9 +13,24 @@ workspace. ### Added - `zcash_client_backend::data_api::ReceivedTransactionOutput` - `zcash_client_backend::data_api::wallet::ConfirmationsPolicy::confirmations_until_spendable` +- in `zcash_client_backend::proto::compact_formats`: + - `CompactTx` has added fields `vin` and `vout` + - Added types `CompactTxIn`, `TxOut` +- in `zcash_client_backend::proto::service`: + - Added enum `PoolType` + - `BlockRange` has added field `pool_types` + - `LightdInfo` has added fields `upgrade_name`, `upgrade_height`, and `lighwallet_protocol_version` + - `GetMempoolTxRequest` (previously named `Exclude`) has added field `pool_types` ### Changed - Migrated to `orchard 0.12`, `sapling-crypto 0.6`. +- Migrated to `lightwallet-protocol v0.4.0`. This results in the following API + changes: + - in `zcash_client_backend::proto::compact_formats`: + - `CompactTx::hash` has been renamed to `CompactTx::txid` + - in `zcash_client_backend::proto::service`: + - `Exclude` has been renamed to `GetMempoolTxRequest` + - `Exclude::txid` has been renamed to `GetMempoolTxRequest::exclude_txid_suffixes` - `zcash_client_backend::wallet::OvkPolicy` has been substantially modified to reflect the view that a single outgoing viewing key should be uniformly applied to encrypt all external transaction outputs, irrespective of which @@ -26,7 +41,7 @@ workspace. a single OVK for all shielded outputs irrespective of pools, it now specifies that wallet-internal change outputs should be treated as though the policy for those outputs were `OvkPolicy::None`, rendering them only - recoverable using the wallet's internal IVK. + recoverable using the wallet's internal IVK. - The `OvkPolicy::Custom` variant has changed. Instead of pool-specific OVKs, this now encapsulates a pair of OVKs, one to be used for all shielded external outputs of the transaction, and a second (optional) diff --git a/zcash_client_backend/build.rs b/zcash_client_backend/build.rs index b97699dd06..afc52c3b6b 100644 --- a/zcash_client_backend/build.rs +++ b/zcash_client_backend/build.rs @@ -60,6 +60,14 @@ fn build() -> io::Result<()> { ".cash.z.wallet.sdk.rpc.CompactTx", "crate::proto::compact_formats::CompactTx", ) + .extern_path( + ".cash.z.wallet.sdk.rpc.CompactTxIn", + "crate::proto::compact_formats::CompactTxIn", + ) + .extern_path( + ".cash.z.wallet.sdk.rpc.TxOut", + "crate::proto::compact_formats::TxOut", + ) .extern_path( ".cash.z.wallet.sdk.rpc.CompactSaplingSpend", "crate::proto::compact_formats::CompactSaplingSpend", diff --git a/zcash_client_backend/src/proto/compact_formats.rs b/zcash_client_backend/src/proto/compact_formats.rs index 3cee859467..e0af5156e6 100644 --- a/zcash_client_backend/src/proto/compact_formats.rs +++ b/zcash_client_backend/src/proto/compact_formats.rs @@ -9,12 +9,13 @@ pub struct ChainMetadata { #[prost(uint32, tag = "2")] pub orchard_commitment_tree_size: u32, } -/// A compact representation of the shielded data in a Zcash block. +/// A compact representation of a Zcash block. /// /// CompactBlock is a packaging of ONLY the data from a block that's needed to: /// 1. Detect a payment to your Shielded address /// 2. Detect a spend of your Shielded notes /// 3. Update your witnesses to generate new spend proofs. +/// 4. Spend UTXOs associated to t-addresses of your wallet. #[derive(Clone, PartialEq, ::prost::Message)] pub struct CompactBlock { /// the version of this wire format, for storage @@ -32,7 +33,7 @@ pub struct CompactBlock { /// Unix epoch time when the block was mined #[prost(uint32, tag = "5")] pub time: u32, - /// (hash, prevHash, and time) OR (full header) + /// full header (as returned by the getblock RPC) #[prost(bytes = "vec", tag = "6")] pub header: ::prost::alloc::vec::Vec, /// zero or more compact transactions from this block @@ -42,23 +43,24 @@ pub struct CompactBlock { #[prost(message, optional, tag = "8")] pub chain_metadata: ::core::option::Option, } -/// A compact representation of the shielded data in a Zcash transaction. +/// A compact representation of a Zcash transaction. /// /// CompactTx contains the minimum information for a wallet to know if this transaction -/// is relevant to it (either pays to it or spends from it) via shielded elements -/// only. This message will not encode a transparent-to-transparent transaction. +/// is relevant to it (either pays to it or spends from it) via shielded elements. Additionally, +/// it can optionally include the minimum necessary data to detect payments to transparent addresses +/// related to your wallet. #[derive(Clone, PartialEq, ::prost::Message)] pub struct CompactTx { - /// Index and hash will allow the receiver to call out to chain - /// explorers or other data structures to retrieve more information - /// about this transaction. - /// - /// the index within the full block + /// The index of the transaction within the block. #[prost(uint64, tag = "1")] pub index: u64, - /// the ID (hash) of this transaction, same as in block explorers + /// The id of the transaction as defined in + /// [§ 7.1.1 ‘Transaction Identifiers’]() + /// This byte array MUST be in protocol order and MUST NOT be reversed + /// or hex-encoded; the byte-reversed and hex-encoded representation is + /// exclusively a textual representation of a txid. #[prost(bytes = "vec", tag = "2")] - pub hash: ::prost::alloc::vec::Vec, + pub txid: ::prost::alloc::vec::Vec, /// The transaction fee: present if server can provide. In the case of a /// stateless server and a transaction with transparent inputs, this will be /// unset because the calculation requires reference to prior transactions. @@ -72,6 +74,43 @@ pub struct CompactTx { pub outputs: ::prost::alloc::vec::Vec, #[prost(message, repeated, tag = "6")] pub actions: ::prost::alloc::vec::Vec, + /// `CompactTxIn` values corresponding to the `vin` entries of the full transaction. + /// + /// Note: the single null-outpoint input for coinbase transactions is omitted. Light + /// clients can test `CompactTx.index == 0` to determine whether a `CompactTx` + /// represents a coinbase transaction, as the coinbase transaction is always the + /// first transaction in any block. + #[prost(message, repeated, tag = "7")] + pub vin: ::prost::alloc::vec::Vec, + /// A sequence of transparent outputs being created by the transaction. + #[prost(message, repeated, tag = "8")] + pub vout: ::prost::alloc::vec::Vec, +} +/// A compact representation of a transparent transaction input. +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct CompactTxIn { + /// The id of the transaction that generated the output being spent. This + /// byte array must be in protocol order and MUST NOT be reversed or + /// hex-encoded. + #[prost(bytes = "vec", tag = "1")] + pub prevout_txid: ::prost::alloc::vec::Vec, + /// The index of the output being spent in the `vout` array of the + /// transaction referred to by `prevoutTxid`. + #[prost(uint32, tag = "2")] + pub prevout_index: u32, +} +/// A transparent output being created by the transaction. +/// +/// This contains identical data to the `TxOut` type in the transaction itself, and +/// thus it is not "compact". +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct TxOut { + /// The value of the output, in Zatoshis. + #[prost(uint64, tag = "1")] + pub value: u64, + /// The script pubkey that must be satisfied in order to spend this output. + #[prost(bytes = "vec", tag = "2")] + pub script_pub_key: ::prost::alloc::vec::Vec, } /// A compact representation of a [Sapling Spend](). /// @@ -79,7 +118,7 @@ pub struct CompactTx { /// protocol specification. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct CompactSaplingSpend { - /// nullifier (see the Zcash protocol specification) + /// Nullifier (see the Zcash protocol specification) #[prost(bytes = "vec", tag = "1")] pub nf: ::prost::alloc::vec::Vec, } @@ -89,13 +128,13 @@ pub struct CompactSaplingSpend { /// `encCiphertext` field of a Sapling Output Description. Total size is 116 bytes. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct CompactSaplingOutput { - /// note commitment u-coordinate + /// Note commitment u-coordinate. #[prost(bytes = "vec", tag = "1")] pub cmu: ::prost::alloc::vec::Vec, - /// ephemeral public key + /// Ephemeral public key. #[prost(bytes = "vec", tag = "2")] pub ephemeral_key: ::prost::alloc::vec::Vec, - /// first 52 bytes of ciphertext + /// First 52 bytes of ciphertext. #[prost(bytes = "vec", tag = "3")] pub ciphertext: ::prost::alloc::vec::Vec, } diff --git a/zcash_client_backend/src/proto/service.rs b/zcash_client_backend/src/proto/service.rs index be3930af61..05d6a5ed20 100644 --- a/zcash_client_backend/src/proto/service.rs +++ b/zcash_client_backend/src/proto/service.rs @@ -10,12 +10,22 @@ pub struct BlockId { } /// BlockRange specifies a series of blocks from start to end inclusive. /// Both BlockIDs must be heights; specification by hash is not yet supported. +/// +/// If no pool types are specified, the server should default to the legacy +/// behavior of returning only data relevant to the shielded (Sapling and +/// Orchard) pools; otherwise, the server should prune `CompactBlocks` returned +/// to include only data relevant to the requested pool types. Clients MUST +/// verify that the version of the server they are connected to are capable +/// of returning pruned and/or transparent data before setting `poolTypes` +/// to a non-empty value. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct BlockRange { #[prost(message, optional, tag = "1")] pub start: ::core::option::Option, #[prost(message, optional, tag = "2")] pub end: ::core::option::Option, + #[prost(enumeration = "PoolType", repeated, tag = "3")] + pub pool_types: ::prost::alloc::vec::Vec, } /// A TxFilter contains the information needed to identify a particular /// transaction: either a block and an index, or a direct transaction hash. @@ -123,15 +133,29 @@ pub struct LightdInfo { /// Zcash donation UA address #[prost(string, tag = "15")] pub donation_address: ::prost::alloc::string::String, + /// name of next pending network upgrade, empty if none scheduled + #[prost(string, tag = "16")] + pub upgrade_name: ::prost::alloc::string::String, + /// height of next pending upgrade, zero if none is scheduled + #[prost(uint64, tag = "17")] + pub upgrade_height: u64, + /// version of served by this server + #[prost(string, tag = "18")] + pub lightwallet_protocol_version: ::prost::alloc::string::String, } -/// TransparentAddressBlockFilter restricts the results to the given address -/// or block range. +/// TransparentAddressBlockFilter restricts the results of the GRPC methods that +/// use it to the transactions that involve the given address and were mined in +/// the specified block range. Non-default values for both the address and the +/// block range must be specified. Mempool transactions are not included. +/// +/// The `poolTypes` field of the `range` argument should be ignored. +/// Implementations MAY consider it an error if any pool types are specified. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct TransparentAddressBlockFilter { /// t-address #[prost(string, tag = "1")] pub address: ::prost::alloc::string::String, - /// start, end heights + /// start, end heights only #[prost(message, optional, tag = "2")] pub range: ::core::option::Option, } @@ -168,12 +192,23 @@ pub struct Balance { #[prost(int64, tag = "1")] pub value_zat: i64, } -/// The a shortened transaction ID is the prefix in big-endian (hex) format -/// (then converted to binary). +/// Request parameters for the `GetMempoolTx` RPC. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] -pub struct Exclude { +pub struct GetMempoolTxRequest { + /// A list of transaction ID byte string suffixes that should be excluded + /// from the response. These suffixes may be produced either directly from + /// the underlying txid bytes, or, if the source values are encoded txid + /// strings, by truncating the hexadecimal representation of each + /// transaction ID to an even number of characters, and then hex-decoding + /// and then byte-reversing this value to obtain the byte representation. #[prost(bytes = "vec", repeated, tag = "1")] - pub txid: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + pub exclude_txid_suffixes: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + /// The server must prune `CompactTx`s returned to include only data + /// relevant to the requested pool types. If no pool types are specified, + /// the server should default to the legacy behavior of returning only data + /// relevant to the shielded (Sapling and Orchard) pools. + #[prost(enumeration = "PoolType", repeated, tag = "3")] + pub pool_types: ::prost::alloc::vec::Vec, } /// The TreeState is derived from the Zcash z_gettreestate rpc. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] @@ -253,6 +288,39 @@ pub struct GetAddressUtxosReplyList { #[prost(message, repeated, tag = "1")] pub address_utxos: ::prost::alloc::vec::Vec, } +/// An identifier for a Zcash value pool. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum PoolType { + Invalid = 0, + Transparent = 1, + Sapling = 2, + Orchard = 3, +} +impl PoolType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Invalid => "POOL_TYPE_INVALID", + Self::Transparent => "TRANSPARENT", + Self::Sapling => "SAPLING", + Self::Orchard => "ORCHARD", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "POOL_TYPE_INVALID" => Some(Self::Invalid), + "TRANSPARENT" => Some(Self::Transparent), + "SAPLING" => Some(Self::Sapling), + "ORCHARD" => Some(Self::Orchard), + _ => None, + } + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ShieldedProtocol { @@ -417,7 +485,11 @@ pub mod compact_tx_streamer_client { ); self.inner.unary(req, path, codec).await } - /// Same as GetBlock except actions contain only nullifiers + /// Same as GetBlock except the returned CompactBlock value contains only + /// nullifiers. + /// + /// Note: this method is deprecated. Implementations should ignore any + /// `PoolType::TRANSPARENT` member of the `poolTypes` argument. pub async fn get_block_nullifiers( &mut self, request: impl tonic::IntoRequest, @@ -447,7 +519,11 @@ pub mod compact_tx_streamer_client { ); self.inner.unary(req, path, codec).await } - /// Return a list of consecutive compact blocks + /// Return a list of consecutive compact blocks in the specified range, + /// which is inclusive of `range.end`. + /// + /// If range.start <= range.end, blocks are returned increasing height order; + /// otherwise blocks are returned in decreasing height order. pub async fn get_block_range( &mut self, request: impl tonic::IntoRequest, @@ -479,7 +555,11 @@ pub mod compact_tx_streamer_client { ); self.inner.server_streaming(req, path, codec).await } - /// Same as GetBlockRange except actions contain only nullifiers + /// Same as GetBlockRange except the returned CompactBlock values contain + /// only nullifiers. + /// + /// Note: this method is deprecated. Implementations should ignore any + /// `PoolType::TRANSPARENT` member of the `poolTypes` argument. pub async fn get_block_range_nullifiers( &mut self, request: impl tonic::IntoRequest, @@ -565,8 +645,9 @@ pub mod compact_tx_streamer_client { ); self.inner.unary(req, path, codec).await } - /// Return the transactions corresponding to the given t-address within the given block range - /// NB - this method is misnamed, it returns transactions, not transaction IDs. + /// Return RawTransactions that match the given transparent address filter. + /// + /// Note: This function is misnamed, it returns complete `RawTransaction` values, not TxIds. /// NOTE: this method is deprecated, please use GetTaddressTransactions instead. pub async fn get_taddress_txids( &mut self, @@ -597,7 +678,8 @@ pub mod compact_tx_streamer_client { ); self.inner.server_streaming(req, path, codec).await } - /// Return the transactions corresponding to the given t-address within the given block range + /// Return the transactions corresponding to the given t-address within the given block range. + /// Mempool transactions are not included in the results. pub async fn get_taddress_transactions( &mut self, request: impl tonic::IntoRequest, @@ -679,21 +761,21 @@ pub mod compact_tx_streamer_client { ); self.inner.client_streaming(req, path, codec).await } - /// Return the compact transactions currently in the mempool; the results - /// can be a few seconds out of date. If the Exclude list is empty, return - /// all transactions; otherwise return all *except* those in the Exclude list - /// (if any); this allows the client to avoid receiving transactions that it - /// already has (from an earlier call to this rpc). The transaction IDs in the - /// Exclude list can be shortened to any number of bytes to make the request - /// more bandwidth-efficient; if two or more transactions in the mempool - /// match a shortened txid, they are all sent (none is excluded). Transactions - /// in the exclude list that don't exist in the mempool are ignored. - /// - /// The a shortened transaction ID is the prefix in big-endian (hex) format - /// (then converted to binary). See smoke-test.bash for examples. + /// Returns a stream of the compact transaction representation for transactions + /// currently in the mempool. The results of this operation may be a few + /// seconds out of date. If the `exclude_txid_suffixes` list is empty, + /// return all transactions; otherwise return all *except* those in the + /// `exclude_txid_suffixes` list (if any); this allows the client to avoid + /// receiving transactions that it already has (from an earlier call to this + /// RPC). The transaction IDs in the `exclude_txid_suffixes` list can be + /// shortened to any number of bytes to make the request more + /// bandwidth-efficient; if two or more transactions in the mempool match a + /// txid suffix, none of the matching transactions are excluded. Txid + /// suffixes in the exclude list that don't match any transactions in the + /// mempool are ignored. pub async fn get_mempool_tx( &mut self, - request: impl tonic::IntoRequest, + request: impl tonic::IntoRequest, ) -> std::result::Result< tonic::Response< tonic::codec::Streaming, From 4ee193db62d706c2e6ff3eb7db2a1602cc650f1c Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 8 Dec 2025 14:46:08 -0700 Subject: [PATCH 036/263] zcash_client_backend: Adapt to GRPC API changes after lightwallet-protocol_v0.4.0 update. --- zcash_client_backend/src/data_api/testing.rs | 4 ++-- zcash_client_backend/src/proto.rs | 6 +++--- zcash_client_backend/src/scanning.rs | 4 ++-- zcash_client_backend/src/sync.rs | 1 + .../src/wallet/init/migrations/receiving_key_scopes.rs | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index c2c8731cfc..94ff07dfe9 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -2199,7 +2199,7 @@ fn fake_compact_tx(rng: &mut R) -> CompactTx { let mut ctx = CompactTx::default(); let mut txid = vec![0; 32]; rng.fill_bytes(&mut txid); - ctx.hash = txid; + ctx.txid = txid; ctx } @@ -2294,7 +2294,7 @@ fn fake_compact_block_from_tx( // Create a fake CompactTx containing the transaction. let mut ctx = CompactTx { index: tx_index as u64, - hash: tx.txid().as_ref().to_vec(), + txid: tx.txid().as_ref().to_vec(), ..Default::default() }; diff --git a/zcash_client_backend/src/proto.rs b/zcash_client_backend/src/proto.rs index 5af8aec872..a45045a23d 100644 --- a/zcash_client_backend/src/proto.rs +++ b/zcash_client_backend/src/proto.rs @@ -109,9 +109,9 @@ impl compact_formats::CompactBlock { impl compact_formats::CompactTx { /// Returns the transaction Id pub fn txid(&self) -> TxId { - let mut hash = [0u8; 32]; - hash.copy_from_slice(&self.hash); - TxId::from_bytes(hash) + let mut txid_bytes = [0u8; 32]; + txid_bytes.copy_from_slice(&self.txid); + TxId::from_bytes(txid_bytes) } } diff --git a/zcash_client_backend/src/scanning.rs b/zcash_client_backend/src/scanning.rs index 72141c78d8..9992ce6c69 100644 --- a/zcash_client_backend/src/scanning.rs +++ b/zcash_client_backend/src/scanning.rs @@ -1234,7 +1234,7 @@ pub mod testing { let mut ctx = CompactTx::default(); let mut txid = vec![0; 32]; rng.fill_bytes(&mut txid); - ctx.hash = txid; + ctx.txid = txid; ctx.spends.push(cspend); ctx.outputs.push(cout); ctx @@ -1300,7 +1300,7 @@ pub mod testing { let mut ctx = CompactTx::default(); let mut txid = vec![0; 32]; rng.fill_bytes(&mut txid); - ctx.hash = txid; + ctx.txid = txid; ctx.spends.push(cspend); ctx.outputs.push(cout); ctx.index = cb.vtx.len() as u64; diff --git a/zcash_client_backend/src/sync.rs b/zcash_client_backend/src/sync.rs index c5d35ddc80..20a0260db9 100644 --- a/zcash_client_backend/src/sync.rs +++ b/zcash_client_backend/src/sync.rs @@ -331,6 +331,7 @@ where let range = service::BlockRange { start: Some(start), end: Some(end), + pool_types: vec![], }; let compact_blocks = client .get_block_range(range) diff --git a/zcash_client_sqlite/src/wallet/init/migrations/receiving_key_scopes.rs b/zcash_client_sqlite/src/wallet/init/migrations/receiving_key_scopes.rs index 2a3935b864..1e56825fd6 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations/receiving_key_scopes.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations/receiving_key_scopes.rs @@ -645,7 +645,7 @@ mod tests { let tx = res.transaction(); let mut compact_tx = CompactTx { - hash: tx.txid().as_ref()[..].into(), + txid: tx.txid().as_ref()[..].into(), ..Default::default() }; for output in tx.sapling_bundle().unwrap().shielded_outputs() { From 87f179782eb369ccc89cf3ab030d0baf17feaaaf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 05:02:16 +0000 Subject: [PATCH 037/263] build(deps): bump codecov/codecov-action from 5.5.1 to 5.5.2 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.5.1 to 5.5.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/5a1091511ad55cbe89839c7260b706298ca349f7...671740ac38dd9b0130fbe1cec585b89eea48d3de) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: 5.5.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 468f1c599d..58f61a23e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -508,7 +508,7 @@ jobs: --timeout 600 --out xml - name: Upload coverage to Codecov - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: token: ${{ secrets.CODECOV_TOKEN }} From 8ce6e727cd321f0b7ecf21e10f6af02659ac41b6 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Tue, 9 Dec 2025 17:12:47 -0700 Subject: [PATCH 038/263] zcash_address: Add `ZcashAddress::is_transparent_only` --- components/zcash_address/CHANGELOG.md | 3 +++ components/zcash_address/src/lib.rs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/components/zcash_address/CHANGELOG.md b/components/zcash_address/CHANGELOG.md index c46fa40eb3..bce46086bc 100644 --- a/components/zcash_address/CHANGELOG.md +++ b/components/zcash_address/CHANGELOG.md @@ -10,6 +10,9 @@ workspace. ## [Unreleased] +### Added +- `zcash_address::ZcashAddress::is_transparent_only` + ### Removed - Removed deprecated `zcash_address::Network`, use `zcash_protocol::consensus::Network` instead. diff --git a/components/zcash_address/src/lib.rs b/components/zcash_address/src/lib.rs index 27e99421b7..8237e8540b 100644 --- a/components/zcash_address/src/lib.rs +++ b/components/zcash_address/src/lib.rs @@ -317,6 +317,25 @@ impl ZcashAddress { } } + /// Returns whether the only recognized receivers of this address are transparent protocol + /// receivers. + /// + /// A unified address with unknown receivers may be considered transparent-only if it does not + /// also contain a Sapling or Orchard receiver, i.e. if ordinary transaction construction + /// methods would produce a transaction sending to a transparent address. + pub fn is_transparent_only(&self) -> bool { + use AddressKind::*; + match &self.kind { + Sprout(_) | Sapling(_) => false, + Unified(addr) => { + addr.has_receiver_of_type(PoolType::Transparent) + && !(addr.has_receiver_of_type(PoolType::SAPLING) + || addr.has_receiver_of_type(PoolType::ORCHARD)) + } + P2pkh(_) | P2sh(_) | Tex(_) => true, + } + } + /// Returns whether or not this address contains or corresponds to the given unified address /// receiver. pub fn matches_receiver(&self, receiver: &Receiver) -> bool { From 3ba4199aa4a330283eb34858f2ed0915fe0e9b20 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Tue, 9 Dec 2025 17:20:39 -0700 Subject: [PATCH 039/263] zip321: Make `zip321::Payment::amount` an optional field. Previously, the amount field of the payment would be set to zero if no amount parameter was present; however, this behavior is not specified by ZIP 321. The semantics of this field have now been altered such that if no amount is specified by a payment request, this should be interpreted to mean that the sender of the transaction should specify an amount for the payment. --- components/zip321/CHANGELOG.md | 20 +++++- components/zip321/src/lib.rs | 114 ++++++++++++++++++++++++--------- 2 files changed, 101 insertions(+), 33 deletions(-) diff --git a/components/zip321/CHANGELOG.md b/components/zip321/CHANGELOG.md index 621e712d67..1a89e3d27b 100644 --- a/components/zip321/CHANGELOG.md +++ b/components/zip321/CHANGELOG.md @@ -8,10 +8,28 @@ indicated by the `PLANNED` status in order to make it possible to correctly represent the transitive `semver` implications of changes within the enclosing workspace. -## [Unreleased] +## [0.7.0] - PENDING ### Changed - MSRV is now 1.85.1. +- `zip321::Payment::amount` now returns `Option` instead of `Zatoshis`. + Previously, the amount field of the payment would be set to zero if no amount + parameter was present; however, this behavior is not specified by ZIP 321. + The semantics of this field have now been altered such that if no amount is + specified by a payment request, this should be interpreted to mean that the + sender of the transaction should specify an amount for the payment. +- `zip321::Payment::new` now takes its `amount` parameter as `Option` + instead of `Zatoshis`. It now returns `None` if the payment requests that a + zero-valued output OR a memo be sent to a transparent-only address. +- `zip321::Zip321Error` has added variant `Zip321Error::ZeroValuedTransparentOutput`. + Zero-valued transparent outputs are rejected by the Zcash consensus rules, + and so payments to transparent addresses with the `amount` parameter explicitly + set to zero are now disallowed. +- The return type of `zip321::TransactionRequest::total` has been modified; + it now returns `Ok(None)` if any payment amount is `None`, as the total + is not well-defined in this case. +- `zip321::Zip321Error` has been marked `#[non_exhaustive]` to permit future + semver-compatible additions to the errors that can be identified at parse time. ## [0.6.0] - 2025-10-02 diff --git a/components/zip321/src/lib.rs b/components/zip321/src/lib.rs index 3f1e77bcd9..9e46e95346 100644 --- a/components/zip321/src/lib.rs +++ b/components/zip321/src/lib.rs @@ -25,6 +25,7 @@ use zcash_protocol::{ /// Errors that may be produced in decoding of payment requests. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum Zip321Error { /// A memo field in the ZIP 321 URI was not properly base-64 encoded InvalidBase64(base64::DecodeError), @@ -39,6 +40,9 @@ pub enum Zip321Error { /// The payment at the wrapped index attempted to include a memo when sending to a /// transparent recipient address, which is not supported by the protocol. TransparentMemo(usize), + /// The payment at the wrapped index requested a zero-valued output to a transparent recipient + /// address, which is disallowed by the Zcash consensus rules. + ZeroValuedTransparentOutput(usize), /// The payment at the wrapped index did not include a recipient address. RecipientMissing(usize), /// The ZIP 321 URI was malformed and failed to parse. @@ -75,6 +79,10 @@ impl Display for Zip321Error { f, "Payment {idx} is invalid: cannot send a memo to a transparent recipient address" ), + Zip321Error::ZeroValuedTransparentOutput(idx) => write!( + f, + "Payment {idx} is invalid: zero-valued transparent outputs are disallowed by consensus" + ), Zip321Error::RecipientMissing(idx) => { write!(f, "Payment {idx} is missing its recipient address") } @@ -115,8 +123,8 @@ pub fn memo_from_base64(s: &str) -> Result { pub struct Payment { /// The address to which the payment should be sent. recipient_address: ZcashAddress, - /// The amount of the payment that is being requested. - amount: Zatoshis, + /// The amount of the payment that is being requested, if any. + amount: Option, /// A memo that, if included, must be provided with the payment. /// If a memo is present and [`recipient_address`] is not a shielded /// address, the wallet should report an error. @@ -136,17 +144,34 @@ pub struct Payment { impl Payment { /// Constructs a new [`Payment`] from its constituent parts. /// + /// # Parameters + /// - `recipient_address`: The address to which the payment should be sent. + /// - `amount`: The amount of the payment that is being requested, if any. If no amount is + /// provided, this indicates that the sender of should specify the amount. + /// - `memo`: A memo that, if included, must be provided with the payment. If a memo is present + /// and [`recipient_address`] is not a shielded address, the wallet should report an error. + /// - `label` A human-readable label for this payment (usually identifying information + /// associated with the recipient address) within the larger structure of the transaction + /// request. + /// - `message`: A human-readable message to be displayed to the user describing the + /// purpose of this payment within the larger structure of the transaction request. + /// - `other_params`: A list of other arbitrary key/value pairs associated with this payment. + /// /// Returns `None` if the payment requests that a memo be sent to a recipient that cannot - /// receive a memo. + /// receive a memo or a zero-valued output be sent to a transparent address. pub fn new( recipient_address: ZcashAddress, - amount: Zatoshis, + amount: Option, memo: Option, label: Option, message: Option, other_params: Vec<(String, String)>, ) -> Option { - if memo.is_none() || recipient_address.can_receive_memo() { + if (recipient_address.is_transparent_only() && amount == Some(Zatoshis::ZERO)) + || (memo.is_some() && !recipient_address.can_receive_memo()) + { + None + } else { Some(Self { recipient_address, amount, @@ -155,16 +180,18 @@ impl Payment { message, other_params, }) - } else { - None } } /// Constructs a new [`Payment`] paying the given address the specified amount. + /// + /// # Parameters + /// - `recipient_address`: The address to which the payment should be sent. + /// - `amount`: The amount of the payment that is being requested. pub fn without_memo(recipient_address: ZcashAddress, amount: Zatoshis) -> Self { Self { recipient_address, - amount, + amount: Some(amount), memo: None, label: None, message: None, @@ -178,7 +205,7 @@ impl Payment { } /// Returns the value of the payment that is being requested, in zatoshis. - pub fn amount(&self) -> Zatoshis { + pub fn amount(&self) -> Option { self.amount } @@ -274,14 +301,20 @@ impl TransactionRequest { /// Returns the total value of payments to be made. /// - /// Returns `Err` in the case of overflow, or if the value is - /// outside the range `0..=MAX_MONEY` zatoshis. - pub fn total(&self) -> Result { + /// Returns Ok(None) if any payment does not specify an amount, as the total of the request is + /// not well-defined in this circumstance. + /// + /// Returns `Err` if any summation step results in a value outside the range `0..=MAX_MONEY` + /// zatoshis. + pub fn total(&self) -> Result, BalanceError> { self.payments .values() - .map(|p| p.amount) - .try_fold(Zatoshis::ZERO, |acc, a| { - (acc + a).ok_or(BalanceError::Overflow) + .try_fold(Some(Zatoshis::ZERO), |total_opt, payment| { + if let (Some(total), Some(value)) = (total_opt, payment.amount) { + (total + value).ok_or(BalanceError::Overflow).map(Some) + } else { + Ok(None) + } }) } @@ -312,7 +345,11 @@ impl TransactionRequest { payment_index: Option, ) -> impl IntoIterator + '_ { std::iter::empty() - .chain(Some(render::amount_param(payment.amount, payment_index))) + .chain( + payment + .amount + .map(|a| render::amount_param(a, payment_index)), + ) .chain( payment .memo @@ -599,7 +636,7 @@ mod parse { let mut payment = Payment { recipient_address: *addr.ok_or(Zip321Error::RecipientMissing(i))?, - amount: Zatoshis::ZERO, + amount: None, memo: None, label: None, message: None, @@ -608,7 +645,13 @@ mod parse { for v in vs { match v { - Param::Amount(a) => payment.amount = a, + Param::Amount(a) => { + if payment.recipient_address().is_transparent_only() && a == Zatoshis::ZERO { + return Err(Zip321Error::ZeroValuedTransparentOutput(i)); + } else { + payment.amount = Some(a) + } + } Param::Memo(m) => { if payment.recipient_address.can_receive_memo() { payment.memo = Some(*m); @@ -782,12 +825,13 @@ mod parse { #[cfg(any(test, feature = "test-dependencies"))] pub mod testing { - use proptest::collection::btree_map; - use proptest::collection::vec; + use proptest::collection::{btree_map, vec}; use proptest::option; use proptest::prelude::{any, prop_compose}; + use proptest::strategy::Strategy as _; use zcash_address::testing::arb_address; + use zcash_protocol::value::Zatoshis; use zcash_protocol::{consensus::NetworkType, value::testing::arb_zatoshis}; use super::{MemoBytes, Payment, TransactionRequest}; @@ -801,8 +845,14 @@ pub mod testing { prop_compose! { pub fn arb_zip321_payment(network: NetworkType)( - recipient_address in arb_address(network), - amount in arb_zatoshis(), + (recipient_address, amount) in arb_address(network).prop_flat_map(|addr| { + arb_zatoshis().prop_filter_map( + "zero-valued outputs to transparent addresses are disallowed by consensus", + move |zat| (!addr.is_transparent_only() || zat > Zatoshis::ZERO).then_some( + (addr.clone(), zat) + ) + ) + }), memo in option::of(arb_valid_memo()), message in option::of(any::()), label in option::of(any::()), @@ -816,7 +866,7 @@ pub mod testing { .collect(); Payment { recipient_address, - amount, + amount: Some(amount), memo, label, message, @@ -913,7 +963,7 @@ mod tests { vec![ Payment { recipient_address: ZcashAddress::try_from_encoded("ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap(), - amount: Zatoshis::const_from_u64(376876902796286), + amount: Some(Zatoshis::const_from_u64(376876902796286)), memo: None, label: None, message: Some("".to_string()), @@ -934,7 +984,7 @@ mod tests { vec![ Payment { recipient_address: ZcashAddress::try_from_encoded("ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap(), - amount: Zatoshis::ZERO, + amount: None, memo: None, label: None, message: None, @@ -952,7 +1002,7 @@ mod tests { vec![ Payment { recipient_address: ZcashAddress::try_from_encoded("ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap(), - amount: Zatoshis::ZERO, + amount: Some(Zatoshis::ZERO), memo: None, label: None, message: Some("".to_string()), @@ -996,7 +1046,7 @@ mod tests { let valid_1 = "zcash:ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez?amount=1&memo=VGhpcyBpcyBhIHNpbXBsZSBtZW1vLg&message=Thank%20you%20for%20your%20purchase"; let v1r = TransactionRequest::from_uri(valid_1).unwrap(); assert_eq!( - v1r.payments.get(&0).map(|p| p.amount), + v1r.payments.get(&0).and_then(|p| p.amount), Some(Zatoshis::const_from_u64(100000000)) ); @@ -1004,11 +1054,11 @@ mod tests { let mut v2r = TransactionRequest::from_uri(valid_2).unwrap(); v2r.normalize(); assert_eq!( - v2r.payments.get(&0).map(|p| p.amount), + v2r.payments.get(&0).and_then(|p| p.amount), Some(Zatoshis::const_from_u64(12345600000)) ); assert_eq!( - v2r.payments.get(&1).map(|p| p.amount), + v2r.payments.get(&1).and_then(|p| p.amount), Some(Zatoshis::const_from_u64(78900000)) ); @@ -1017,7 +1067,7 @@ mod tests { let valid_3 = "zcash:ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez?amount=20999999.99999999"; let v3r = TransactionRequest::from_uri(valid_3).unwrap(); assert_eq!( - v3r.payments.get(&0).map(|p| p.amount), + v3r.payments.get(&0).and_then(|p| p.amount), Some(Zatoshis::const_from_u64(2099999999999999)) ); @@ -1026,7 +1076,7 @@ mod tests { let valid_4 = "zcash:ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez?amount=21000000"; let v4r = TransactionRequest::from_uri(valid_4).unwrap(); assert_eq!( - v4r.payments.get(&0).map(|p| p.amount), + v4r.payments.get(&0).and_then(|p| p.amount), Some(Zatoshis::const_from_u64(2100000000000000)) ); } @@ -1036,7 +1086,7 @@ mod tests { let valid_1 = "zcash:zregtestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle7505hlz3?amount=1&memo=VGhpcyBpcyBhIHNpbXBsZSBtZW1vLg&message=Thank%20you%20for%20your%20purchase"; let v1r = TransactionRequest::from_uri(valid_1).unwrap(); assert_eq!( - v1r.payments.get(&0).map(|p| p.amount), + v1r.payments.get(&0).and_then(|p| p.amount), Some(Zatoshis::const_from_u64(100000000)) ); } From a078a78881f13d633ef36dddf52453f8a89c052a Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Tue, 9 Dec 2025 18:48:20 -0700 Subject: [PATCH 040/263] zcash_client_backend: Update to `zip321 0.7` --- zcash_client_backend/CHANGELOG.md | 6 ++- zcash_client_backend/src/data_api/wallet.rs | 17 +++++--- .../src/data_api/wallet/input_selection.rs | 43 +++++++++++++------ zcash_client_backend/src/proposal.rs | 28 ++++++++---- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 7e187f0cf0..3958f36f6c 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -21,9 +21,10 @@ workspace. - `BlockRange` has added field `pool_types` - `LightdInfo` has added fields `upgrade_name`, `upgrade_height`, and `lighwallet_protocol_version` - `GetMempoolTxRequest` (previously named `Exclude`) has added field `pool_types` +- `impl From for zcash_client_backend::data_api::wallet::input_selection::InputSelectorError<...>` ### Changed -- Migrated to `orchard 0.12`, `sapling-crypto 0.6`. +- Migrated to `orchard 0.12`, `sapling-crypto 0.6`, `zip321 0.7` - Migrated to `lightwallet-protocol v0.4.0`. This results in the following API changes: - in `zcash_client_backend::proto::compact_formats`: @@ -48,7 +49,8 @@ workspace. key that will be used to encrypt any wallet-internal change outputs that would otherwise only be recoverable using the wallet's internal IVK. -- `zcash_client_backend::data_api::WalletRead` has added method `get_received_outputs. +- `zcash_client_backend::data_api::WalletRead` has added method `get_received_outputs`. +- `zcash_client_backend::proposal::ProposalError` has added variant `PaymentAmountMissing` ## [0.21.0] - 2025-11-05 diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 9c6adfe76c..b95f400487 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -701,7 +701,7 @@ where let request = zip321::TransactionRequest::new(vec![ Payment::new( to.to_zcash_address(params), - amount, + Some(amount), memo, None, None, @@ -1393,6 +1393,9 @@ where .expect( "The mapping between payment index and payment is checked in step construction", ); + let payment_amount = payment + .amount() + .ok_or(ProposalError::PaymentAmountMissing(payment_index))?; let recipient_address = payment.recipient_address(); let add_sapling_output = @@ -1404,7 +1407,7 @@ where builder.add_sapling_output( external_ovk.map(|k| k.into()), to, - payment.amount(), + payment_amount, memo.clone(), )?; sapling_output_meta.push(( @@ -1412,7 +1415,7 @@ where recipient_address: recipient_address.clone(), output_pool: PoolType::SAPLING, }, - payment.amount(), + payment_amount, Some(memo), )); Ok(()) @@ -1428,7 +1431,7 @@ where builder.add_orchard_output( external_ovk.map(|k| k.into()), to, - payment.amount().into(), + payment_amount.into(), memo.clone(), )?; orchard_output_meta.push(( @@ -1436,7 +1439,7 @@ where recipient_address: recipient_address.clone(), output_pool: PoolType::ORCHARD, }, - payment.amount(), + payment_amount, Some(memo), )); Ok(()) @@ -1450,14 +1453,14 @@ where if payment.memo().is_some() { return Err(Error::MemoForbidden); } - builder.add_transparent_output(&to, payment.amount())?; + builder.add_transparent_output(&to, payment_amount)?; transparent_output_meta.push(( BuildRecipient::External { recipient_address: recipient_address.clone(), output_pool: PoolType::TRANSPARENT, }, to, - payment.amount(), + payment_amount, StepOutputIndex::Payment(payment_index), )); Ok(()) diff --git a/zcash_client_backend/src/data_api/wallet/input_selection.rs b/zcash_client_backend/src/data_api/wallet/input_selection.rs index cf80b2355d..74eab24899 100644 --- a/zcash_client_backend/src/data_api/wallet/input_selection.rs +++ b/zcash_client_backend/src/data_api/wallet/input_selection.rs @@ -150,6 +150,12 @@ impl From> for InputSelectorError { } } +impl From for InputSelectorError { + fn from(err: ProposalError) -> Self { + InputSelectorError::Proposal(err) + } +} + /// A strategy for selecting transaction inputs and proposing transaction outputs. /// /// Proposals should include only economically useful inputs, as determined by `Self::FeeRule`; @@ -414,6 +420,9 @@ impl InputSelector for GreedyInputSelector { let mut total_ephemeral = Zatoshis::ZERO; for (idx, payment) in transaction_request.payments() { + let payment_amount = payment + .amount() + .ok_or(ProposalError::PaymentAmountMissing(*idx))?; let recipient_address: Address = payment .recipient_address() .clone() @@ -422,7 +431,7 @@ impl InputSelector for GreedyInputSelector { match recipient_address { Address::Transparent(addr) => { payment_pools.insert(*idx, PoolType::TRANSPARENT); - transparent_outputs.push(TxOut::new(payment.amount(), addr.script().into())); + transparent_outputs.push(TxOut::new(payment_amount, addr.script().into())); } #[cfg(feature = "transparent-inputs")] Address::Tex(data) => { @@ -430,7 +439,7 @@ impl InputSelector for GreedyInputSelector { tr1_payment_pools.insert(*idx, PoolType::TRANSPARENT); tr1_transparent_outputs - .push(TxOut::new(payment.amount(), p2pkh_addr.script().into())); + .push(TxOut::new(payment_amount, p2pkh_addr.script().into())); tr1_payments.push( Payment::new( payment.recipient_address().clone(), @@ -442,7 +451,7 @@ impl InputSelector for GreedyInputSelector { ) .expect("cannot fail because memo is None"), ); - total_ephemeral = (total_ephemeral + payment.amount()) + total_ephemeral = (total_ephemeral + payment_amount) .ok_or(GreedyInputSelectorError::Balance(BalanceError::Overflow))?; } #[cfg(not(feature = "transparent-inputs"))] @@ -453,26 +462,25 @@ impl InputSelector for GreedyInputSelector { } Address::Sapling(_) => { payment_pools.insert(*idx, PoolType::SAPLING); - sapling_outputs.push(SaplingPayment(payment.amount())); + sapling_outputs.push(SaplingPayment(payment_amount)); } Address::Unified(addr) => { #[cfg(feature = "orchard")] if addr.has_orchard() { payment_pools.insert(*idx, PoolType::ORCHARD); - orchard_outputs.push(OrchardPayment(payment.amount())); + orchard_outputs.push(OrchardPayment(payment_amount)); continue; } if addr.has_sapling() { payment_pools.insert(*idx, PoolType::SAPLING); - sapling_outputs.push(SaplingPayment(payment.amount())); + sapling_outputs.push(SaplingPayment(payment_amount)); continue; } if let Some(addr) = addr.transparent() { payment_pools.insert(*idx, PoolType::TRANSPARENT); - transparent_outputs - .push(TxOut::new(payment.amount(), addr.script().into())); + transparent_outputs.push(TxOut::new(payment_amount, addr.script().into())); continue; } @@ -879,12 +887,19 @@ where let tr0_balance = TransactionBalance::new(tr0_change, tr0_fee) .expect("the sum of an single-element vector of fee values cannot overflow"); - let payment = zip321::Payment::new(recipient, total_to_recipient, memo, None, None, vec![]) - .ok_or_else(|| { - InputSelectorError::Proposal(ProposalError::Zip321( - zip321::Zip321Error::TransparentMemo(0), - )) - })?; + let payment = zip321::Payment::new( + recipient, + Some(total_to_recipient), + memo, + None, + None, + vec![], + ) + .ok_or_else(|| { + InputSelectorError::Proposal(ProposalError::Zip321(zip321::Zip321Error::TransparentMemo( + 0, + ))) + })?; let transaction_request = TransactionRequest::new(vec![payment.clone()]).map_err(|payment_error| { diff --git a/zcash_client_backend/src/proposal.rs b/zcash_client_backend/src/proposal.rs index 8288fb5136..e8b334b6a2 100644 --- a/zcash_client_backend/src/proposal.rs +++ b/zcash_client_backend/src/proposal.rs @@ -51,6 +51,8 @@ pub enum ProposalError { SpendsChange(StepOutput), /// The proposal results in an invalid payment request according to ZIP-321. Zip321(Zip321Error), + /// The ZIP 321 payment request at the wrapped index lacked payment amount information. + PaymentAmountMissing(usize), /// A proposal step created an ephemeral output that was not spent in any later step. #[cfg(feature = "transparent-inputs")] EphemeralOutputLeftUnspent(StepOutput), @@ -116,6 +118,12 @@ impl Display for ProposalError { ProposalError::Zip321(r) => { write!(f, "The proposal results in an invalid payment {r:?}.",) } + ProposalError::PaymentAmountMissing(idx) => { + write!( + f, + "Payment amount not specified for requested payment at index {idx}." + ) + } #[cfg(feature = "transparent-inputs")] ProposalError::EphemeralOutputLeftUnspent(r) => write!( f, @@ -419,12 +427,14 @@ impl Step { return Err(ProposalError::PaymentPoolsMismatch); } for (idx, pool) in &payment_pools { - if !transaction_request - .payments() - .get(idx) - .iter() - .any(|payment| payment.recipient_address().can_receive_as(*pool)) - { + if let Some(payment) = transaction_request.payments().get(idx) { + if !payment.recipient_address().can_receive_as(*pool) { + return Err(ProposalError::PaymentPoolsMismatch); + } + if payment.amount().is_none() { + return Err(ProposalError::PaymentAmountMissing(*idx)); + } + } else { return Err(ProposalError::PaymentPoolsMismatch); } } @@ -455,7 +465,8 @@ impl Step { .payments() .get(&i) .ok_or(ProposalError::ReferenceError(*s_ref))? - .amount(), + .amount() + .ok_or(ProposalError::PaymentAmountMissing(i))?, StepOutputIndex::Change(i) => step .balance .proposed_change() @@ -474,7 +485,8 @@ impl Step { let request_total = transaction_request .total() - .map_err(|_| ProposalError::RequestTotalInvalid)?; + .map_err(|_| ProposalError::RequestTotalInvalid)? + .expect("all payments previously checked to have amount values"); let output_total = (request_total + balance.total()).ok_or(ProposalError::Overflow)?; if is_shielding From 99d3ae4a38615c38842501d583a377dd77d1e6c2 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 10 Dec 2025 12:52:07 -0700 Subject: [PATCH 041/263] cargo vet updates following the `zcash_protocol-0.7.1` release. --- supply-chain/audits.toml | 6 +-- supply-chain/config.toml | 20 --------- supply-chain/imports.lock | 92 +++++++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 47 deletions(-) diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index befb6c1cb9..8787f8bbb7 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1170,7 +1170,7 @@ end = "2025-04-22" criteria = "safe-to-deploy" user-id = 169181 # Kris Nuttycombe (nuttycom) start = "2024-08-20" -end = "2025-08-26" +end = "2026-12-10" [[trusted.zcash_client_backend]] criteria = "safe-to-deploy" @@ -1260,7 +1260,7 @@ end = "2026-09-25" criteria = "safe-to-deploy" user-id = 169181 # Kris Nuttycombe (nuttycom) start = "2024-08-20" -end = "2025-08-26" +end = "2026-12-10" [[trusted.zcash_primitives]] criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"] @@ -1284,7 +1284,7 @@ end = "2026-09-25" criteria = "safe-to-deploy" user-id = 169181 # Kris Nuttycombe (nuttycom) start = "2024-08-20" -end = "2025-08-26" +end = "2026-12-10" [[trusted.zcash_proofs]] criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"] diff --git a/supply-chain/config.toml b/supply-chain/config.toml index 66f085a495..672a64131a 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -167,10 +167,6 @@ criteria = "safe-to-deploy" version = "1.0.3" criteria = "safe-to-deploy" -[[exemptions.atomic-waker]] -version = "1.1.2" -criteria = "safe-to-deploy" - [[exemptions.backtrace]] version = "0.3.69" criteria = "safe-to-deploy" @@ -223,10 +219,6 @@ criteria = "safe-to-deploy" version = "0.8.0" criteria = "safe-to-deploy" -[[exemptions.bounded-vec]] -version = "0.9.0" -criteria = "safe-to-deploy" - [[exemptions.bounded-vec-deque]] version = "0.1.1" criteria = "safe-to-deploy" @@ -475,10 +467,6 @@ criteria = "safe-to-deploy" version = "0.13.8" criteria = "safe-to-deploy" -[[exemptions.embedded-io]] -version = "0.6.1" -criteria = "safe-to-deploy" - [[exemptions.enum-ordinalize]] version = "3.1.15" criteria = "safe-to-deploy" @@ -527,10 +515,6 @@ criteria = "safe-to-run" version = "0.8.0" criteria = "safe-to-deploy" -[[exemptions.fixedbitset]] -version = "0.4.2" -criteria = "safe-to-deploy" - [[exemptions.fluid-let]] version = "1.0.0" criteria = "safe-to-deploy" @@ -1443,10 +1427,6 @@ criteria = "safe-to-deploy" version = "0.1.27" criteria = "safe-to-deploy" -[[exemptions.tracing-log]] -version = "0.2.0" -criteria = "safe-to-deploy" - [[exemptions.tracing-test]] version = "0.2.5" criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 4909ef1325..9016420f6d 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -288,8 +288,8 @@ user-login = "str4d" user-name = "Jack Grigg" [[publisher.zcash_address]] -version = "0.9.0" -when = "2025-07-31" +version = "0.10.1" +when = "2025-10-20" user-id = 169181 user-login = "nuttycom" user-name = "Kris Nuttycombe" @@ -337,25 +337,25 @@ user-login = "str4d" user-name = "Jack Grigg" [[publisher.zcash_primitives]] -version = "0.25.0" -when = "2025-09-25" -user-id = 6289 -user-login = "str4d" -user-name = "Jack Grigg" +version = "0.26.1" +when = "2025-10-20" +user-id = 169181 +user-login = "nuttycom" +user-name = "Kris Nuttycombe" [[publisher.zcash_proofs]] -version = "0.25.0" -when = "2025-09-25" -user-id = 6289 -user-login = "str4d" -user-name = "Jack Grigg" +version = "0.26.1" +when = "2025-10-20" +user-id = 169181 +user-login = "nuttycom" +user-name = "Kris Nuttycombe" [[publisher.zcash_protocol]] -version = "0.6.2" -when = "2025-09-25" -user-id = 6289 -user-login = "str4d" -user-name = "Jack Grigg" +version = "0.7.1" +when = "2025-10-20" +user-id = 169181 +user-login = "nuttycom" +user-name = "Kris Nuttycombe" [[publisher.zcash_script]] version = "0.4.0" @@ -372,11 +372,11 @@ user-login = "daira" user-name = "Daira-Emma Hopwood" [[publisher.zcash_transparent]] -version = "0.5.0" -when = "2025-09-25" -user-id = 6289 -user-login = "str4d" -user-name = "Jack Grigg" +version = "0.6.0" +when = "2025-10-02" +user-id = 169181 +user-login = "nuttycom" +user-name = "Kris Nuttycombe" [[publisher.zip32]] version = "0.2.0" @@ -386,8 +386,8 @@ user-login = "nuttycom" user-name = "Kris Nuttycombe" [[publisher.zip321]] -version = "0.5.0" -when = "2025-07-31" +version = "0.6.0" +when = "2025-10-02" user-id = 169181 user-login = "nuttycom" user-name = "Kris Nuttycombe" @@ -425,6 +425,12 @@ Unsafe code, but its logic looks good to me. Necessary given what it is doing. Well tested, has quickchecks. """ +[[audits.bytecode-alliance.audits.atomic-waker]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "1.1.2" +notes = "Contains `unsafe` code but it's well-documented and scoped to what it's intended to be doing. Otherwise a well-focused and straightforward crate." + [[audits.bytecode-alliance.audits.base64]] who = "Pat Hickey " criteria = "safe-to-deploy" @@ -512,6 +518,12 @@ criteria = "safe-to-deploy" version = "0.4.0" notes = "No `unsafe` code and only uses `std` in ways one would expect the crate to do so." +[[audits.bytecode-alliance.audits.embedded-io]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.6.1" +notes = "Major updates, but almost all safe code. Lots of pruning/deletions, nothing out of the ordrinary." + [[audits.bytecode-alliance.audits.errno]] who = "Dan Gohman " criteria = "safe-to-deploy" @@ -543,6 +555,16 @@ This update had a few doc updates but no otherwise-substantial source code updates. """ +[[audits.bytecode-alliance.audits.fixedbitset]] +who = "Nick Fitzgerald " +criteria = "safe-to-deploy" +version = "0.4.2" +notes = """ +No ambient I/O. Uses some `unsafe`, but the uses look good and are guarded by +relevant assertions, although could use some comments and some slight +refactoring into helpers to dedupe unsafe blocks in my personal opinion. +""" + [[audits.bytecode-alliance.audits.futures-channel]] who = "Joel Dice " criteria = "safe-to-deploy" @@ -792,6 +814,21 @@ without `unsafe`. Skimming the crate everything looks reasonable and what one would expect from idiomatic safe collections in Rust. """ +[[audits.bytecode-alliance.audits.tracing-log]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.1.3" +notes = """ +This is a standard adapter between the `log` ecosystem and the `tracing` +ecosystem. There's one `unsafe` block in this crate and it's well-scoped. +""" + +[[audits.bytecode-alliance.audits.tracing-log]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.3 -> 0.2.0" +notes = "Nothing out of the ordinary, a typical major version update and nothing awry." + [[audits.bytecode-alliance.audits.tracing-subscriber]] who = "Pat Hickey " criteria = "safe-to-deploy" @@ -2914,6 +2951,13 @@ delta = "0.10.3 -> 0.10.4" notes = "Adds panics to prevent a block size of zero from causing unsoundness." aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" +[[audits.zcash.audits.bounded-vec]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +version = "0.9.0" +notes = "Crate forbids unsafe code and uses no powerful imports. It consists primarily of safe constructors for newtype wrappers around `Vec`." +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + [[audits.zcash.audits.bs58]] who = "Daira-Emma Hopwood " criteria = "safe-to-deploy" From 84895d29109aa2caedc3e6f0987f17988028467f Mon Sep 17 00:00:00 2001 From: Marek Date: Sun, 30 Nov 2025 21:45:16 +0100 Subject: [PATCH 042/263] zcash_protocol: Add `TxId::NULL` Co-authored-by: Kris Nuttycombe Co-authored-by: Jack Grigg --- components/zcash_protocol/CHANGELOG.md | 3 +++ components/zcash_protocol/src/txid.rs | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/components/zcash_protocol/CHANGELOG.md b/components/zcash_protocol/CHANGELOG.md index 29ef6458cb..e193a6c37e 100644 --- a/components/zcash_protocol/CHANGELOG.md +++ b/components/zcash_protocol/CHANGELOG.md @@ -10,6 +10,9 @@ workspace. ## [Unreleased] +### Added +- `zcash_protocol::txid::TxId::NULL` + ## [0.7.1] - 2025-10-18 ### Fixed diff --git a/components/zcash_protocol/src/txid.rs b/components/zcash_protocol/src/txid.rs index ddbbfefd9f..ee76c71a35 100644 --- a/components/zcash_protocol/src/txid.rs +++ b/components/zcash_protocol/src/txid.rs @@ -48,6 +48,10 @@ impl From for [u8; 32] { } impl TxId { + /// The all-zeros txid. This is reserved as the txid of the transparent input to a coinbase + /// transaction. + pub const NULL: TxId = TxId([0u8; 32]); + /// Wraps the given byte array as a TxId value pub const fn from_bytes(bytes: [u8; 32]) -> Self { TxId(bytes) @@ -66,9 +70,9 @@ impl TxId { Ok(()) } - /// Returns true when the txid consists of all zeros; this only occurs for coinbase - /// transactions. + /// Returns true when the txid consists of all zeros, indicating the input + /// to a coinbase transaction. pub fn is_null(&self) -> bool { - self.0 == [0u8; 32] + *self == Self::NULL } } From 278a8423a06672343910f17be1570b51e2e722bd Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 10 Dec 2025 11:57:02 -0700 Subject: [PATCH 043/263] Release zcash_protocol version 0.7.2 --- Cargo.lock | 2 +- components/zcash_protocol/CHANGELOG.md | 2 ++ components/zcash_protocol/Cargo.toml | 2 +- supply-chain/imports.lock | 4 ++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f21675477..d67512108f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6705,7 +6705,7 @@ dependencies = [ [[package]] name = "zcash_protocol" -version = "0.7.1" +version = "0.7.2" dependencies = [ "core2", "document-features", diff --git a/components/zcash_protocol/CHANGELOG.md b/components/zcash_protocol/CHANGELOG.md index e193a6c37e..156f0bf669 100644 --- a/components/zcash_protocol/CHANGELOG.md +++ b/components/zcash_protocol/CHANGELOG.md @@ -10,6 +10,8 @@ workspace. ## [Unreleased] +## [0.7.2] - 2025-12-10 + ### Added - `zcash_protocol::txid::TxId::NULL` diff --git a/components/zcash_protocol/Cargo.toml b/components/zcash_protocol/Cargo.toml index e13774d795..83cc6712ed 100644 --- a/components/zcash_protocol/Cargo.toml +++ b/components/zcash_protocol/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zcash_protocol" description = "Zcash protocol network constants and value types." -version = "0.7.1" +version = "0.7.2" authors = [ "Jack Grigg ", "Kris Nuttycombe ", diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 9016420f6d..c371cc769b 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1,6 +1,10 @@ # cargo-vet imports lock +[[unpublished.zcash_protocol]] +version = "0.7.2" +audited_as = "0.7.1" + [[publisher.bumpalo]] version = "3.16.0" when = "2024-04-08" From 98a4f576ac0cb15b1b4945383be950b8b5dc021a Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 11 Dec 2025 12:35:44 -0700 Subject: [PATCH 044/263] Post-release `cargo vet` update. --- supply-chain/imports.lock | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index c371cc769b..75f9e08439 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1,10 +1,6 @@ # cargo-vet imports lock -[[unpublished.zcash_protocol]] -version = "0.7.2" -audited_as = "0.7.1" - [[publisher.bumpalo]] version = "3.16.0" when = "2024-04-08" @@ -355,8 +351,8 @@ user-login = "nuttycom" user-name = "Kris Nuttycombe" [[publisher.zcash_protocol]] -version = "0.7.1" -when = "2025-10-20" +version = "0.7.2" +when = "2025-12-11" user-id = 169181 user-login = "nuttycom" user-name = "Kris Nuttycombe" From 5e4082378a3ab8211b86adeeadc3555bacb2a560 Mon Sep 17 00:00:00 2001 From: Marek Date: Sun, 30 Nov 2025 21:45:16 +0100 Subject: [PATCH 045/263] zcash_transparent: Construct null outpoints Co-authored-by: Kris Nuttycombe Co-authored-by: Jack Grigg --- Cargo.toml | 2 +- zcash_transparent/CHANGELOG.md | 3 +++ zcash_transparent/src/bundle.rs | 14 ++++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e1203b94a5..05382c434e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ zcash_address = { version = "0.10", path = "components/zcash_address", default-f zcash_client_backend = { version = "0.20", path = "zcash_client_backend" } zcash_encoding = { version = "0.3", path = "components/zcash_encoding", default-features = false } zcash_keys = { version = "0.11", path = "zcash_keys" } -zcash_protocol = { version = "0.7", path = "components/zcash_protocol", default-features = false } +zcash_protocol = { version = "0.7.2", path = "components/zcash_protocol", default-features = false } zip321 = { version = "0.6", path = "components/zip321" } zcash_note_encryption = "0.4.1" diff --git a/zcash_transparent/CHANGELOG.md b/zcash_transparent/CHANGELOG.md index dd5077e0cb..adf9e6eeb9 100644 --- a/zcash_transparent/CHANGELOG.md +++ b/zcash_transparent/CHANGELOG.md @@ -10,6 +10,9 @@ workspace. ## [Unreleased] +### Added +- `zcash_transparent::bundle::Outpoint::NULL` + ## [0.6.1] - 2025-10-27 ### Added diff --git a/zcash_transparent/src/bundle.rs b/zcash_transparent/src/bundle.rs index 83c180bfbc..3501f926a5 100644 --- a/zcash_transparent/src/bundle.rs +++ b/zcash_transparent/src/bundle.rs @@ -146,9 +146,17 @@ pub struct OutPoint { } impl OutPoint { + /// Returns the null [`OutPoint`] in the Bitcoin sense: + /// - [`TxId`] is set to all-zeroes, and + /// - output index is set to [`u32::MAX`]. + pub const NULL: OutPoint = OutPoint { + hash: TxId::NULL, + n: u32::MAX, + }; + /// Constructs an `OutPoint` for the output at index `n` in the transaction /// with txid `hash`. - pub fn new(hash: [u8; 32], n: u32) -> Self { + pub const fn new(hash: [u8; 32], n: u32) -> Self { OutPoint { hash: TxId::from_bytes(hash), n, @@ -180,9 +188,7 @@ impl OutPoint { /// Returns `true` if this `OutPoint` is "null" in the Bitcoin sense: it has txid set to /// all-zeroes and output index set to `u32::MAX`. fn is_null(&self) -> bool { - // From `BaseOutPoint::IsNull()` in zcashd: - // return (hash.IsNull() && n == (uint32_t) -1); - self.hash.is_null() && self.n == u32::MAX + *self == Self::NULL } /// Returns the output index of this `OutPoint`. From b0ca95e25bf568c6583d91544771bdbc4713c5b5 Mon Sep 17 00:00:00 2001 From: Marek Date: Sun, 30 Nov 2025 21:45:54 +0100 Subject: [PATCH 046/263] zcash_transparent: Construct coinbase inputs Co-authored-by: Kris Nuttycombe Co-authored-by: Greg Pfeil Co-authored-by: Jack Grigg Co-authored-by: Daira-Emma Hopwood --- zcash_transparent/CHANGELOG.md | 9 ++- zcash_transparent/src/builder.rs | 8 +++ zcash_transparent/src/bundle.rs | 94 ++++++++++++++++++++++++++++++- zcash_transparent/src/coinbase.rs | 59 +++++++++++++++++++ zcash_transparent/src/lib.rs | 4 ++ 5 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 zcash_transparent/src/coinbase.rs diff --git a/zcash_transparent/CHANGELOG.md b/zcash_transparent/CHANGELOG.md index adf9e6eeb9..1a45c35235 100644 --- a/zcash_transparent/CHANGELOG.md +++ b/zcash_transparent/CHANGELOG.md @@ -11,7 +11,14 @@ workspace. ## [Unreleased] ### Added -- `zcash_transparent::bundle::Outpoint::NULL` +- `zcash_transparent`: + - `builder`: + - `Coinbase` marker type + - `impl Authorization for Coinbase` + - `bundle`: + - `Outpoint::NULL` + - `TxIn::::coinbase` + - `coinbase` module, containing helpers for constructing coinbase transactions. ## [0.6.1] - 2025-10-27 diff --git a/zcash_transparent/src/builder.rs b/zcash_transparent/src/builder.rs index 1968bd629b..1aacd1e95c 100644 --- a/zcash_transparent/src/builder.rs +++ b/zcash_transparent/src/builder.rs @@ -239,6 +239,14 @@ pub struct TransparentSignatureContext<'a, V: secp256k1::Verification = secp256k final_script_sigs: Vec>, } +/// [`Authorization`] marker type for coinbase transactions without authorization data. +#[derive(Debug, Clone)] +pub struct Coinbase; + +impl Authorization for Coinbase { + type ScriptSig = script::Sig; +} + impl TransparentBuilder { /// Constructs a new TransparentBuilder pub fn empty() -> Self { diff --git a/zcash_transparent/src/bundle.rs b/zcash_transparent/src/bundle.rs index 3501f926a5..f7fc7d4f9c 100644 --- a/zcash_transparent/src/bundle.rs +++ b/zcash_transparent/src/bundle.rs @@ -3,15 +3,22 @@ use alloc::vec::Vec; use core::fmt::Debug; use core2::io::{self, Read, Write}; -use zcash_script::script; +use zcash_script::{ + opcode::{Evaluable as _, PushValue}, + pattern::push_num, + pv, + script::{self, Evaluable as _}, +}; use zcash_protocol::{ + consensus::BlockHeight, value::{BalanceError, ZatBalance, Zatoshis}, TxId, }; use crate::{ address::{Script, TransparentAddress}, + builder, coinbase, sighash::TransparentAuthorizingContext, }; @@ -264,6 +271,91 @@ impl TxIn { } } +impl TxIn { + /// Creates an input for a coinbase transaction. + /// + /// - Does not support creating inputs for the genesis block. + /// - The `miner_data` parameter can carry arbitrary data, which will be included in the input's + /// `script_sig` field, as long as the field's length stays within + /// [`coinbase::MAX_COINBASE_SCRIPT_LEN`] bytes. + pub fn coinbase( + height: BlockHeight, + miner_data: Option, + ) -> Result { + let h = match i64::from(height) { + 0 => Err(coinbase::Error::GenesisInputNotSupported), + h => Ok(push_num(h)), + }?; + + let h_len = h.byte_len(); + assert!(h_len > 0); + + // # Consensus + // + // > A coinbase transaction for a block at block height greater than 0 MUST have a script + // > that, as its first item, encodes the block height `height` as follows. For `height` in + // > the range {1 .. 16}, the encoding is a single byte of value `0x50` + `height`. + // > Otherwise, let `heightBytes` be the signed little-endian representation of `height`, + // > using the minimum nonzero number of bytes such that the most significant byte is < + // > `0x80`. The length of `heightBytes` MUST be in the range {1 .. 5}. Then the encoding is + // > the length of `heightBytes` encoded as one byte, followed by `heightBytes` itself. This + // > matches the encoding used by Bitcoin in the implementation of [BIP-34] (but the + // > description here is to be considered normative). + // + // + // + // ## Note + // + // The height is encoded in `push_num`, which always returns an opcode, and every opcode + // serializes to at least one byte, so we assert the lower bound. + // + // [BIP-34]: + if h_len > coinbase::MAX_COINBASE_HEIGHT_LEN { + return Err(coinbase::Error::OversizedHeight); + } + + let script_sig = script::Component( + [ + Some(h), + // Consensus rule: coinbase script must be at least 2 bytes. + (h_len < coinbase::MIN_COINBASE_SCRIPT_LEN && miner_data.is_none()) + .then_some(pv::_0), + miner_data, + ] + .into_iter() + .flatten() + .collect(), + ); + + let s_len = script_sig.byte_len(); + assert!(s_len >= coinbase::MIN_COINBASE_SCRIPT_LEN); + + // # Consensus + // + // > A coinbase transaction script MUST have length in {2 .. 100} bytes. + // + // + // + // ## Note + // + // The `miner_data` param always contains an opcode, and every opcode serializes to at least + // one byte, so we assert the lower bound. + if s_len > coinbase::MAX_COINBASE_SCRIPT_LEN { + return Err(coinbase::Error::OversizedScript); + } + + // We set the `prevout` argument to [`OutPoint::NULL`] since [§ 3.11] defines coinbase txs + // as those that have a single transparent input with a null `prevout` field. + // + // We set the `sequence` field to [`u32::MAX`] to disable time-locking, as described in the + // [Bitcoin Developer Reference]. + // + // [§ 3.11]: + // [Bitcoin Developer Reference]: + Ok(TxIn::from_parts(OutPoint::NULL, script_sig, u32::MAX)) + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct TxOut { #[deprecated(since = "0.4.1", note = "use the value() accessor instead.")] diff --git a/zcash_transparent/src/coinbase.rs b/zcash_transparent/src/coinbase.rs new file mode 100644 index 0000000000..4a8fdefb49 --- /dev/null +++ b/zcash_transparent/src/coinbase.rs @@ -0,0 +1,59 @@ +//! Types, constants, and functions related to coinbase transactions. + +use alloc::fmt; + +/// The minimum length of the coinbase transaction script. +/// +/// [§ 7.1.2](https://zips.z.cash/protocol/protocol.pdf#txnconsensus) specifies: +/// +/// > A coinbase transaction script MUST have length in {2 .. 100} bytes. +pub const MIN_COINBASE_SCRIPT_LEN: usize = 2; + +/// The maximum length of the coinbase transaction script. +/// +/// [§ 7.1.2](https://zips.z.cash/protocol/protocol.pdf#txnconsensus) specifies: +/// +/// > A coinbase transaction script MUST have length in {2 .. 100} bytes. +pub const MAX_COINBASE_SCRIPT_LEN: usize = 100; + +/// The maximum length of the encoded height in the coinbase transaction script. +/// +/// [§ 7.1.2](https://zips.z.cash/protocol/protocol.pdf#txnconsensus) specifies: +/// +/// > The length of `heightBytes` MUST be in the range {1 .. 5}. Then the encoding is the length of +/// > `heightBytes` encoded as one byte, followed by `heightBytes` itself. +pub const MAX_COINBASE_HEIGHT_LEN: usize = 6; + +/// Errors related to coinbase transactions. +#[derive(Clone, Debug)] +#[non_exhaustive] +pub enum Error { + /// Encoded coinbase script exceeds [`MAX_COINBASE_SCRIPT_LEN`]. + OversizedScript, + /// Encoded block height exceeds [`MAX_COINBASE_HEIGHT_LEN`]. + OversizedHeight, + /// Creating a coinbase input for the genesis block is not supported. + GenesisInputNotSupported, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::OversizedScript => write!( + f, + "encoded coinbase script exceeds the limit of {MAX_COINBASE_SCRIPT_LEN} bytes", + ), + Error::OversizedHeight => write!( + f, + "encoded block height exceeds the limit of {MAX_COINBASE_HEIGHT_LEN} bytes", + ), + Error::GenesisInputNotSupported => write!( + f, + "creating a coinbase input for the genesis block is not supported", + ), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error {} diff --git a/zcash_transparent/src/lib.rs b/zcash_transparent/src/lib.rs index 0b55c47e3f..05eb5c35e3 100644 --- a/zcash_transparent/src/lib.rs +++ b/zcash_transparent/src/lib.rs @@ -6,9 +6,13 @@ #![no_std] +#[cfg(feature = "std")] +extern crate std; + pub mod address; pub mod builder; pub mod bundle; +pub mod coinbase; pub mod keys; pub mod pczt; pub mod sighash; From c5540ba96d8801420cc25f451c0204b0fdcf9c6b Mon Sep 17 00:00:00 2001 From: Marek Date: Sun, 30 Nov 2025 21:46:15 +0100 Subject: [PATCH 047/263] zcash_transparent: Impl `TransparentAuthorizingContext` for `Coinbase` --- zcash_transparent/CHANGELOG.md | 1 + zcash_transparent/src/builder.rs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/zcash_transparent/CHANGELOG.md b/zcash_transparent/CHANGELOG.md index 1a45c35235..6b8a058e3a 100644 --- a/zcash_transparent/CHANGELOG.md +++ b/zcash_transparent/CHANGELOG.md @@ -15,6 +15,7 @@ workspace. - `builder`: - `Coinbase` marker type - `impl Authorization for Coinbase` + - `impl TransparentAuthorizingContext for Coinbase` - `bundle`: - `Outpoint::NULL` - `TxIn::::coinbase` diff --git a/zcash_transparent/src/builder.rs b/zcash_transparent/src/builder.rs index 1aacd1e95c..6bcebd3c64 100644 --- a/zcash_transparent/src/builder.rs +++ b/zcash_transparent/src/builder.rs @@ -247,6 +247,16 @@ impl Authorization for Coinbase { type ScriptSig = script::Sig; } +impl TransparentAuthorizingContext for Coinbase { + fn input_amounts(&self) -> Vec { + vec![] + } + + fn input_scriptpubkeys(&self) -> Vec