From 43b5e506e4f24fc07904a7adc7362f3f7c982f46 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Mon, 29 Jul 2024 10:13:56 +0200 Subject: [PATCH 01/46] Prepare to use Orchard ZSA --- Cargo.lock | 344 +++++++++++++++++++++++++++++++++++------ zebra-chain/Cargo.toml | 18 ++- 2 files changed, 309 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea09e646716..0e3ac5e59dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.11.0" @@ -1035,6 +1041,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1180,6 +1198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -1220,6 +1239,20 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "ed25519" version = "2.2.3" @@ -1273,6 +1306,25 @@ dependencies = [ "void", ] +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1298,6 +1350,14 @@ dependencies = [ "regex", ] +[[package]] +name = "equihash" +version = "0.2.0" +dependencies = [ + "blake2b_simd", + "byteorder", +] + [[package]] name = "equihash" version = "0.2.0" @@ -1334,6 +1394,13 @@ dependencies = [ "once_cell", ] +[[package]] +name = "f4jumble" +version = "0.1.0" +dependencies = [ + "blake2b_simd", +] + [[package]] name = "f4jumble" version = "0.1.0" @@ -1548,6 +1615,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1664,11 +1732,10 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" dependencies = [ - "cfg-if 1.0.0", "crunchy", ] @@ -1682,7 +1749,24 @@ dependencies = [ "bitvec", "ff", "group", - "halo2_proofs", + "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "pasta_curves", + "rand 0.8.5", + "subtle", + "uint", +] + +[[package]] +name = "halo2_gadgets" +version = "0.3.0" +source = "git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11#7f5c0babd61f8ca46c9165a1adfac298d3fd3a11" +dependencies = [ + "arrayvec", + "bitvec", + "ff", + "group", + "halo2_proofs 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", "lazy_static", "pasta_curves", "rand 0.8.5", @@ -1712,6 +1796,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "halo2_proofs" +version = "0.3.0" +source = "git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11#7f5c0babd61f8ca46c9165a1adfac298d3fd3a11" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "halo2_legacy_pdqsort", + "maybe-rayon", + "pasta_curves", + "rand_core 0.6.4", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -2086,6 +2185,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb1872810fb725b06b8c153dde9e86f3ec26747b9b60096da7a869883b549cbe" dependencies = [ "either", + "proptest", + "rand 0.8.5", + "rand_core 0.6.4", ] [[package]] @@ -2340,6 +2442,20 @@ dependencies = [ "subtle", ] +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + [[package]] name = "known-folders" version = "1.1.0" @@ -2757,6 +2873,36 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "orchard" +version = "0.8.0" +dependencies = [ + "aes", + "bitvec", + "blake2b_simd", + "ff", + "fpe", + "group", + "half", + "halo2_gadgets 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", + "halo2_proofs 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", + "hex", + "incrementalmerkletree", + "k256", + "lazy_static", + "memuse", + "nonempty", + "pasta_curves", + "rand 0.8.5", + "reddsa", + "serde", + "subtle", + "tracing", + "zcash_note_encryption 0.4.0 (git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1)", + "zcash_spec", + "zip32", +] + [[package]] name = "orchard" version = "0.8.0" @@ -2769,8 +2915,8 @@ dependencies = [ "ff", "fpe", "group", - "halo2_gadgets", - "halo2_proofs", + "halo2_gadgets 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "incrementalmerkletree", "lazy_static", @@ -2782,7 +2928,7 @@ dependencies = [ "serde", "subtle", "tracing", - "zcash_note_encryption", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_spec", "zip32", ] @@ -3591,6 +3737,16 @@ dependencies = [ "winreg", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rgb" version = "0.8.37" @@ -3809,7 +3965,7 @@ dependencies = [ "redjubjub", "subtle", "tracing", - "zcash_note_encryption", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_spec", "zip32", ] @@ -3830,6 +3986,20 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" version = "0.26.0" @@ -4149,6 +4319,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ + "digest", "rand_core 0.6.4", ] @@ -5612,6 +5783,17 @@ version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" +[[package]] +name = "zcash_address" +version = "0.3.2" +dependencies = [ + "bech32", + "bs58", + "f4jumble 0.1.0", + "zcash_encoding 0.2.0", + "zcash_protocol 0.1.1", +] + [[package]] name = "zcash_address" version = "0.3.2" @@ -5620,9 +5802,9 @@ checksum = "827c17a1f7e3a69f0d44e991ff610c7a842228afdc9dc2325ffdd1a67fee01e9" dependencies = [ "bech32", "bs58", - "f4jumble", - "zcash_encoding", - "zcash_protocol", + "f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5655,15 +5837,23 @@ dependencies = [ "tonic-build 0.10.2", "tracing", "which", - "zcash_address", - "zcash_encoding", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_keys", - "zcash_note_encryption", - "zcash_primitives", - "zcash_protocol", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.15.1", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zip32", ] +[[package]] +name = "zcash_encoding" +version = "0.2.0" +dependencies = [ + "byteorder", + "nonempty", +] + [[package]] name = "zcash_encoding" version = "0.2.0" @@ -5704,10 +5894,10 @@ dependencies = [ "secrecy", "subtle", "tracing", - "zcash_address", - "zcash_encoding", - "zcash_primitives", - "zcash_protocol", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.15.1", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zip32", ] @@ -5724,18 +5914,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "zcash_note_encryption" +version = "0.4.0" +source = "git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1#b8bd2a186fc04ec4f55b2db44df7374f03ab5725" +dependencies = [ + "chacha20", + "chacha20poly1305", + "cipher", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "zcash_primitives" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ccee58d0f9e8da312a999a4c0cd3d001ff3b37af6fb1318c89e6a3076f4da" +version = "0.15.0" dependencies = [ "aes", "bip0039", "blake2b_simd", "byteorder", "document-features", - "equihash", + "equihash 0.2.0", "ff", "fpe", "group", @@ -5745,7 +5945,7 @@ dependencies = [ "jubjub", "memuse", "nonempty", - "orchard", + "orchard 0.8.0", "rand 0.8.5", "rand_core 0.6.4", "redjubjub", @@ -5755,10 +5955,46 @@ dependencies = [ "sha2", "subtle", "tracing", - "zcash_address", - "zcash_encoding", - "zcash_note_encryption", - "zcash_protocol", + "zcash_address 0.3.2", + "zcash_encoding 0.2.0", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1", + "zcash_spec", + "zip32", +] + +[[package]] +name = "zcash_primitives" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ccee58d0f9e8da312a999a4c0cd3d001ff3b37af6fb1318c89e6a3076f4da" +dependencies = [ + "aes", + "bip0039", + "blake2b_simd", + "byteorder", + "document-features", + "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ff", + "fpe", + "group", + "hex", + "incrementalmerkletree", + "jubjub", + "memuse", + "nonempty", + "orchard 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.8.5", + "rand_core 0.6.4", + "redjubjub", + "sapling-crypto", + "sha2", + "subtle", + "tracing", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_spec", "zip32", ] @@ -5783,7 +6019,17 @@ dependencies = [ "sapling-crypto", "tracing", "xdg", - "zcash_primitives", + "zcash_primitives 0.15.1", +] + +[[package]] +name = "zcash_protocol" +version = "0.1.1" +dependencies = [ + "document-features", + "incrementalmerkletree", + "memuse", + "proptest", ] [[package]] @@ -5831,10 +6077,10 @@ dependencies = [ "color-eyre", "criterion", "ed25519-zebra", - "equihash", + "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "group", - "halo2_proofs", + "halo2_proofs 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", "hex", "humantime", "incrementalmerkletree", @@ -5842,7 +6088,7 @@ dependencies = [ "jubjub", "lazy_static", "num-integer", - "orchard", + "orchard 0.8.0", "primitive-types", "proptest", "proptest-derive", @@ -5868,13 +6114,13 @@ dependencies = [ "tracing", "uint", "x25519-dalek", - "zcash_address", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_client_backend", - "zcash_encoding", + "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_history", - "zcash_note_encryption", - "zcash_primitives", - "zcash_protocol", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.15.0", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zebra-test", ] @@ -5889,7 +6135,7 @@ dependencies = [ "color-eyre", "futures", "futures-util", - "halo2_proofs", + "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "howudoin", "jubjub", @@ -5897,7 +6143,7 @@ dependencies = [ "metrics", "num-integer", "once_cell", - "orchard", + "orchard 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "proptest", "proptest-derive", "rand 0.8.5", @@ -5939,7 +6185,7 @@ dependencies = [ "tonic-build 0.11.0", "tonic-reflection", "tower", - "zcash_primitives", + "zcash_primitives 0.15.1", "zebra-chain", "zebra-node-services", "zebra-state", @@ -6021,8 +6267,8 @@ dependencies = [ "tokio", "tower", "tracing", - "zcash_address", - "zcash_primitives", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.15.1", "zebra-chain", "zebra-consensus", "zebra-network", @@ -6055,11 +6301,11 @@ dependencies = [ "tokio", "tower", "tracing", - "zcash_address", + "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_client_backend", "zcash_keys", - "zcash_note_encryption", - "zcash_primitives", + "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.15.1", "zebra-chain", "zebra-grpc", "zebra-node-services", @@ -6089,7 +6335,7 @@ dependencies = [ "dirs", "elasticsearch", "futures", - "halo2_proofs", + "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "hex-literal", "howudoin", @@ -6175,8 +6421,8 @@ dependencies = [ "tracing-error", "tracing-subscriber", "zcash_client_backend", - "zcash_primitives", - "zcash_protocol", + "zcash_primitives 0.15.1", + "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "zebra-chain", "zebra-node-services", "zebra-rpc", diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index 9b4160b5c69..bb97fc415f9 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -92,13 +92,18 @@ uint = "0.9.5" x25519-dalek = { version = "2.0.1", features = ["serde"] } # ECC deps -halo2 = { package = "halo2_proofs", version = "0.3.0" } -orchard = "0.8.0" +#halo2 = { package = "halo2_proofs", version = "0.3.0" } +halo2 = { package = "halo2_proofs", git = "https://github.com/QED-it/halo2", rev = "7f5c0babd61f8ca46c9165a1adfac298d3fd3a11", version = "0.3.0" } +#orchard = { version = "0.8.0", default-features = false, git = "https://github.com/QED-it/orchard", branch = "zsa1" } +orchard = { version = "0.8.0", default-features = false, path = "../../orchard", features = ["multicore"] } zcash_encoding = "0.2.0" zcash_history = "0.4.0" zcash_note_encryption = "0.4.0" -zcash_primitives = { version = "0.15.0", features = ["transparent-inputs"] } -sapling = { package = "sapling-crypto", version = "0.1" } +#zcash_primitives = { version = "0.15.0", features = ["transparent-inputs"] } +#zcash_primitives = { version = "0.15", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd1", features = ["transparent-inputs"] } +zcash_primitives = { version = "0.15", path = "../../librustzcash/zcash_primitives", features = ["transparent-inputs"] } +#sapling = { package = "sapling-crypto", version = "0.1" } +sapling = { package = "sapling-crypto", version = "0.1.3" } zcash_protocol = { version = "0.1.1" } zcash_address = { version = "0.3.2" } @@ -176,3 +181,8 @@ required-features = ["bench"] [[bench]] name = "redpallas" harness = false + +[patch.crates-io] +#zcash_primitives = { version = "0.15", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd1" } +zcash_note_encryption = { version = "0.4", git = "https://github.com/QED-it/zcash_note_encryption", branch = "fix-sapling-constants" } +sapling = { package = "sapling-crypto", version = "0.1.3", git = "https://github.com/QED-it/sapling-crypto", branch = "orchard-backward-compatibility" } From 95dce56ab33ceabd6960c78acd005d2c34f366f6 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Sun, 11 Aug 2024 22:25:01 +0200 Subject: [PATCH 02/46] Switch Zebra to QED-it ZSA-compatible crates but maintain the original Orchard support only, without supporting and enabling ZSA features. --- Cargo.lock | 812 ++++++++---------- Cargo.toml | 12 + zebra-chain/Cargo.toml | 18 +- zebra-chain/src/orchard/note/ciphertexts.rs | 2 + zebra-consensus/src/primitives/halo2.rs | 17 +- zebra-consensus/src/primitives/halo2/tests.rs | 24 +- 6 files changed, 405 insertions(+), 480 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e3ac5e59dc..4ddf06cb4b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ "arc-swap", "backtrace", "canonical-path", - "clap 4.5.7", + "clap 4.5.13", "color-eyre", "fs-err", "once_cell", @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -152,33 +152,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -198,9 +198,9 @@ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -210,9 +210,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-compression" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" dependencies = [ "flate2", "futures-core", @@ -240,18 +240,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -290,7 +290,7 @@ dependencies = [ "futures-util", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.29", + "hyper 0.14.30", "itoa", "matchit", "memchr", @@ -428,7 +428,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.68", + "syn 2.0.72", "which", ] @@ -560,9 +560,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", "serde", @@ -582,9 +582,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.16.1" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" +checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" [[package]] name = "byteorder" @@ -594,9 +594,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bzip2-sys" @@ -664,13 +664,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.100" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c891175c3fb232128f48de6590095e59198bbeb8620c310be349bfc3afd12c7b" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", - "once_cell", ] [[package]] @@ -728,7 +727,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -797,9 +796,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -807,9 +806,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstream", "anstyle", @@ -819,21 +818,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "color-eyre" @@ -865,9 +864,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "console" @@ -974,7 +973,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.7", + "clap 4.5.13", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1088,7 +1087,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -1103,12 +1102,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -1127,16 +1126,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -1152,13 +1151,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.9", + "darling_core 0.20.10", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -1226,9 +1225,9 @@ dependencies = [ [[package]] name = "document-features" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" dependencies = [ "litrs", ] @@ -1282,9 +1281,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elasticsearch" @@ -1353,6 +1352,8 @@ dependencies = [ [[package]] name = "equihash" version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab579d7cf78477773b03e80bc2f89702ef02d7112c711d54ca93dcdce68533d5" dependencies = [ "blake2b_simd", "byteorder", @@ -1361,8 +1362,7 @@ dependencies = [ [[package]] name = "equihash" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab579d7cf78477773b03e80bc2f89702ef02d7112c711d54ca93dcdce68533d5" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "blake2b_simd", "byteorder", @@ -1397,15 +1397,7 @@ dependencies = [ [[package]] name = "f4jumble" version = "0.1.0" -dependencies = [ - "blake2b_simd", -] - -[[package]] -name = "f4jumble" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a83e8d7fd0c526af4aad893b7c9fe41e2699ed8a776a6c74aecdeafe05afc75" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "blake2b_simd", ] @@ -1453,9 +1445,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -1574,7 +1566,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -1650,9 +1642,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git2" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ "bitflags 2.6.0", "libc", @@ -1704,7 +1696,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.3.0", "slab", "tokio", "tokio-util 0.7.11", @@ -1723,7 +1715,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.2.6", + "indexmap 2.3.0", "slab", "tokio", "tokio-util 0.7.11", @@ -1739,24 +1731,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "halo2_gadgets" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126a150072b0c38c7b573fe3eaf0af944a7fed09e154071bf2436d3f016f7230" -dependencies = [ - "arrayvec", - "bitvec", - "ff", - "group", - "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static", - "pasta_curves", - "rand 0.8.5", - "subtle", - "uint", -] - [[package]] name = "halo2_gadgets" version = "0.3.0" @@ -1766,7 +1740,7 @@ dependencies = [ "bitvec", "ff", "group", - "halo2_proofs 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", + "halo2_proofs", "lazy_static", "pasta_curves", "rand 0.8.5", @@ -1780,22 +1754,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47716fe1ae67969c5e0b2ef826f32db8c3be72be325e1aa3c1951d06b5575ec5" -[[package]] -name = "halo2_proofs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b867a8d9bbb85fca76fff60652b5cd19b853a1c4d0665cb89bee68b18d2caf0" -dependencies = [ - "blake2b_simd", - "ff", - "group", - "halo2_legacy_pdqsort", - "maybe-rayon", - "pasta_curves", - "rand_core 0.6.4", - "tracing", -] - [[package]] name = "halo2_proofs" version = "0.3.0" @@ -1973,9 +1931,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http 1.1.0", @@ -1990,7 +1948,7 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -2030,9 +1988,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.29" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -2054,16 +2012,16 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", "futures-util", "h2 0.4.5", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -2081,7 +2039,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.29", + "hyper 0.14.30", "rustls", "tokio", "tokio-rustls", @@ -2093,7 +2051,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.29", + "hyper 0.14.30", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -2101,16 +2059,16 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", + "http-body 1.0.1", + "hyper 1.4.1", "pin-project-lite", "socket2", "tokio", @@ -2185,9 +2143,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb1872810fb725b06b8c153dde9e86f3ec26747b9b60096da7a869883b549cbe" dependencies = [ "either", - "proptest", - "rand 0.8.5", - "rand_core 0.6.4", ] [[package]] @@ -2209,9 +2164,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -2233,9 +2188,9 @@ dependencies = [ [[package]] name = "inferno" -version = "0.11.19" +version = "0.11.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321f0f839cd44a4686e9504b0a62b4d69a50b62072144c71c68f5873c167b8d9" +checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" dependencies = [ "ahash", "is-terminal", @@ -2301,9 +2256,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -2340,9 +2295,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -2401,7 +2356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff" dependencies = [ "futures", - "hyper 0.14.29", + "hyper 0.14.30", "jsonrpc-core", "jsonrpc-server-utils", "log", @@ -2488,9 +2443,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libgit2-sys" -version = "0.16.2+1.7.2" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", @@ -2500,12 +2455,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if 1.0.0", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2581,15 +2536,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lz4-sys" -version = "1.9.5" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" +checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" dependencies = [ "cc", "libc", @@ -2653,9 +2608,9 @@ checksum = "5d58e362dc7206e9456ddbcdbd53c71ba441020e62104703075a69151e38d85f" dependencies = [ "base64 0.22.1", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", - "indexmap 2.2.6", + "indexmap 2.3.0", "ipnet", "metrics", "metrics-util", @@ -2703,13 +2658,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2772,9 +2728,9 @@ dependencies = [ [[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", @@ -2857,9 +2813,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "opaque-debug" @@ -2876,6 +2832,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchard" version = "0.8.0" +source = "git+https://github.com/QED-it/orchard?branch=zsa1#6e6112c80eb751a93c0fd1d881e9ca69887e1154" dependencies = [ "aes", "bitvec", @@ -2884,8 +2841,8 @@ dependencies = [ "fpe", "group", "half", - "halo2_gadgets 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", - "halo2_proofs 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", + "halo2_gadgets", + "halo2_proofs", "hex", "incrementalmerkletree", "k256", @@ -2898,37 +2855,7 @@ dependencies = [ "serde", "subtle", "tracing", - "zcash_note_encryption 0.4.0 (git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1)", - "zcash_spec", - "zip32", -] - -[[package]] -name = "orchard" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0462569fc8b0d1b158e4d640571867a4e4319225ebee2ab6647e60c70af19ae3" -dependencies = [ - "aes", - "bitvec", - "blake2b_simd", - "ff", - "fpe", - "group", - "halo2_gadgets 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex", - "incrementalmerkletree", - "lazy_static", - "memuse", - "nonempty", - "pasta_curves", - "rand 0.8.5", - "reddsa", - "serde", - "subtle", - "tracing", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_note_encryption", "zcash_spec", "zip32", ] @@ -3050,9 +2977,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.5.2", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -3099,9 +3026,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -3110,9 +3037,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -3120,22 +3047,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] name = "pest_meta" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -3149,7 +3076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.3.0", ] [[package]] @@ -3169,7 +3096,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -3241,9 +3168,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "powerfmt" @@ -3253,9 +3180,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" @@ -3264,7 +3194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -3387,7 +3317,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.68", + "syn 2.0.72", "tempfile", ] @@ -3401,7 +3331,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -3563,9 +3493,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.0.2" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" dependencies = [ "bitflags 2.6.0", ] @@ -3632,9 +3562,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags 2.6.0", ] @@ -3652,9 +3582,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -3709,7 +3639,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.29", + "hyper 0.14.30", "hyper-rustls", "ipnet", "js-sys", @@ -3749,9 +3679,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +checksum = "e12bc8d2f72df26a5d3178022df33720fbede0d31d82c7291662eff89836994d" dependencies = [ "bytemuck", ] @@ -3941,8 +3871,7 @@ dependencies = [ [[package]] name = "sapling-crypto" version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f4270033afcb0c74c5c7d59c73cfd1040367f67f224fe7ed9a919ae618f1b7" +source = "git+https://github.com/QED-it/sapling-crypto?branch=zsa1#e19f4d916360842becf2842bfd9b27228e66fa81" dependencies = [ "aes", "bellman", @@ -3965,7 +3894,7 @@ dependencies = [ "redjubjub", "subtle", "tracing", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_note_encryption", "zcash_spec", "zip32", ] @@ -4141,9 +4070,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -4159,32 +4088,33 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.118" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4213,19 +4143,19 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_derive", "serde_json", - "serde_with_macros 3.8.1", + "serde_with_macros 3.9.0", "time", ] @@ -4243,14 +4173,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ - "darling 0.20.9", + "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -4259,7 +4189,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "itoa", "ryu", "serde", @@ -4325,9 +4255,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "sketches-ddsketch" @@ -4480,9 +4410,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.68" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -4536,12 +4466,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" dependencies = [ "cfg-if 1.0.0", "fastrand", + "once_cell", "rustix", "windows-sys 0.52.0", ] @@ -4566,22 +4497,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -4653,9 +4584,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4668,22 +4599,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4698,13 +4628,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -4780,21 +4710,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.14", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4805,22 +4735,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow 0.6.18", ] [[package]] @@ -4837,7 +4767,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.29", + "hyper 0.14.30", "hyper-timeout", "percent-encoding", "pin-project", @@ -4864,7 +4794,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.29", + "hyper 0.14.30", "hyper-timeout", "percent-encoding", "pin-project", @@ -4887,7 +4817,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -4900,7 +4830,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -5030,7 +4960,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -5143,7 +5073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -5302,9 +5232,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "serde", ] @@ -5329,9 +5259,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "vergen" -version = "8.3.1" +version = "8.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" +checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" dependencies = [ "anyhow", "cargo_metadata", @@ -5345,9 +5275,9 @@ dependencies = [ [[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 = "void" @@ -5466,7 +5396,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -5500,7 +5430,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5557,11 +5487,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5577,7 +5507,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5586,7 +5516,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5604,7 +5534,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "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]] @@ -5624,18 +5563,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5646,9 +5585,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5658,9 +5597,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5670,15 +5609,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5688,9 +5627,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5700,9 +5639,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5712,9 +5651,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5724,9 +5663,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -5739,9 +5678,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -5786,32 +5725,19 @@ checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "zcash_address" version = "0.3.2" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "bech32", "bs58", - "f4jumble 0.1.0", - "zcash_encoding 0.2.0", - "zcash_protocol 0.1.1", -] - -[[package]] -name = "zcash_address" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827c17a1f7e3a69f0d44e991ff610c7a842228afdc9dc2325ffdd1a67fee01e9" -dependencies = [ - "bech32", - "bs58", - "f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "f4jumble", + "zcash_encoding", + "zcash_protocol", ] [[package]] name = "zcash_client_backend" version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0364e69c446fcf96a1f73f342c6c3fa697ea65ae7eeeae7d76ca847b9c442e40" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "base64 0.21.7", "bech32", @@ -5837,28 +5763,20 @@ dependencies = [ "tonic-build 0.10.2", "tracing", "which", - "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_keys", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.15.1", - "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address", + "zcash_encoding", + "zcash_keys 0.2.0 (git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2)", + "zcash_note_encryption", + "zcash_primitives", + "zcash_protocol", "zip32", + "zip321", ] [[package]] name = "zcash_encoding" version = "0.2.0" -dependencies = [ - "byteorder", - "nonempty", -] - -[[package]] -name = "zcash_encoding" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03391b81727875efa6ac0661a20883022b6fba92365dc121c48fa9b00c5aac0" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "byteorder", "nonempty", @@ -5867,8 +5785,7 @@ dependencies = [ [[package]] name = "zcash_history" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fde17bf53792f9c756b313730da14880257d7661b5bfc69d0571c3a7c11a76d" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "blake2b_simd", "byteorder", @@ -5894,30 +5811,42 @@ dependencies = [ "secrecy", "subtle", "tracing", - "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.15.1", - "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address", + "zcash_encoding", + "zcash_primitives", + "zcash_protocol", "zip32", ] [[package]] -name = "zcash_note_encryption" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4580cd6cee12e44421dac43169be8d23791650816bdb34e6ddfa70ac89c1c5" +name = "zcash_keys" +version = "0.2.0" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ - "chacha20", - "chacha20poly1305", - "cipher", + "bech32", + "blake2b_simd", + "bls12_381", + "bs58", + "document-features", + "group", + "memuse", + "nonempty", "rand_core 0.6.4", + "sapling-crypto", + "secrecy", "subtle", + "tracing", + "zcash_address", + "zcash_encoding", + "zcash_primitives", + "zcash_protocol", + "zip32", ] [[package]] name = "zcash_note_encryption" version = "0.4.0" -source = "git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1#b8bd2a186fc04ec4f55b2db44df7374f03ab5725" +source = "git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1#58384553aab76b2ee6d6eb328cf2187fa824ec9a" dependencies = [ "chacha20", "chacha20poly1305", @@ -5929,13 +5858,14 @@ dependencies = [ [[package]] name = "zcash_primitives" version = "0.15.0" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "aes", "bip0039", "blake2b_simd", "byteorder", "document-features", - "equihash 0.2.0", + "equihash 0.2.0 (git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2)", "ff", "fpe", "group", @@ -5945,7 +5875,7 @@ dependencies = [ "jubjub", "memuse", "nonempty", - "orchard 0.8.0", + "orchard", "rand 0.8.5", "rand_core 0.6.4", "redjubjub", @@ -5955,46 +5885,10 @@ dependencies = [ "sha2", "subtle", "tracing", - "zcash_address 0.3.2", - "zcash_encoding 0.2.0", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_protocol 0.1.1", - "zcash_spec", - "zip32", -] - -[[package]] -name = "zcash_primitives" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ccee58d0f9e8da312a999a4c0cd3d001ff3b37af6fb1318c89e6a3076f4da" -dependencies = [ - "aes", - "bip0039", - "blake2b_simd", - "byteorder", - "document-features", - "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ff", - "fpe", - "group", - "hex", - "incrementalmerkletree", - "jubjub", - "memuse", - "nonempty", - "orchard 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.8.5", - "rand_core 0.6.4", - "redjubjub", - "sapling-crypto", - "sha2", - "subtle", - "tracing", - "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address", + "zcash_encoding", + "zcash_note_encryption", + "zcash_protocol", "zcash_spec", "zip32", ] @@ -6019,24 +5913,13 @@ dependencies = [ "sapling-crypto", "tracing", "xdg", - "zcash_primitives 0.15.1", + "zcash_primitives", ] [[package]] name = "zcash_protocol" version = "0.1.1" -dependencies = [ - "document-features", - "incrementalmerkletree", - "memuse", - "proptest", -] - -[[package]] -name = "zcash_protocol" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f8189d4a304e8aa3aef3b75e89f3874bb0dc84b1cd623316a84e79e06cddabc" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" dependencies = [ "document-features", "memuse", @@ -6080,7 +5963,7 @@ dependencies = [ "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "group", - "halo2_proofs 0.3.0 (git+https://github.com/QED-it/halo2?rev=7f5c0babd61f8ca46c9165a1adfac298d3fd3a11)", + "halo2_proofs", "hex", "humantime", "incrementalmerkletree", @@ -6088,7 +5971,7 @@ dependencies = [ "jubjub", "lazy_static", "num-integer", - "orchard 0.8.0", + "orchard", "primitive-types", "proptest", "proptest-derive", @@ -6104,7 +5987,7 @@ dependencies = [ "serde", "serde-big-array", "serde_json", - "serde_with 3.8.1", + "serde_with 3.9.0", "sha2", "spandoc", "static_assertions", @@ -6114,13 +5997,13 @@ dependencies = [ "tracing", "uint", "x25519-dalek", - "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address", "zcash_client_backend", - "zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding", "zcash_history", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.15.0", - "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_note_encryption", + "zcash_primitives", + "zcash_protocol", "zebra-test", ] @@ -6135,7 +6018,7 @@ dependencies = [ "color-eyre", "futures", "futures-util", - "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "halo2_proofs", "hex", "howudoin", "jubjub", @@ -6143,7 +6026,7 @@ dependencies = [ "metrics", "num-integer", "once_cell", - "orchard 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "orchard", "proptest", "proptest-derive", "rand 0.8.5", @@ -6185,7 +6068,7 @@ dependencies = [ "tonic-build 0.11.0", "tonic-reflection", "tower", - "zcash_primitives 0.15.1", + "zcash_primitives", "zebra-chain", "zebra-node-services", "zebra-state", @@ -6205,7 +6088,7 @@ dependencies = [ "hex", "howudoin", "humantime-serde", - "indexmap 2.2.6", + "indexmap 2.3.0", "itertools 0.13.0", "lazy_static", "metrics", @@ -6224,7 +6107,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util 0.7.11", - "toml 0.8.14", + "toml 0.8.19", "tower", "tracing", "tracing-error", @@ -6253,8 +6136,8 @@ dependencies = [ "chrono", "futures", "hex", - "hyper 0.14.29", - "indexmap 2.2.6", + "hyper 0.14.30", + "indexmap 2.3.0", "insta", "jsonrpc-core", "jsonrpc-derive", @@ -6267,8 +6150,8 @@ dependencies = [ "tokio", "tower", "tracing", - "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.15.1", + "zcash_address", + "zcash_primitives", "zebra-chain", "zebra-consensus", "zebra-network", @@ -6288,7 +6171,7 @@ dependencies = [ "ff", "futures", "group", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "itertools 0.13.0", "jubjub", @@ -6301,11 +6184,11 @@ dependencies = [ "tokio", "tower", "tracing", - "zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address", "zcash_client_backend", - "zcash_keys", - "zcash_note_encryption 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.15.1", + "zcash_keys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_note_encryption", + "zcash_primitives", "zebra-chain", "zebra-grpc", "zebra-node-services", @@ -6335,13 +6218,13 @@ dependencies = [ "dirs", "elasticsearch", "futures", - "halo2_proofs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "halo2_proofs", "hex", "hex-literal", "howudoin", "human_bytes", "humantime-serde", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "itertools 0.13.0", "jubjub", @@ -6378,7 +6261,7 @@ dependencies = [ "futures", "hex", "humantime", - "indexmap 2.2.6", + "indexmap 2.3.0", "insta", "itertools 0.13.0", "lazy_static", @@ -6414,15 +6297,15 @@ dependencies = [ "serde_json", "serde_yaml", "structopt", - "syn 2.0.68", + "syn 2.0.72", "thiserror", "tinyvec", "tokio", "tracing-error", "tracing-subscriber", "zcash_client_backend", - "zcash_primitives 0.15.1", - "zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives", + "zcash_protocol", "zebra-chain", "zebra-node-services", "zebra-rpc", @@ -6436,7 +6319,7 @@ dependencies = [ "abscissa_core", "atty", "chrono", - "clap 4.5.7", + "clap 4.5.13", "color-eyre", "console-subscriber", "dirs", @@ -6445,8 +6328,8 @@ dependencies = [ "hex-literal", "howudoin", "humantime-serde", - "hyper 0.14.29", - "indexmap 2.2.6", + "hyper 0.14.30", + "indexmap 2.3.0", "indicatif", "inferno", "insta", @@ -6474,7 +6357,7 @@ dependencies = [ "tinyvec", "tokio", "tokio-stream", - "toml 0.8.14", + "toml 0.8.19", "tonic 0.11.0", "tonic-build 0.11.0", "tower", @@ -6501,22 +6384,23 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -6536,7 +6420,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.72", ] [[package]] @@ -6549,3 +6433,15 @@ dependencies = [ "memuse", "subtle", ] + +[[package]] +name = "zip321" +version = "0.0.0" +source = "git+https://github.com/QED-it/librustzcash?branch=txv6-separate-bundles-rebased-dd2#04ebee7fb22303c1e1dc6428def3dd3cecc4715d" +dependencies = [ + "base64 0.21.7", + "nom", + "percent-encoding", + "zcash_address", + "zcash_protocol", +] diff --git a/Cargo.toml b/Cargo.toml index 591c0d898e1..e6baf5c7db5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,3 +89,15 @@ panic = "abort" # - add "-flto=thin" to all C/C++ code builds # - see https://doc.rust-lang.org/rustc/linker-plugin-lto.html#cc-code-as-a-dependency-in-rust lto = "thin" + +[patch.crates-io] +halo2_proofs = { version = "0.3.0", git = "https://github.com/QED-it/halo2", rev = "7f5c0babd61f8ca46c9165a1adfac298d3fd3a11" } +zcash_note_encryption = { version = "0.4.0", git = "https://github.com/QED-it/zcash_note_encryption", branch = "zsa1" } +sapling-crypto = { version = "0.1.3", git = "https://github.com/QED-it/sapling-crypto", branch = "zsa1" } +orchard = { version = "0.8.0", git = "https://github.com/QED-it/orchard", branch = "zsa1" } +zcash_primitives = { version = "0.15.0", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd2" } +zcash_protocol = { version = "0.1.1", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd2" } +zcash_address = { version = "0.3.2", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd2" } +zcash_encoding = { version = "0.2.0", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd2" } +zcash_history = { version = "0.4.0", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd2" } +zcash_client_backend = { version = "0.12.1", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd2" } diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index bb97fc415f9..9b4160b5c69 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -92,18 +92,13 @@ uint = "0.9.5" x25519-dalek = { version = "2.0.1", features = ["serde"] } # ECC deps -#halo2 = { package = "halo2_proofs", version = "0.3.0" } -halo2 = { package = "halo2_proofs", git = "https://github.com/QED-it/halo2", rev = "7f5c0babd61f8ca46c9165a1adfac298d3fd3a11", version = "0.3.0" } -#orchard = { version = "0.8.0", default-features = false, git = "https://github.com/QED-it/orchard", branch = "zsa1" } -orchard = { version = "0.8.0", default-features = false, path = "../../orchard", features = ["multicore"] } +halo2 = { package = "halo2_proofs", version = "0.3.0" } +orchard = "0.8.0" zcash_encoding = "0.2.0" zcash_history = "0.4.0" zcash_note_encryption = "0.4.0" -#zcash_primitives = { version = "0.15.0", features = ["transparent-inputs"] } -#zcash_primitives = { version = "0.15", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd1", features = ["transparent-inputs"] } -zcash_primitives = { version = "0.15", path = "../../librustzcash/zcash_primitives", features = ["transparent-inputs"] } -#sapling = { package = "sapling-crypto", version = "0.1" } -sapling = { package = "sapling-crypto", version = "0.1.3" } +zcash_primitives = { version = "0.15.0", features = ["transparent-inputs"] } +sapling = { package = "sapling-crypto", version = "0.1" } zcash_protocol = { version = "0.1.1" } zcash_address = { version = "0.3.2" } @@ -181,8 +176,3 @@ required-features = ["bench"] [[bench]] name = "redpallas" harness = false - -[patch.crates-io] -#zcash_primitives = { version = "0.15", git = "https://github.com/QED-it/librustzcash", branch = "txv6-separate-bundles-rebased-dd1" } -zcash_note_encryption = { version = "0.4", git = "https://github.com/QED-it/zcash_note_encryption", branch = "fix-sapling-constants" } -sapling = { package = "sapling-crypto", version = "0.1.3", git = "https://github.com/QED-it/sapling-crypto", branch = "orchard-backward-compatibility" } diff --git a/zebra-chain/src/orchard/note/ciphertexts.rs b/zebra-chain/src/orchard/note/ciphertexts.rs index 8f857cf1444..b27ffbc53a1 100644 --- a/zebra-chain/src/orchard/note/ciphertexts.rs +++ b/zebra-chain/src/orchard/note/ciphertexts.rs @@ -1,5 +1,7 @@ //! Encrypted parts of Orchard notes. +// FIXME: make it a generic and add support for OrchardZSA (encrypted tote size ofr it is not 580!) + use std::{fmt, io}; use serde_big_array::BigArray; diff --git a/zebra-consensus/src/primitives/halo2.rs b/zebra-consensus/src/primitives/halo2.rs index ffc58a5feb8..447d9bbd449 100644 --- a/zebra-consensus/src/primitives/halo2.rs +++ b/zebra-consensus/src/primitives/halo2.rs @@ -10,7 +10,7 @@ use std::{ use futures::{future::BoxFuture, FutureExt}; use once_cell::sync::Lazy; -use orchard::circuit::VerifyingKey; +use orchard::{circuit::VerifyingKey, orchard_flavor::OrchardVanilla}; use rand::{thread_rng, CryptoRng, RngCore}; use thiserror::Error; @@ -75,7 +75,8 @@ pub type ItemVerifyingKey = VerifyingKey; lazy_static::lazy_static! { /// The halo2 proof verifying key. - pub static ref VERIFYING_KEY: ItemVerifyingKey = ItemVerifyingKey::build(); + // FIXME: support OrchardZSA? + pub static ref VERIFYING_KEY: ItemVerifyingKey = ItemVerifyingKey::build::(); } // === TEMPORARY BATCH HALO2 SUBSTITUTE === @@ -143,6 +144,15 @@ impl From<&zebra_chain::orchard::ShieldedData> for Item { .flags .contains(zebra_chain::orchard::Flags::ENABLE_OUTPUTS); + // FIXME: simplify the flags creation - make `Flags::from_parts` method pub? + // FIXME: support OrchardZSA? + let flags = match (enable_spend, enable_output) { + (false, false) => orchard::builder::BundleType::DISABLED.flags(), + (false, true) => orchard::bundle::Flags::SPENDS_DISABLED_WITHOUT_ZSA, + (true, false) => orchard::bundle::Flags::OUTPUTS_DISABLED, + (true, true) => orchard::bundle::Flags::ENABLED_WITHOUT_ZSA, + }; + let instances = shielded_data .actions() .map(|action| { @@ -155,8 +165,7 @@ impl From<&zebra_chain::orchard::ShieldedData> for Item { )) .expect("should be a valid redpallas spendauth verification key"), note::ExtractedNoteCommitment::from_bytes(&action.cm_x.into()).unwrap(), - enable_spend, - enable_output, + flags, ) }) .collect(); diff --git a/zebra-consensus/src/primitives/halo2/tests.rs b/zebra-consensus/src/primitives/halo2/tests.rs index e654adcc546..9b5c367e640 100644 --- a/zebra-consensus/src/primitives/halo2/tests.rs +++ b/zebra-consensus/src/primitives/halo2/tests.rs @@ -11,6 +11,8 @@ use orchard::{ bundle::Flags, circuit::ProvingKey, keys::{FullViewingKey, Scope, SpendingKey}, + note::AssetBase, + orchard_flavor::OrchardVanilla, value::NoteValue, Anchor, Bundle, }; @@ -23,9 +25,10 @@ use zebra_chain::{ use crate::primitives::halo2::*; +// FIXME: add support for OrchardZSA (see OrchardVanilla and AssetBase::native() usage below) #[allow(dead_code, clippy::print_stdout)] fn generate_test_vectors() { - let proving_key = ProvingKey::build(); + let proving_key = ProvingKey::build::(); let rng = OsRng; @@ -50,11 +53,17 @@ fn generate_test_vectors() { for _ in 0..num_recipients { builder - .add_output(None, recipient, NoteValue::from_raw(note_value), None) + .add_output( + None, + recipient, + NoteValue::from_raw(note_value), + AssetBase::native(), + None, + ) .unwrap(); } - let bundle: Bundle<_, i64> = builder.build(rng).unwrap().unwrap().0; + let bundle: Bundle<_, i64, OrchardVanilla> = builder.build(rng).unwrap().unwrap().0; let bundle = bundle .create_proof(&proving_key, rng) @@ -79,7 +88,14 @@ fn generate_test_vectors() { rk: <[u8; 32]>::from(a.rk()).into(), cm_x: pallas::Base::from_repr(a.cmx().into()).unwrap(), ephemeral_key: a.encrypted_note().epk_bytes.try_into().unwrap(), - enc_ciphertext: a.encrypted_note().enc_ciphertext.into(), + // FIXME: support OrchardZSA too, 580 works for OrchardVanilla only! + // FIXME: consider more "type safe" way to do the following conversion + // (now it goes through &[u8]) + enc_ciphertext: <[u8; 580]>::try_from( + a.encrypted_note().enc_ciphertext.as_ref(), + ) + .unwrap() + .into(), out_ciphertext: a.encrypted_note().out_ciphertext.into(), }; zebra_chain::orchard::shielded_data::AuthorizedAction { From cdb9efdb276546a2c719e74b25570792b21ab7f2 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Thu, 29 Aug 2024 20:57:17 +0100 Subject: [PATCH 03/46] fix(docker): allow the `zebra` user access to relevant dirs (#8817) * fix(docker): allow the `zebra` user access to relevant dirs When runnning a Zebra node using Docker without a privileged user, you won't be able to modify some files and directories, not even the ones in the current directory, as the `zebra` user has no permission to `/`. The best way to solve this is making the `/opt/zebrad` the current `WORKDIR`. This also requires moving the `entrypoint.sh` from the root `/` directory to `/etc/zebrad` as this directory is used to save configuration, and other files. An `APP_HOME` ARG is used as not all platforms where a Docker container is deployed allows writting permissions to the `/opt` directory. This allow some users to re-build the image with a custom `WORKDIR` * fix(docker): allow starting the container without a `zebrad` command As `gosu` is just required and available in our `runtime` image, trying to run `docker run -it --rm --name tests -t zfnd/zebra: /bin/bash` in other stages will fail, as `gosu` is not available. --- docker/Dockerfile | 40 +++++++++++++++++++++++++--------------- docker/entrypoint.sh | 10 +++++++--- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 3820d87adf4..1ccaa5915a5 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -19,10 +19,14 @@ ARG FEATURES="default-release-binaries" ARG TEST_FEATURES="lightwalletd-grpc-tests zebra-checkpoints" ARG EXPERIMENTAL_FEATURES="" +ARG APP_HOME="/opt/zebrad" # This stage implements cargo-chef for docker layer caching FROM rust:bookworm as chef RUN cargo install cargo-chef --locked -WORKDIR /opt/zebrad + +ARG APP_HOME +ENV APP_HOME=${APP_HOME} +WORKDIR ${APP_HOME} # Analyze the current project to determine the minimum subset of files # (Cargo.lock and Cargo.toml manifests) required to build it and cache dependencies @@ -38,7 +42,7 @@ RUN cargo chef prepare --recipe-path recipe.json # We set defaults for the arguments, in case the build does not include this information. FROM chef AS deps SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -COPY --from=planner /opt/zebrad/recipe.json recipe.json +COPY --from=planner ${APP_HOME}/recipe.json recipe.json # Install zebra build deps and Dockerfile deps RUN apt-get -qq update && \ @@ -90,7 +94,7 @@ ARG SHORT_SHA # https://github.com/ZcashFoundation/zebra/blob/9ebd56092bcdfc1a09062e15a0574c94af37f389/zebrad/src/application.rs#L179-L182 ENV SHORT_SHA=${SHORT_SHA:-} -ENV CARGO_HOME="/opt/zebrad/.cargo/" +ENV CARGO_HOME="${APP_HOME}/.cargo/" # In this stage we build tests (without running then) # @@ -128,17 +132,16 @@ RUN cargo chef cook --tests --release --features "${ENTRYPOINT_FEATURES}" --work # Undo the source file changes made by cargo-chef. # rsync invalidates the cargo cache for the changed files only, by updating their timestamps. # This makes sure the fake empty binaries created by cargo-chef are rebuilt. -COPY --from=planner /opt/zebrad zebra-original +COPY --from=planner ${APP_HOME} zebra-original RUN rsync --recursive --checksum --itemize-changes --verbose zebra-original/ . RUN rm -r zebra-original # Build Zebra test binaries, but don't run them RUN cargo test --locked --release --features "${ENTRYPOINT_FEATURES}" --workspace --no-run -RUN cp /opt/zebrad/target/release/zebrad /usr/local/bin -RUN cp /opt/zebrad/target/release/zebra-checkpoints /usr/local/bin +RUN cp ${APP_HOME}/target/release/zebrad /usr/local/bin +RUN cp ${APP_HOME}/target/release/zebra-checkpoints /usr/local/bin -COPY ./docker/entrypoint.sh / -RUN chmod u+x /entrypoint.sh +COPY ./docker/entrypoint.sh /etc/zebrad/entrypoint.sh # Entrypoint environment variables ENV ENTRYPOINT_FEATURES=${ENTRYPOINT_FEATURES} @@ -147,7 +150,7 @@ ARG EXPERIMENTAL_FEATURES="shielded-scan journald prometheus filter-reload" ENV ENTRYPOINT_FEATURES_EXPERIMENTAL="${ENTRYPOINT_FEATURES} ${EXPERIMENTAL_FEATURES}" # By default, runs the entrypoint tests specified by the environmental variables (if any are set) -ENTRYPOINT [ "/entrypoint.sh" ] +ENTRYPOINT [ "/etc/zebrad/entrypoint.sh" ] # In this stage we build a release (generate the zebrad binary) # @@ -167,15 +170,14 @@ ARG FEATURES RUN cargo chef cook --release --features "${FEATURES}" --package zebrad --bin zebrad --recipe-path recipe.json # Undo the source file changes made by cargo-chef, so the fake empty zebrad binary is rebuilt. -COPY --from=planner /opt/zebrad zebra-original +COPY --from=planner ${APP_HOME} zebra-original RUN rsync --recursive --checksum --itemize-changes --verbose zebra-original/ . RUN rm -r zebra-original # Build zebrad RUN cargo build --locked --release --features "${FEATURES}" --package zebrad --bin zebrad -COPY ./docker/entrypoint.sh / -RUN chmod u+x /entrypoint.sh +COPY ./docker/entrypoint.sh ./ # This stage is only used when deploying nodes or when only the resulting zebrad binary is needed # @@ -183,6 +185,11 @@ RUN chmod u+x /entrypoint.sh # binary from the `release` stage FROM debian:bookworm-slim AS runtime +# Set the default path for the zebrad binary +ARG APP_HOME +ENV APP_HOME=${APP_HOME} +WORKDIR ${APP_HOME} + RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates \ @@ -220,13 +227,16 @@ ENV FEATURES=${FEATURES} ENV ZEBRA_CONF_DIR=${ZEBRA_CONF_DIR:-/etc/zebrad} ENV ZEBRA_CONF_FILE=${ZEBRA_CONF_FILE:-zebrad.toml} -COPY --from=release /opt/zebrad/target/release/zebrad /usr/local/bin -COPY --from=release /entrypoint.sh / +RUN mkdir -p ${ZEBRA_CONF_DIR} && chown ${UID}:${UID} ${ZEBRA_CONF_DIR} \ + && chown ${UID}:${UID} ${APP_HOME} + +COPY --from=release ${APP_HOME}/target/release/zebrad /usr/local/bin +COPY --from=release ${APP_HOME}/entrypoint.sh /etc/zebrad # Expose configured ports EXPOSE 8233 18233 # Update the config file based on the Docker run variables, # and launch zebrad with it -ENTRYPOINT [ "/entrypoint.sh" ] +ENTRYPOINT [ "/etc/zebrad/entrypoint.sh" ] CMD ["zebrad"] diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 3dd5275d643..b67cf5ee5b5 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -357,11 +357,15 @@ case "$1" in exec cargo test --locked --release --features "zebra-test" --package zebra-scan -- --nocapture --include-ignored scan_task_commands else - exec gosu "$USER" "$@" + exec "$@" fi fi ;; *) - exec gosu "$USER" "$@" + if command -v gosu >/dev/null 2>&1; then + exec gosu "$USER" "$@" + else + exec "$@" + fi ;; -esac +esac \ No newline at end of file From 0ef9987e9eeaae4d9af121264f66a866501d4cee Mon Sep 17 00:00:00 2001 From: Arya Date: Thu, 29 Aug 2024 17:09:27 -0400 Subject: [PATCH 04/46] fix(state): Write database format version to disk atomically to avoid a rare panic (#8795) * Splits `atomic_write_to_tmp_file` out of `zebra_network::Config::update_peer_cache` * Uses the new `atomic_write_to_tmp_file` fn in `update_peer_cache()` * Replaces repetitive code for getting the default peer and state cache directories with `default_cache_dir()` * Converts `atomic_write_to_tmp_file` to a blocking function and adds `spawn_atomic_write_to_tmp_file` for use in async environments. * Uses `atomic_write_to_tmp_file` to write database versions to disk * Removes `spawn_atomic_write_to_tmp_file()` and inlines its body at its callsite to avoid adding tokio as a dependency of zebra-chain. * Apply suggestions from code review Co-authored-by: Marek --------- Co-authored-by: Marek --- Cargo.lock | 2 + zebra-chain/Cargo.toml | 2 + zebra-chain/src/common.rs | 71 ++++++++++++++++ zebra-chain/src/lib.rs | 1 + zebra-network/src/config.rs | 111 +++++++------------------- zebra-network/src/config/cache_dir.rs | 9 +-- zebra-state/src/config.rs | 17 ++-- 7 files changed, 113 insertions(+), 100 deletions(-) create mode 100644 zebra-chain/src/common.rs diff --git a/Cargo.lock b/Cargo.lock index 76374083800..c5169cf98dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5964,6 +5964,7 @@ dependencies = [ "chrono", "color-eyre", "criterion", + "dirs", "ed25519-zebra", "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures", @@ -5996,6 +5997,7 @@ dependencies = [ "sha2", "spandoc", "static_assertions", + "tempfile", "thiserror", "tinyvec", "tokio", diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index a7a4a7efc05..a6ec5c1f342 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -81,6 +81,8 @@ group = "0.13.0" incrementalmerkletree.workspace = true jubjub = "0.10.0" lazy_static = "1.4.0" +tempfile = "3.11.0" +dirs = "5.0.1" num-integer = "0.1.46" primitive-types = "0.12.2" rand_core = "0.6.4" diff --git a/zebra-chain/src/common.rs b/zebra-chain/src/common.rs new file mode 100644 index 00000000000..2af22887d8d --- /dev/null +++ b/zebra-chain/src/common.rs @@ -0,0 +1,71 @@ +//! Common functions used in Zebra. + +use std::{ + ffi::OsString, + fs, + io::{self, Write}, + path::PathBuf, +}; + +use tempfile::PersistError; + +/// Returns Zebra's default cache directory path. +pub fn default_cache_dir() -> PathBuf { + dirs::cache_dir() + .unwrap_or_else(|| std::env::current_dir().unwrap().join("cache")) + .join("zebra") +} + +/// Accepts a target file path and a byte-slice. +/// +/// Atomically writes the byte-slice to a file to avoid corrupting the file if Zebra +/// panics, crashes, or exits while the file is being written, or if multiple Zebra instances +/// try to read and write the same file. +/// +/// Returns the provided file path if successful. +/// +/// # Concurrency +/// +/// This function blocks on filesystem operations and should be called in a blocking task +/// when calling from an async environment. +/// +/// # Panics +/// +/// If the provided `file_path` is a directory path. +pub fn atomic_write( + file_path: PathBuf, + data: &[u8], +) -> io::Result>> { + // Get the file's parent directory, or use Zebra's default cache directory + let file_dir = file_path + .parent() + .map(|p| p.to_owned()) + .unwrap_or_else(default_cache_dir); + + // Create the directory if needed. + fs::create_dir_all(&file_dir)?; + + // Give the temporary file a similar name to the permanent file, + // but hide it in directory listings. + let mut tmp_file_prefix: OsString = ".tmp.".into(); + tmp_file_prefix.push( + file_path + .file_name() + .expect("file path must have a file name"), + ); + + // Create the temporary file in the same directory as the permanent file, + // so atomic filesystem operations are possible. + let mut tmp_file = tempfile::Builder::new() + .prefix(&tmp_file_prefix) + .tempfile_in(file_dir)?; + + tmp_file.write_all(data)?; + + // Atomically write the temp file to `file_path`. + let persist_result = tmp_file + .persist(&file_path) + // Drops the temp file and returns the file path. + .map(|_| file_path); + Ok(persist_result) +} diff --git a/zebra-chain/src/lib.rs b/zebra-chain/src/lib.rs index 4faaeab70cc..460d3a850f0 100644 --- a/zebra-chain/src/lib.rs +++ b/zebra-chain/src/lib.rs @@ -22,6 +22,7 @@ pub mod amount; pub mod block; pub mod chain_sync_status; pub mod chain_tip; +pub mod common; pub mod diagnostic; pub mod error; pub mod fmt; diff --git a/zebra-network/src/config.rs b/zebra-network/src/config.rs index 00f4f8b4460..7936ea0e787 100644 --- a/zebra-network/src/config.rs +++ b/zebra-network/src/config.rs @@ -2,7 +2,6 @@ use std::{ collections::HashSet, - ffi::OsString, io::{self, ErrorKind}, net::{IpAddr, SocketAddr}, time::Duration, @@ -10,11 +9,11 @@ use std::{ use indexmap::IndexSet; use serde::{de, Deserialize, Deserializer}; -use tempfile::NamedTempFile; -use tokio::{fs, io::AsyncWriteExt}; -use tracing::Span; +use tokio::fs; +use tracing::Span; use zebra_chain::{ + common::atomic_write, parameters::{ testnet::{self, ConfiguredActivationHeights, ConfiguredFundingStreams}, Magic, Network, NetworkKind, @@ -503,90 +502,36 @@ impl Config { // Make a newline-separated list let peer_data = peer_list.join("\n"); - // Write to a temporary file, so the cache is not corrupted if Zebra shuts down or crashes - // at the same time. - // - // # Concurrency - // - // We want to use async code to avoid blocking the tokio executor on filesystem operations, - // but `tempfile` is implemented using non-asyc methods. So we wrap its filesystem - // operations in `tokio::spawn_blocking()`. - // - // TODO: split this out into an atomic_write_to_tmp_file() method if we need to re-use it - - // Create the peer cache directory if needed - let peer_cache_dir = peer_cache_file - .parent() - .expect("cache path always has a network directory") - .to_owned(); - tokio::fs::create_dir_all(&peer_cache_dir).await?; - - // Give the temporary file a similar name to the permanent cache file, - // but hide it in directory listings. - let mut tmp_peer_cache_prefix: OsString = ".tmp.".into(); - tmp_peer_cache_prefix.push( - peer_cache_file - .file_name() - .expect("cache file always has a file name"), - ); - - // Create the temporary file. - // Do blocking filesystem operations on a dedicated thread. + // Write the peer cache file atomically so the cache is not corrupted if Zebra shuts down + // or crashes. let span = Span::current(); - let tmp_peer_cache_file = tokio::task::spawn_blocking(move || { - span.in_scope(move || { - // Put the temporary file in the same directory as the permanent file, - // so atomic filesystem operations are possible. - tempfile::Builder::new() - .prefix(&tmp_peer_cache_prefix) - .tempfile_in(peer_cache_dir) - }) + let write_result = tokio::task::spawn_blocking(move || { + span.in_scope(move || atomic_write(peer_cache_file, peer_data.as_bytes())) }) .await - .expect("unexpected panic creating temporary peer cache file")?; - - // Write the list to the file asynchronously, by extracting the inner file, using it, - // then combining it back into a type that will correctly drop the file on error. - let (tmp_peer_cache_file, tmp_peer_cache_path) = tmp_peer_cache_file.into_parts(); - let mut tmp_peer_cache_file = tokio::fs::File::from_std(tmp_peer_cache_file); - tmp_peer_cache_file.write_all(peer_data.as_bytes()).await?; - - let tmp_peer_cache_file = - NamedTempFile::from_parts(tmp_peer_cache_file, tmp_peer_cache_path); - - // Atomically replace the current cache with the temporary cache. - // Do blocking filesystem operations on a dedicated thread. - let span = Span::current(); - tokio::task::spawn_blocking(move || { - span.in_scope(move || { - let result = tmp_peer_cache_file.persist(&peer_cache_file); - - // Drops the temp file if needed - match result { - Ok(_temp_file) => { - info!( - cached_ip_count = ?peer_list.len(), - ?peer_cache_file, - "updated cached peer IP addresses" - ); + .expect("could not write the peer cache file")?; + + match write_result { + Ok(peer_cache_file) => { + info!( + cached_ip_count = ?peer_list.len(), + ?peer_cache_file, + "updated cached peer IP addresses" + ); - for ip in &peer_list { - metrics::counter!( - "zcash.net.peers.cache", - "cache" => peer_cache_file.display().to_string(), - "remote_ip" => ip.to_string() - ) - .increment(1); - } - - Ok(()) - } - Err(error) => Err(error.error), + for ip in &peer_list { + metrics::counter!( + "zcash.net.peers.cache", + "cache" => peer_cache_file.display().to_string(), + "remote_ip" => ip.to_string() + ) + .increment(1); } - }) - }) - .await - .expect("unexpected panic making temporary peer cache file permanent") + + Ok(()) + } + Err(error) => Err(error.error), + } } } diff --git a/zebra-network/src/config/cache_dir.rs b/zebra-network/src/config/cache_dir.rs index 99b75f9f4e1..1e80b27bb9a 100644 --- a/zebra-network/src/config/cache_dir.rs +++ b/zebra-network/src/config/cache_dir.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; -use zebra_chain::parameters::Network; +use zebra_chain::{common::default_cache_dir, parameters::Network}; /// A cache directory config field. /// @@ -56,12 +56,7 @@ impl CacheDir { /// Returns the `zebra-network` base cache directory, if enabled. pub fn cache_dir(&self) -> Option { match self { - Self::IsEnabled(is_enabled) => is_enabled.then(|| { - dirs::cache_dir() - .unwrap_or_else(|| std::env::current_dir().unwrap().join("cache")) - .join("zebra") - }), - + Self::IsEnabled(is_enabled) => is_enabled.then(default_cache_dir), Self::CustomPath(cache_dir) => Some(cache_dir.to_owned()), } } diff --git a/zebra-state/src/config.rs b/zebra-state/src/config.rs index fa9032edf6e..4cd800f3975 100644 --- a/zebra-state/src/config.rs +++ b/zebra-state/src/config.rs @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize}; use tokio::task::{spawn_blocking, JoinHandle}; use tracing::Span; -use zebra_chain::parameters::Network; +use zebra_chain::{common::default_cache_dir, parameters::Network}; use crate::{ constants::{DATABASE_FORMAT_VERSION_FILE_NAME, RESTORABLE_DB_VERSIONS, STATE_DATABASE_KIND}, @@ -173,12 +173,8 @@ impl Config { impl Default for Config { fn default() -> Self { - let cache_dir = dirs::cache_dir() - .unwrap_or_else(|| std::env::current_dir().unwrap().join("cache")) - .join("zebra"); - Self { - cache_dir, + cache_dir: default_cache_dir(), ephemeral: false, delete_old_database: true, debug_stop_at_height: None, @@ -471,6 +467,8 @@ pub(crate) use hidden::{ pub(crate) mod hidden { #![allow(dead_code)] + use zebra_chain::common::atomic_write; + use super::*; /// Writes `changed_version` to the on-disk state database after the format is changed. @@ -512,10 +510,9 @@ pub(crate) mod hidden { let version = format!("{}.{}", changed_version.minor, changed_version.patch); - // # Concurrency - // - // The caller handles locking for this file write. - fs::write(version_path, version.as_bytes())?; + // Write the version file atomically so the cache is not corrupted if Zebra shuts down or + // crashes. + atomic_write(version_path, version.as_bytes())??; Ok(()) } From 6b95d271d834d0ffe0bcc44bbed3f0d32fee0ed8 Mon Sep 17 00:00:00 2001 From: Arya Date: Fri, 30 Aug 2024 16:09:10 -0400 Subject: [PATCH 05/46] fix(rpc): Return verification errors from `sendrawtransaction` RPC method (#8788) * Adds a mempool request to wait for a transaction verification result and uses it in `sendrawtransaction` RPC method * removes unnecessary clone * fix clippy warnings * returns verification errors for all `mempool::Queue` requests, removes `QueueRpc` request variant * returns oneshot channel in mempool::Response::Queue * updates a test vector to check for download or verification error in mempool::response::Queued result receiver * Always require tokio as a dependency in zebra-node-services * checks for closed channel errors in sendrawtransaction and updates a prop test to check that verification errors are propagated correctly --- zebra-node-services/Cargo.toml | 4 +- zebra-node-services/src/mempool.rs | 9 ++-- zebra-rpc/src/methods.rs | 15 +++++-- zebra-rpc/src/methods/tests/prop.rs | 43 ++++++++++++++++--- zebra-rpc/src/queue/tests/prop.rs | 10 +++-- zebrad/src/components/mempool.rs | 36 ++++++++++------ .../components/mempool/crawler/tests/prop.rs | 14 ++++-- zebrad/src/components/mempool/downloads.rs | 31 +++++++++---- zebrad/src/components/mempool/tests/vector.rs | 17 +++++++- 9 files changed, 133 insertions(+), 46 deletions(-) diff --git a/zebra-node-services/Cargo.toml b/zebra-node-services/Cargo.toml index 5c188b34b40..8d0992dcf5a 100644 --- a/zebra-node-services/Cargo.toml +++ b/zebra-node-services/Cargo.toml @@ -34,7 +34,7 @@ rpc-client = [ "serde_json", ] -shielded-scan = ["tokio"] +shielded-scan = [] [dependencies] zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" } @@ -48,7 +48,7 @@ jsonrpc-core = { version = "18.0.0", optional = true } reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true } serde = { version = "1.0.204", optional = true } serde_json = { version = "1.0.122", optional = true } -tokio = { version = "1.39.2", features = ["time"], optional = true } +tokio = { version = "1.39.2", features = ["time", "sync"] } [dev-dependencies] diff --git a/zebra-node-services/src/mempool.rs b/zebra-node-services/src/mempool.rs index 98c1969bbad..fbaaf029c75 100644 --- a/zebra-node-services/src/mempool.rs +++ b/zebra-node-services/src/mempool.rs @@ -4,6 +4,7 @@ use std::collections::HashSet; +use tokio::sync::oneshot; use zebra_chain::transaction::{self, UnminedTx, UnminedTxId}; #[cfg(feature = "getblocktemplate-rpcs")] @@ -114,13 +115,11 @@ pub enum Response { /// Returns matching cached rejected [`UnminedTxId`]s from the mempool, RejectedTransactionIds(HashSet), - /// Returns a list of queue results. - /// - /// These are the results of the initial queue checks. - /// The transaction may also fail download or verification later. + /// Returns a list of initial queue checks results and a oneshot receiver + /// for awaiting download and/or verification results. /// /// Each result matches the request at the corresponding vector index. - Queued(Vec>), + Queued(Vec>, BoxError>>), /// Confirms that the mempool has checked for recently verified transactions. CheckedForVerifiedTransactions, diff --git a/zebra-rpc/src/methods.rs b/zebra-rpc/src/methods.rs index ae5deb7a5b9..471d542922c 100644 --- a/zebra-rpc/src/methods.rs +++ b/zebra-rpc/src/methods.rs @@ -664,7 +664,7 @@ where let response = mempool.oneshot(request).await.map_server_error()?; - let queue_results = match response { + let mut queue_results = match response { mempool::Response::Queued(results) => results, _ => unreachable!("incorrect response variant from mempool service"), }; @@ -675,10 +675,17 @@ where "mempool service returned more results than expected" ); - tracing::debug!("sent transaction to mempool: {:?}", &queue_results[0]); + let queue_result = queue_results + .pop() + .expect("there should be exactly one item in Vec") + .inspect_err(|err| tracing::debug!("sent transaction to mempool: {:?}", &err)) + .map_server_error()? + .await; + + tracing::debug!("sent transaction to mempool: {:?}", &queue_result); - queue_results[0] - .as_ref() + queue_result + .map_server_error()? .map(|_| SentTransactionHash(transaction_hash)) .map_server_error() } diff --git a/zebra-rpc/src/methods/tests/prop.rs b/zebra-rpc/src/methods/tests/prop.rs index c2a9c70a348..409a6aefe52 100644 --- a/zebra-rpc/src/methods/tests/prop.rs +++ b/zebra-rpc/src/methods/tests/prop.rs @@ -7,6 +7,7 @@ use hex::ToHex; use jsonrpc_core::{Error, ErrorCode}; use proptest::{collection::vec, prelude::*}; use thiserror::Error; +use tokio::sync::oneshot; use tower::buffer::Buffer; use zebra_chain::{ @@ -61,7 +62,9 @@ proptest! { let unmined_transaction = UnminedTx::from(transaction); let expected_request = mempool::Request::Queue(vec![unmined_transaction.into()]); - let response = mempool::Response::Queued(vec![Ok(())]); + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Ok(())); + let response = mempool::Response::Queued(vec![Ok(rsp_rx)]); mempool .expect_request(expected_request) @@ -111,10 +114,10 @@ proptest! { .expect("Transaction serializes successfully"); let transaction_hex = hex::encode(&transaction_bytes); - let send_task = tokio::spawn(rpc.send_raw_transaction(transaction_hex)); + let send_task = tokio::spawn(rpc.send_raw_transaction(transaction_hex.clone())); let unmined_transaction = UnminedTx::from(transaction); - let expected_request = mempool::Request::Queue(vec![unmined_transaction.into()]); + let expected_request = mempool::Request::Queue(vec![unmined_transaction.clone().into()]); mempool .expect_request(expected_request) @@ -138,6 +141,32 @@ proptest! { "Result is not a server error: {result:?}" ); + let send_task = tokio::spawn(rpc.send_raw_transaction(transaction_hex)); + + let expected_request = mempool::Request::Queue(vec![unmined_transaction.clone().into()]); + + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Err("any verification error".into())); + mempool + .expect_request(expected_request) + .await? + .respond(Ok::<_, BoxError>(mempool::Response::Queued(vec![Ok(rsp_rx)]))); + + let result = send_task + .await + .expect("Sending raw transactions should not panic"); + + prop_assert!( + matches!( + result, + Err(Error { + code: ErrorCode::ServerError(_), + .. + }) + ), + "Result is not a server error: {result:?}" + ); + // The queue task should continue without errors or panics let rpc_tx_queue_task_result = rpc_tx_queue_task_handle.now_or_never(); prop_assert!(rpc_tx_queue_task_result.is_none()); @@ -897,7 +926,9 @@ proptest! { // now a retry will be sent to the mempool let expected_request = mempool::Request::Queue(vec![mempool::Gossip::Tx(tx_unmined.clone())]); - let response = mempool::Response::Queued(vec![Ok(())]); + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Ok(())); + let response = mempool::Response::Queued(vec![Ok(rsp_rx)]); mempool .expect_request(expected_request) @@ -997,7 +1028,9 @@ proptest! { for tx in txs.clone() { let expected_request = mempool::Request::Queue(vec![mempool::Gossip::Tx(UnminedTx::from(tx))]); - let response = mempool::Response::Queued(vec![Ok(())]); + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Ok(())); + let response = mempool::Response::Queued(vec![Ok(rsp_rx)]); mempool .expect_request(expected_request) diff --git a/zebra-rpc/src/queue/tests/prop.rs b/zebra-rpc/src/queue/tests/prop.rs index 1db9a340f2e..9f63ecce24d 100644 --- a/zebra-rpc/src/queue/tests/prop.rs +++ b/zebra-rpc/src/queue/tests/prop.rs @@ -5,7 +5,7 @@ use std::{collections::HashSet, env, sync::Arc}; use proptest::prelude::*; use chrono::Duration; -use tokio::time; +use tokio::{sync::oneshot, time}; use tower::ServiceExt; use zebra_chain::{ @@ -196,7 +196,9 @@ proptest! { let request = Request::Queue(vec![Gossip::Tx(unmined_transaction.clone())]); let expected_request = Request::Queue(vec![Gossip::Tx(unmined_transaction.clone())]); let send_task = tokio::spawn(mempool.clone().oneshot(request)); - let response = Response::Queued(vec![Ok(())]); + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Ok(())); + let response = Response::Queued(vec![Ok(rsp_rx)]); mempool .expect_request(expected_request) @@ -337,7 +339,9 @@ proptest! { // retry will queue the transaction to mempool let gossip = Gossip::Tx(UnminedTx::from(transaction.clone())); let expected_request = Request::Queue(vec![gossip]); - let response = Response::Queued(vec![Ok(())]); + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Ok(())); + let response = Response::Queued(vec![Ok(rsp_rx)]); mempool .expect_request(expected_request) diff --git a/zebrad/src/components/mempool.rs b/zebrad/src/components/mempool.rs index 2d9b2b3e0c5..05732ddaac2 100644 --- a/zebrad/src/components/mempool.rs +++ b/zebrad/src/components/mempool.rs @@ -27,7 +27,7 @@ use std::{ }; use futures::{future::FutureExt, stream::Stream}; -use tokio::sync::broadcast; +use tokio::sync::{broadcast, oneshot}; use tokio_stream::StreamExt; use tower::{buffer::Buffer, timeout::Timeout, util::BoxService, Service}; @@ -560,7 +560,7 @@ impl Service for Mempool { for tx in tx_retries { // This is just an efficiency optimisation, so we don't care if queueing // transaction requests fails. - let _result = tx_downloads.download_if_needed_and_verify(tx); + let _result = tx_downloads.download_if_needed_and_verify(tx, None); } } @@ -608,8 +608,8 @@ impl Service for Mempool { tracing::trace!("chain grew during tx verification, retrying ..",); // We don't care if re-queueing the transaction request fails. - let _result = - tx_downloads.download_if_needed_and_verify(tx.transaction.into()); + let _result = tx_downloads + .download_if_needed_and_verify(tx.transaction.into(), None); } } Ok(Err((txid, error))) => { @@ -758,16 +758,24 @@ impl Service for Mempool { Request::Queue(gossiped_txs) => { trace!(req_count = ?gossiped_txs.len(), "got mempool Queue request"); - let rsp: Vec> = gossiped_txs - .into_iter() - .map(|gossiped_tx| -> Result<(), MempoolError> { - storage.should_download_or_verify(gossiped_tx.id())?; - tx_downloads.download_if_needed_and_verify(gossiped_tx)?; - - Ok(()) - }) - .map(|result| result.map_err(BoxError::from)) - .collect(); + let rsp: Vec>, BoxError>> = + gossiped_txs + .into_iter() + .map( + |gossiped_tx| -> Result< + oneshot::Receiver>, + MempoolError, + > { + let (rsp_tx, rsp_rx) = oneshot::channel(); + storage.should_download_or_verify(gossiped_tx.id())?; + tx_downloads + .download_if_needed_and_verify(gossiped_tx, Some(rsp_tx))?; + + Ok(rsp_rx) + }, + ) + .map(|result| result.map_err(BoxError::from)) + .collect(); // We've added transactions to the queue self.update_metrics(); diff --git a/zebrad/src/components/mempool/crawler/tests/prop.rs b/zebrad/src/components/mempool/crawler/tests/prop.rs index fa1e3ef5785..524d754cfdc 100644 --- a/zebrad/src/components/mempool/crawler/tests/prop.rs +++ b/zebrad/src/components/mempool/crawler/tests/prop.rs @@ -6,7 +6,7 @@ use proptest::{ collection::{hash_set, vec}, prelude::*, }; -use tokio::time; +use tokio::{sync::oneshot, time}; use zebra_chain::{ chain_sync_status::ChainSyncStatus, parameters::Network, transaction::UnminedTxId, @@ -317,9 +317,17 @@ async fn respond_to_queue_request( expected_transaction_ids: HashSet, response: impl IntoIterator>, ) -> Result<(), TestCaseError> { - let response = response + let response: Vec>, BoxError>> = response .into_iter() - .map(|result| result.map_err(BoxError::from)) + .map(|result| { + result + .map(|_| { + let (rsp_tx, rsp_rx) = oneshot::channel(); + let _ = rsp_tx.send(Ok(())); + rsp_rx + }) + .map_err(BoxError::from) + }) .collect(); mempool diff --git a/zebrad/src/components/mempool/downloads.rs b/zebrad/src/components/mempool/downloads.rs index d3f62b4087b..b37f988dcc8 100644 --- a/zebrad/src/components/mempool/downloads.rs +++ b/zebrad/src/components/mempool/downloads.rs @@ -51,7 +51,7 @@ use zebra_chain::{ use zebra_consensus::transaction as tx; use zebra_network as zn; use zebra_node_services::mempool::Gossip; -use zebra_state as zs; +use zebra_state::{self as zs, CloneError}; use crate::components::sync::{BLOCK_DOWNLOAD_TIMEOUT, BLOCK_VERIFY_TIMEOUT}; @@ -105,17 +105,17 @@ pub const MAX_INBOUND_CONCURRENCY: usize = 25; struct CancelDownloadAndVerify; /// Errors that can occur while downloading and verifying a transaction. -#[derive(Error, Debug)] +#[derive(Error, Debug, Clone)] #[allow(dead_code)] pub enum TransactionDownloadVerifyError { #[error("transaction is already in state")] InState, #[error("error in state service")] - StateError(#[source] BoxError), + StateError(#[source] CloneError), #[error("error downloading transaction")] - DownloadFailed(#[source] BoxError), + DownloadFailed(#[source] CloneError), #[error("transaction download / verification was cancelled")] Cancelled, @@ -243,6 +243,7 @@ where pub fn download_if_needed_and_verify( &mut self, gossiped_tx: Gossip, + rsp_tx: Option>>, ) -> Result<(), MempoolError> { let txid = gossiped_tx.id(); @@ -295,7 +296,7 @@ where Ok((Some(height), next_height)) } Ok(_) => unreachable!("wrong response"), - Err(e) => Err(TransactionDownloadVerifyError::StateError(e)), + Err(e) => Err(TransactionDownloadVerifyError::StateError(e.into())), }?; trace!(?txid, ?next_height, "got next height"); @@ -307,11 +308,12 @@ where let tx = match network .oneshot(req) .await + .map_err(CloneError::from) .map_err(TransactionDownloadVerifyError::DownloadFailed)? { zn::Response::Transactions(mut txs) => txs.pop().ok_or_else(|| { TransactionDownloadVerifyError::DownloadFailed( - "no transactions returned".into(), + BoxError::from("no transactions returned").into(), ) })?, _ => unreachable!("wrong response to transaction request"), @@ -373,7 +375,7 @@ where let task = tokio::spawn(async move { // Prefer the cancel handle if both are ready. - tokio::select! { + let result = tokio::select! { biased; _ = &mut cancel_rx => { trace!("task cancelled prior to completion"); @@ -381,7 +383,19 @@ where Err((TransactionDownloadVerifyError::Cancelled, txid)) } verification = fut => verification, + }; + + // Send the result to responder channel if one was provided. + if let Some(rsp_tx) = rsp_tx { + let _ = rsp_tx.send( + result + .as_ref() + .map(|_| ()) + .map_err(|(err, _)| err.clone().into()), + ); } + + result }); self.pending.push(task); @@ -458,6 +472,7 @@ where match state .ready() .await + .map_err(CloneError::from) .map_err(TransactionDownloadVerifyError::StateError)? .call(zs::Request::Transaction(txid.mined_id())) .await @@ -465,7 +480,7 @@ where Ok(zs::Response::Transaction(None)) => Ok(()), Ok(zs::Response::Transaction(Some(_))) => Err(TransactionDownloadVerifyError::InState), Ok(_) => unreachable!("wrong response"), - Err(e) => Err(TransactionDownloadVerifyError::StateError(e)), + Err(e) => Err(TransactionDownloadVerifyError::StateError(e.into())), }?; Ok(()) diff --git a/zebrad/src/components/mempool/tests/vector.rs b/zebrad/src/components/mempool/tests/vector.rs index 2868fef2e65..c285923fa7d 100644 --- a/zebrad/src/components/mempool/tests/vector.rs +++ b/zebrad/src/components/mempool/tests/vector.rs @@ -445,12 +445,17 @@ async fn mempool_cancel_mined() -> Result<(), Report> { .call(Request::Queue(vec![txid.into()])) .await .unwrap(); - let queued_responses = match response { + let mut queued_responses = match response { Response::Queued(queue_responses) => queue_responses, _ => unreachable!("will never happen in this test"), }; assert_eq!(queued_responses.len(), 1); - assert!(queued_responses[0].is_ok()); + + let queued_response = queued_responses + .pop() + .expect("already checked that there is exactly 1 item in Vec") + .expect("initial queue checks result should be Ok"); + assert_eq!(mempool.tx_downloads().in_flight(), 1); // Push block 2 to the state @@ -489,6 +494,14 @@ async fn mempool_cancel_mined() -> Result<(), Report> { // Check if download was cancelled. assert_eq!(mempool.tx_downloads().in_flight(), 0); + assert!( + queued_response + .await + .expect("channel should not be closed") + .is_err(), + "queued tx should fail to download and verify due to chain tip change" + ); + Ok(()) } From 53c65b675b1ce50905f145412b8e18fcc56a98d3 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Mon, 2 Sep 2024 10:39:29 +0200 Subject: [PATCH 06/46] Trigger CI From 9a616f46a5087e8598eb0e5e6d657b0206907fd2 Mon Sep 17 00:00:00 2001 From: Marek Date: Mon, 2 Sep 2024 21:00:26 +0200 Subject: [PATCH 07/46] fix(deps): Replace `serde_yaml` by `serde_yml` (#8825) * Use `serde_yml` instead of `serde_yaml` * Regenerate `openapi.yaml` --- Cargo.lock | 32 +++++++----- openapi.yaml | 52 +++++++++---------- supply-chain/config.toml | 5 -- zebra-utils/Cargo.toml | 4 +- zebra-utils/src/bin/openapi-generator/main.rs | 4 +- 5 files changed, 49 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5169cf98dc..ae84f840965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2434,6 +2434,16 @@ dependencies = [ "lz4-sys", ] +[[package]] +name = "libyml" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" +dependencies = [ + "anyhow", + "version_check", +] + [[package]] name = "libz-sys" version = "1.1.18" @@ -4071,16 +4081,18 @@ dependencies = [ ] [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "serde_yml" +version = "0.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" dependencies = [ "indexmap 2.3.0", "itoa", + "libyml", + "memchr", "ryu", "serde", - "unsafe-libyaml", + "version_check", ] [[package]] @@ -5018,12 +5030,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "untrusted" version = "0.9.0" @@ -5108,9 +5114,9 @@ dependencies = [ [[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" @@ -6318,7 +6324,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "serde_yaml", + "serde_yml", "structopt", "syn 2.0.72", "thiserror", diff --git a/openapi.yaml b/openapi.yaml index 2a7636a90b7..10ac6bfdf61 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -28,7 +28,7 @@ paths: default: getinfo id: type: string - default: x2r3lRddGL + default: VuJXrxLSw8 params: type: array items: {} @@ -61,7 +61,7 @@ paths: default: getblockchaininfo id: type: string - default: w8Lb0nAvLd + default: HDVqYXM9m6 params: type: array items: {} @@ -99,7 +99,7 @@ paths: default: getaddressbalance id: type: string - default: QbTztoTvRo + default: Xw5TDBKXGl params: type: array items: {} @@ -147,7 +147,7 @@ paths: default: sendrawtransaction id: type: string - default: aDK5RQWj16 + default: QaJv2bXyZu params: type: array items: {} @@ -196,7 +196,7 @@ paths: default: getblock id: type: string - default: xxCP1d61X0 + default: k0DACJrgZs params: type: array items: {} @@ -239,7 +239,7 @@ paths: default: getbestblockhash id: type: string - default: DoZgd1j7xW + default: rIFaLhZwHF params: type: array items: {} @@ -272,7 +272,7 @@ paths: default: getbestblockheightandhash id: type: string - default: 0iUFHsOjk3 + default: oxrhh1swvh params: type: array items: {} @@ -305,7 +305,7 @@ paths: default: getrawmempool id: type: string - default: WXG2c6FcCK + default: E7oUD34jk2 params: type: array items: {} @@ -343,7 +343,7 @@ paths: default: z_gettreestate id: type: string - default: 38P0xXV0do + default: Hp22XK728i params: type: array items: {} @@ -393,7 +393,7 @@ paths: default: z_getsubtreesbyindex id: type: string - default: 662iR8VZGT + default: Cs69hg68pl params: type: array items: {} @@ -432,7 +432,7 @@ paths: default: getrawtransaction id: type: string - default: UuvVrzSzqC + default: iu395PEErc params: type: array items: {} @@ -480,7 +480,7 @@ paths: default: getaddresstxids id: type: string - default: KMss2wDMwH + default: z3lOKfsQdp params: type: array items: {} @@ -528,7 +528,7 @@ paths: default: getaddressutxos id: type: string - default: 4Y6BAhe6Lf + default: '7U4Q4dSxej' params: type: array items: {} @@ -571,7 +571,7 @@ paths: default: getblockcount id: type: string - default: nzPm5W3X1G + default: '8yw3EX7Cwi' params: type: array items: {} @@ -609,7 +609,7 @@ paths: default: getblockhash id: type: string - default: KLKosq2Z8E + default: ndDYksCl9E params: type: array items: {} @@ -657,7 +657,7 @@ paths: default: getblocktemplate id: type: string - default: spj7gKe2AA + default: lJi2hfxty1 params: type: array items: {} @@ -695,7 +695,7 @@ paths: default: submitblock id: type: string - default: QOQsC3nA7z + default: '9fEFOdTQle' params: type: array items: {} @@ -728,7 +728,7 @@ paths: default: getmininginfo id: type: string - default: Si3Sdb9ICT + default: Dytpq4f3lF params: type: array items: {} @@ -761,7 +761,7 @@ paths: default: getnetworksolps id: type: string - default: jWvKPdOxDa + default: yX3woRnOaN params: type: array items: {} @@ -794,7 +794,7 @@ paths: default: getnetworkhashps id: type: string - default: wnFwBVFrN0 + default: AyAZMtbezv params: type: array items: {} @@ -827,7 +827,7 @@ paths: default: getpeerinfo id: type: string - default: NpKiq59CE8 + default: nNcrsu3ZAR params: type: array items: {} @@ -865,7 +865,7 @@ paths: default: validateaddress id: type: string - default: PDjTChWgFW + default: LGyfO7zTjW params: type: array items: {} @@ -903,7 +903,7 @@ paths: default: z_validateaddress id: type: string - default: aCeb6xbIuo + default: '2Q09a2Nh4N' params: type: array items: {} @@ -941,7 +941,7 @@ paths: default: getblocksubsidy id: type: string - default: EeBvVXCJon + default: nv6lOWCRso params: type: array items: {} @@ -984,7 +984,7 @@ paths: default: getdifficulty id: type: string - default: jg2K8N0ZG4 + default: '2O3A0PF1SS' params: type: array items: {} @@ -1022,7 +1022,7 @@ paths: default: z_listunifiedreceivers id: type: string - default: Y3gscsg8yT + default: XYgGcDIx2X params: type: array items: {} diff --git a/supply-chain/config.toml b/supply-chain/config.toml index 9ca2020fc37..21bfeebddba 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -1,4 +1,3 @@ - # cargo-vet config file [cargo-vet] @@ -1414,10 +1413,6 @@ criteria = "safe-to-deploy" version = "3.8.1" criteria = "safe-to-deploy" -[[exemptions.serde_yaml]] -version = "0.9.34+deprecated" -criteria = "safe-to-deploy" - [[exemptions.sha2]] version = "0.10.8" criteria = "safe-to-deploy" diff --git a/zebra-utils/Cargo.toml b/zebra-utils/Cargo.toml index 1c873400730..2c1ce74992e 100644 --- a/zebra-utils/Cargo.toml +++ b/zebra-utils/Cargo.toml @@ -77,7 +77,7 @@ openapi-generator = [ "zebra-rpc", "syn", "quote", - "serde_yaml", + "serde_yml", "serde" ] @@ -121,7 +121,7 @@ zcash_protocol.workspace = true rand = "0.8.5" syn = { version = "2.0.72", features = ["full"], optional = true } quote = { version = "1.0.36", optional = true } -serde_yaml = { version = "0.9.34+deprecated", optional = true } +serde_yml = { version = "0.0.12", optional = true } serde = { version = "1.0.204", features = ["serde_derive"], optional = true } indexmap = "2.3.0" diff --git a/zebra-utils/src/bin/openapi-generator/main.rs b/zebra-utils/src/bin/openapi-generator/main.rs index 0935f6560ff..fd0e9fe9b2b 100644 --- a/zebra-utils/src/bin/openapi-generator/main.rs +++ b/zebra-utils/src/bin/openapi-generator/main.rs @@ -174,9 +174,9 @@ fn main() -> Result<(), Box> { let all_methods = Methods { paths: methods }; // Add openapi header and write to file - let yaml_string = serde_yaml::to_string(&all_methods)?; + let yml_string = serde_yml::to_string(&all_methods)?; let mut w = File::create("openapi.yaml")?; - w.write_all(format!("{}{}", create_yaml(), yaml_string).as_bytes())?; + w.write_all(format!("{}{}", create_yaml(), yml_string).as_bytes())?; Ok(()) } From c238847af2f5ad57f537889e87860042af2100bb Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 08:54:05 +0200 Subject: [PATCH 08/46] Add basic CI checks workflow --- .github/workflows/ci-basic.yml | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/ci-basic.yml diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml new file mode 100644 index 00000000000..92dedd60cb0 --- /dev/null +++ b/.github/workflows/ci-basic.yml @@ -0,0 +1,36 @@ +name: Basic checks + +on: [push, pull_request] + +jobs: + test: + name: Test on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + - name: Run tests + run: cargo test --verbose + - name: Verify working directory is clean + run: git diff --exit-code + + doc-links: + name: Intra-doc links + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: cargo fetch + # Requires #![deny(rustdoc::broken_intra_doc_links)] in crates. + - name: Check intra-doc links + run: cargo doc --all-features --document-private-items + + fmt: + name: Rustfmt + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: cargo fmt -- --check From 2c13ae9ab1ffbc6865867ed7f42a2f5d262a3539 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 10:28:32 +0200 Subject: [PATCH 09/46] Fix ci-basic.yml --- .github/workflows/ci-basic.yml | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index 92dedd60cb0..7b50109c04a 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -12,25 +12,13 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install dependencies on Ubuntu + run: sudo apt-get update && sudo apt-get install -y protoc - name: Run tests run: cargo test --verbose - name: Verify working directory is clean run: git diff --exit-code - - doc-links: - name: Intra-doc links - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: cargo fetch - # Requires #![deny(rustdoc::broken_intra_doc_links)] in crates. - - name: Check intra-doc links + - name: Run doc check run: cargo doc --all-features --document-private-items - - fmt: - name: Rustfmt - timeout-minutes: 30 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: cargo fmt -- --check + - name: Run format check + run: cargo fmt -- --check From 5a839c6f2b56f3ca73f16a101b7a34551a4816da Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 10:31:29 +0200 Subject: [PATCH 10/46] Fix ci-basic.yml (2) --- .github/workflows/ci-basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index 7b50109c04a..522329e2440 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install dependencies on Ubuntu - run: sudo apt-get update && sudo apt-get install -y protoc + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - name: Run tests run: cargo test --verbose - name: Verify working directory is clean From 367a14bff6885625577eac433b6b4ccdc5c6600b Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 10:52:49 +0200 Subject: [PATCH 11/46] Add installing of build-essential to ci-basic.yml --- .github/workflows/ci-basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index 522329e2440..be3d44917eb 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install dependencies on Ubuntu - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler build-essential - name: Run tests run: cargo test --verbose - name: Verify working directory is clean From 5541b27a12df19b9b0e21ca5e5c37de6091170af Mon Sep 17 00:00:00 2001 From: Marek Date: Tue, 3 Sep 2024 12:04:36 +0200 Subject: [PATCH 12/46] Remove `shielded-scan` from experimental features (#8827) --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 1ccaa5915a5..a304934455a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -146,7 +146,7 @@ COPY ./docker/entrypoint.sh /etc/zebrad/entrypoint.sh # Entrypoint environment variables ENV ENTRYPOINT_FEATURES=${ENTRYPOINT_FEATURES} # We repeat the ARGs here, so they are available in the entrypoint.sh script for $RUN_ALL_EXPERIMENTAL_TESTS -ARG EXPERIMENTAL_FEATURES="shielded-scan journald prometheus filter-reload" +ARG EXPERIMENTAL_FEATURES="journald prometheus filter-reload" ENV ENTRYPOINT_FEATURES_EXPERIMENTAL="${ENTRYPOINT_FEATURES} ${EXPERIMENTAL_FEATURES}" # By default, runs the entrypoint tests specified by the environmental variables (if any are set) From f2427d62e68a635654f692d8849a32d3fc0e47b5 Mon Sep 17 00:00:00 2001 From: Marek Date: Tue, 3 Sep 2024 15:43:51 +0200 Subject: [PATCH 13/46] add(docs): Add minimal hardware requirements (#8822) * clean-up: Remove outdated note * Add minimal hardware requirements Source & credit: https://x.com/Zerodartz/status/1811460885996798159 * Apply suggestions from code review Co-authored-by: Arya --------- Co-authored-by: Arya Co-authored-by: Pili Guerra --- book/src/user/requirements.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/book/src/user/requirements.md b/book/src/user/requirements.md index df95aa139ba..d908a7487de 100644 --- a/book/src/user/requirements.md +++ b/book/src/user/requirements.md @@ -1,16 +1,22 @@ # System Requirements -We recommend the following requirements for compiling and running `zebrad`: +Zebra has the following hardware requirements. + +## Recommended Requirements - 4 CPU cores - 16 GB RAM -- 300 GB available disk space for building binaries and storing cached chain - state +- 300 GB available disk space - 100 Mbps network connection, with 300 GB of uploads and downloads per month -Zebra's tests can take over an hour, depending on your machine. Note that you -might be able to build and run Zebra on slower systems — we haven't tested its -exact limits yet. +## Minimum Hardware Requirements + +- 2 CPU cores +- 4 GB RAM +- 300 GB available disk space + +[Zebra has successfully run on an Orange Pi Zero 2W with a 512 GB microSD card +without any issues.](https://x.com/Zerodartz/status/1811460885996798159) ## Disk Requirements @@ -48,9 +54,6 @@ networks. - Ongoing updates: 10 MB - 10 GB upload and download per day, depending on user-created transaction size and peer requests. -Zebra performs an initial sync every time its internal database version changes, -so some version upgrades might require a full download of the whole chain. - Zebra needs some peers which have a round-trip latency of 2 seconds or less. If this is a problem for you, please [open a ticket.](https://github.com/ZcashFoundation/zebra/issues/new/choose) From e9bbb9747360f6bf3f9180df85f8563aebd5ae68 Mon Sep 17 00:00:00 2001 From: dismad <81990132+dismad@users.noreply.github.com> Date: Tue, 3 Sep 2024 06:43:57 -0700 Subject: [PATCH 14/46] Update README.md (#8824) typo --- zebra-utils/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra-utils/README.md b/zebra-utils/README.md index 48a887e09dd..2422264ea4a 100644 --- a/zebra-utils/README.md +++ b/zebra-utils/README.md @@ -112,7 +112,7 @@ This program is commonly used as part of `zebrad-log-filter` where hashes will b The program is designed to filter the output from the zebra terminal or log file. Each time a hash is seen the script will capture it and get the additional information using `zebrad-hash-lookup`. -Assuming `zebrad`, `zclash-cli`, `zebrad-hash-lookup` and `zebrad-log-filter` are in your path the program can used as: +Assuming `zebrad`, `zcash-cli`, `zebrad-hash-lookup` and `zebrad-log-filter` are in your path the program can used as: ```sh $ zebrad -v start | zebrad-log-filter From f425747e759a17c8a102bd30985bddb406d60906 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 20:57:11 +0200 Subject: [PATCH 15/46] Try to use librocksdb-dev in ci-basic.yml --- .github/workflows/ci-basic.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index be3d44917eb..547b64446c3 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -1,6 +1,7 @@ name: Basic checks -on: [push, pull_request] +#on: [push, pull_request] +on: [push] jobs: test: @@ -13,9 +14,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install dependencies on Ubuntu - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler build-essential + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler build-essential librocksdb-dev - name: Run tests - run: cargo test --verbose + run: ROCKSDB_LIB_DIR=/usr/lib SNAPPY_LIB_DIR=/usr/lib/x86_64-linux-gnu cargo test --verbose - name: Verify working directory is clean run: git diff --exit-code - name: Run doc check From 831c847d32201ceb7dc0cf6efde9a317a7274d59 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 21:05:06 +0200 Subject: [PATCH 16/46] Run ci-basic.yml on ubuntu-24.04 --- .github/workflows/ci-basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index 547b64446c3..840d406b609 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -9,7 +9,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-24.04] steps: - uses: actions/checkout@v4 From ecaf98d9a04213b2bc0b6e2fc553880a4849bf5a Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Tue, 3 Sep 2024 22:32:19 +0200 Subject: [PATCH 17/46] Enable nu6 cfg flag in ci-basic.yml --- .github/workflows/ci-basic.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index 840d406b609..4a9bdafa1b5 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -11,12 +11,20 @@ jobs: matrix: os: [ubuntu-24.04] + env: + # Use system-installed RocksDB library instead of building from scratch + ROCKSDB_LIB_DIR: /usr/lib + # Use system-installed Snappy library for compression in RocksDB + SNAPPY_LIB_DIR: /usr/lib/x86_64-linux-gnu + # Enable the `nu6` feature in `zcash_protocol` + RUSTFLAGS: '--cfg zcash_unstable="nu6"' + steps: - uses: actions/checkout@v4 - name: Install dependencies on Ubuntu run: sudo apt-get update && sudo apt-get install -y protobuf-compiler build-essential librocksdb-dev - name: Run tests - run: ROCKSDB_LIB_DIR=/usr/lib SNAPPY_LIB_DIR=/usr/lib/x86_64-linux-gnu cargo test --verbose + run: cargo test --verbose - name: Verify working directory is clean run: git diff --exit-code - name: Run doc check From 7d1115990ab39f28035f568ad4d69eadbd764147 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Wed, 4 Sep 2024 10:51:26 +0200 Subject: [PATCH 18/46] Adjust the code with librustzcash/zcash_protocol nu6 related changes --- zebra-chain/Cargo.toml | 4 +++ zebra-chain/src/parameters/network_upgrade.rs | 7 ++++- .../src/primitives/zcash_primitives.rs | 27 ++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index bf9479976ee..44954d31af7 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -176,3 +176,7 @@ required-features = ["bench"] [[bench]] name = "redpallas" harness = false + +# FIXME: remove this and all zcash_unstable usage in the code after updating librustzcash +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(zcash_unstable, values("nu6"))'] } diff --git a/zebra-chain/src/parameters/network_upgrade.rs b/zebra-chain/src/parameters/network_upgrade.rs index 551c4a88801..ab66fbc7895 100644 --- a/zebra-chain/src/parameters/network_upgrade.rs +++ b/zebra-chain/src/parameters/network_upgrade.rs @@ -530,7 +530,12 @@ impl From for NetworkUpgrade { zcash_protocol::consensus::NetworkUpgrade::Heartwood => Self::Heartwood, zcash_protocol::consensus::NetworkUpgrade::Canopy => Self::Canopy, zcash_protocol::consensus::NetworkUpgrade::Nu5 => Self::Nu5, - // FIXME: uncomment this! zcash_protocol::consensus::NetworkUpgrade::Nu6 => Self::Nu6, + // FIXME: remove cfg + #[cfg(zcash_unstable = "nu6")] + zcash_protocol::consensus::NetworkUpgrade::Nu6 => Self::Nu6, + // FIXME: remove cfg and process Nu7 properly (uses Self::Nu6 for now) + #[cfg(zcash_unstable = "nu6")] + zcash_protocol::consensus::NetworkUpgrade::Nu7 => Self::Nu6, } } } diff --git a/zebra-chain/src/primitives/zcash_primitives.rs b/zebra-chain/src/primitives/zcash_primitives.rs index 7ab2f32d751..be90f18ed23 100644 --- a/zebra-chain/src/primitives/zcash_primitives.rs +++ b/zebra-chain/src/primitives/zcash_primitives.rs @@ -137,6 +137,16 @@ impl zp_tx::components::orchard::MapAuth + for IdentityMap +{ + fn map_issue_authorization(&self, s: orchard::issuance::Signed) -> orchard::issuance::Signed { + s + } +} + #[derive(Debug)] struct PrecomputedAuth<'a> { _phantom: std::marker::PhantomData<&'a ()>, @@ -146,6 +156,14 @@ impl<'a> zp_tx::Authorization for PrecomputedAuth<'a> { type TransparentAuth = TransparentAuth<'a>; type SaplingAuth = sapling_crypto::bundle::Authorized; type OrchardAuth = orchard::bundle::Authorized; + + // FIXME: is this correct? + #[cfg(zcash_unstable = "nu6")] + type OrchardZsaAuth = orchard::bundle::Authorized; + + // FIXME: is this correct? + #[cfg(zcash_unstable = "nu6")] + type IssueAuth = orchard::issuance::Signed; } // End of (mostly) copied code @@ -275,7 +293,14 @@ impl<'a> PrecomputedTxData<'a> { }; let tx_data: zp_tx::TransactionData = alt_tx .into_data() - .map_authorization(f_transparent, IdentityMap, IdentityMap); + // FIXME: do we need to pass another arg values or orchard_zsa and issue instead of IdentityMap? + .map_authorization( + f_transparent, + IdentityMap, + IdentityMap, + IdentityMap, + IdentityMap, + ); PrecomputedTxData { tx_data, From 6a0196e9b791f6873b42bb086bc4bfe18ebeb299 Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Wed, 4 Sep 2024 11:40:25 +0200 Subject: [PATCH 19/46] Add RUSTDOCFLAGS to ci-basic.yml --- .github/workflows/ci-basic.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-basic.yml b/.github/workflows/ci-basic.yml index 4a9bdafa1b5..c2cde8686bf 100644 --- a/.github/workflows/ci-basic.yml +++ b/.github/workflows/ci-basic.yml @@ -18,11 +18,13 @@ jobs: SNAPPY_LIB_DIR: /usr/lib/x86_64-linux-gnu # Enable the `nu6` feature in `zcash_protocol` RUSTFLAGS: '--cfg zcash_unstable="nu6"' + RUSTDOCFLAGS: '--cfg zcash_unstable="nu6"' steps: - uses: actions/checkout@v4 - name: Install dependencies on Ubuntu - run: sudo apt-get update && sudo apt-get install -y protobuf-compiler build-essential librocksdb-dev + #run: sudo apt-get update && sudo apt-get install -y protobuf-compiler build-essential librocksdb-dev + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler librocksdb-dev - name: Run tests run: cargo test --verbose - name: Verify working directory is clean From d31eea5f6456966b6183548729d79b7187897b42 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Thu, 5 Sep 2024 14:29:22 +0100 Subject: [PATCH 20/46] ref(docker): use cache mounts for build cache (#8796) * ref(docker): leverage cache mount with bind mounts This update eliminates the need for external tools like `cargo-chef` to leverage caching layers, resulting in an average build time reduction of 4m30s (~36% improvement). While this solution doesn't fully resolve the issues mentioned in https://github.com/ZcashFoundation/zebra/issues/6169#issuecomment-1712776391, it represents the best possible approach without resorting to custom solutions, which we'd prefer to avoid. * chore: remove extra `WORKDIR` and imp comments * chore: improve comment legibility Co-authored-by: Arya --------- Co-authored-by: Pili Guerra Co-authored-by: Arya --- docker/Dockerfile | 174 +++++++++++++++++++++------------------------- 1 file changed, 80 insertions(+), 94 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index a304934455a..c71e3e422f5 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,12 +1,13 @@ +# syntax=docker/dockerfile:1 +# check=skip=UndefinedVar + # If you want to include a file in the Docker image, add it to .dockerignore. # -# We are using five stages: -# - chef: installs cargo-chef -# - planner: computes the recipe file -# - deps: caches our dependencies and sets the needed variables -# - tests: builds tests -# - release: builds release binary -# - runtime: is our runtime environment +# We are using 4 stages: +# - deps: install build dependencies and sets the needed variables +# - tests: builds tests binaries +# - release: builds release binaries +# - runtime: runs the release binaries # # We first set default values for build arguments used across the stages. # Each stage must define the build arguments (ARGs) it uses. @@ -20,29 +21,18 @@ ARG TEST_FEATURES="lightwalletd-grpc-tests zebra-checkpoints" ARG EXPERIMENTAL_FEATURES="" ARG APP_HOME="/opt/zebrad" -# This stage implements cargo-chef for docker layer caching -FROM rust:bookworm as chef -RUN cargo install cargo-chef --locked - -ARG APP_HOME -ENV APP_HOME=${APP_HOME} -WORKDIR ${APP_HOME} - -# Analyze the current project to determine the minimum subset of files -# (Cargo.lock and Cargo.toml manifests) required to build it and cache dependencies -# -# The recipe.json is the equivalent of the Python requirements.txt file -FROM chef AS planner -COPY . . -RUN cargo chef prepare --recipe-path recipe.json - +ARG RUST_VERSION=1.79.0 # In this stage we download all system requirements to build the project # # It also captures all the build arguments to be used as environment variables. # We set defaults for the arguments, in case the build does not include this information. -FROM chef AS deps +FROM rust:${RUST_VERSION}-bookworm AS deps SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -COPY --from=planner ${APP_HOME}/recipe.json recipe.json + +# Set the default path for the zebrad binary +ARG APP_HOME +ENV APP_HOME=${APP_HOME} +WORKDIR ${APP_HOME} # Install zebra build deps and Dockerfile deps RUN apt-get -qq update && \ @@ -52,27 +42,8 @@ RUN apt-get -qq update && \ clang \ ca-certificates \ protobuf-compiler \ - rsync \ rocksdb-tools \ - ; \ - rm -rf /var/lib/apt/lists/* /tmp/* - -# Install google OS Config agent to be able to get information from the VMs being deployed -# into GCP for integration testing purposes, and as Mainnet nodes -# TODO: this shouldn't be a hardcoded requirement for everyone -RUN if [ "$(uname -m)" != "aarch64" ]; then \ - apt-get -qq update && \ - apt-get -qq install -y --no-install-recommends \ - curl \ - lsb-release \ - && \ - echo "deb http://packages.cloud.google.com/apt google-compute-engine-$(lsb_release -cs)-stable main" > /etc/apt/sources.list.d/google-compute-engine.list && \ - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \ - apt-get -qq update && \ - apt-get -qq install -y --no-install-recommends google-osconfig-agent; \ - fi \ - && \ - rm -rf /var/lib/apt/lists/* /tmp/* + && rm -rf /var/lib/apt/lists/* /tmp/* # Build arguments and variables set for tracelog levels and debug information # @@ -90,24 +61,21 @@ ARG COLORBT_SHOW_HIDDEN ENV COLORBT_SHOW_HIDDEN=${COLORBT_SHOW_HIDDEN:-1} ARG SHORT_SHA -# If this is not set, it must be the empty string, so Zebra can try an alternative git commit source: +# If this is not set, it must be an empty string, so Zebra can try an alternative git commit source: # https://github.com/ZcashFoundation/zebra/blob/9ebd56092bcdfc1a09062e15a0574c94af37f389/zebrad/src/application.rs#L179-L182 ENV SHORT_SHA=${SHORT_SHA:-} ENV CARGO_HOME="${APP_HOME}/.cargo/" +# Copy the entrypoint script to be used on both images +COPY ./docker/entrypoint.sh /etc/zebrad/entrypoint.sh + # In this stage we build tests (without running then) # # We also download needed dependencies for tests to work, from other images. # An entrypoint.sh is only available in this step for easier test handling with variables. FROM deps AS tests -COPY --from=electriccoinco/lightwalletd:latest /usr/local/bin/lightwalletd /usr/local/bin/ - -# cargo uses timestamps for its cache, so they need to be in this order: -# unmodified source files < previous build cache < modified source files -COPY . . - # Skip IPv6 tests by default, as some CI environment don't have IPv6 available ARG ZEBRA_SKIP_IPV6_TESTS ENV ZEBRA_SKIP_IPV6_TESTS=${ZEBRA_SKIP_IPV6_TESTS:-1} @@ -120,28 +88,41 @@ ARG EXPERIMENTAL_FEATURES # TODO: add empty $EXPERIMENTAL_FEATURES when we can avoid adding an extra space to the end of the string ARG ENTRYPOINT_FEATURES="${FEATURES} ${TEST_FEATURES}" -# Re-hydrate the minimum project skeleton identified by `cargo chef prepare` in the planner stage, -# over the top of the original source files, -# and build it to cache all possible sentry and test dependencies. -# -# This is the caching Docker layer for Rust tests! -# It creates fake empty test binaries so dependencies are built, but Zebra is not fully built. -# -# TODO: add --locked when cargo-chef supports it -RUN cargo chef cook --tests --release --features "${ENTRYPOINT_FEATURES}" --workspace --recipe-path recipe.json -# Undo the source file changes made by cargo-chef. -# rsync invalidates the cargo cache for the changed files only, by updating their timestamps. -# This makes sure the fake empty binaries created by cargo-chef are rebuilt. -COPY --from=planner ${APP_HOME} zebra-original -RUN rsync --recursive --checksum --itemize-changes --verbose zebra-original/ . -RUN rm -r zebra-original - # Build Zebra test binaries, but don't run them -RUN cargo test --locked --release --features "${ENTRYPOINT_FEATURES}" --workspace --no-run -RUN cp ${APP_HOME}/target/release/zebrad /usr/local/bin -RUN cp ${APP_HOME}/target/release/zebra-checkpoints /usr/local/bin -COPY ./docker/entrypoint.sh /etc/zebrad/entrypoint.sh +# Leverage a cache mount to /usr/local/cargo/registry/ +# for downloaded dependencies, a cache mount to /usr/local/cargo/git/db +# for git repository dependencies, and a cache mount to ${APP_HOME}/target/ for +# compiled dependencies which will speed up subsequent builds. +# Leverage a bind mount to each crate directory to avoid having to copy the +# source code into the container. Once built, copy the executable to an +# output directory before the cache mounted ${APP_HOME}/target/ is unmounted. +RUN --mount=type=bind,source=zebrad,target=zebrad \ + --mount=type=bind,source=zebra-chain,target=zebra-chain \ + --mount=type=bind,source=zebra-network,target=zebra-network \ + --mount=type=bind,source=zebra-state,target=zebra-state \ + --mount=type=bind,source=zebra-script,target=zebra-script \ + --mount=type=bind,source=zebra-consensus,target=zebra-consensus \ + --mount=type=bind,source=zebra-rpc,target=zebra-rpc \ + --mount=type=bind,source=zebra-node-services,target=zebra-node-services \ + --mount=type=bind,source=zebra-test,target=zebra-test \ + --mount=type=bind,source=zebra-utils,target=zebra-utils \ + --mount=type=bind,source=zebra-scan,target=zebra-scan \ + --mount=type=bind,source=zebra-grpc,target=zebra-grpc \ + --mount=type=bind,source=tower-batch-control,target=tower-batch-control \ + --mount=type=bind,source=tower-fallback,target=tower-fallback \ + --mount=type=bind,source=Cargo.toml,target=Cargo.toml \ + --mount=type=bind,source=Cargo.lock,target=Cargo.lock \ + --mount=type=cache,target=${APP_HOME}/target/ \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/usr/local/cargo/registry/ \ +cargo test --locked --release --features "${ENTRYPOINT_FEATURES}" --workspace --no-run && \ +cp ${APP_HOME}/target/release/zebrad /usr/local/bin && \ +cp ${APP_HOME}/target/release/zebra-checkpoints /usr/local/bin + +# Copy the lightwalletd binary and source files to be able to run tests +COPY --from=electriccoinco/lightwalletd:latest /usr/local/bin/lightwalletd /usr/local/bin/ +COPY ./ ./ # Entrypoint environment variables ENV ENTRYPOINT_FEATURES=${ENTRYPOINT_FEATURES} @@ -154,30 +135,34 @@ ENTRYPOINT [ "/etc/zebrad/entrypoint.sh" ] # In this stage we build a release (generate the zebrad binary) # -# This step also adds `cargo chef` as this stage is completely independent from the +# This step also adds `cache mounts` as this stage is completely independent from the # `test` stage. This step is a dependency for the `runtime` stage, which uses the resulting # zebrad binary from this step. FROM deps AS release -COPY . . - ARG FEATURES -# This is the caching layer for Rust zebrad builds. -# It creates a fake empty zebrad binary, see above for details. -# -# TODO: add --locked when cargo-chef supports it -RUN cargo chef cook --release --features "${FEATURES}" --package zebrad --bin zebrad --recipe-path recipe.json - -# Undo the source file changes made by cargo-chef, so the fake empty zebrad binary is rebuilt. -COPY --from=planner ${APP_HOME} zebra-original -RUN rsync --recursive --checksum --itemize-changes --verbose zebra-original/ . -RUN rm -r zebra-original - -# Build zebrad -RUN cargo build --locked --release --features "${FEATURES}" --package zebrad --bin zebrad - -COPY ./docker/entrypoint.sh ./ +RUN --mount=type=bind,source=tower-batch-control,target=tower-batch-control \ + --mount=type=bind,source=tower-fallback,target=tower-fallback \ + --mount=type=bind,source=zebra-chain,target=zebra-chain \ + --mount=type=bind,source=zebra-consensus,target=zebra-consensus \ + --mount=type=bind,source=zebra-grpc,target=zebra-grpc \ + --mount=type=bind,source=zebra-network,target=zebra-network \ + --mount=type=bind,source=zebra-node-services,target=zebra-node-services \ + --mount=type=bind,source=zebra-rpc,target=zebra-rpc \ + --mount=type=bind,source=zebra-scan,target=zebra-scan \ + --mount=type=bind,source=zebra-script,target=zebra-script \ + --mount=type=bind,source=zebra-state,target=zebra-state \ + --mount=type=bind,source=zebra-test,target=zebra-test \ + --mount=type=bind,source=zebra-utils,target=zebra-utils \ + --mount=type=bind,source=zebrad,target=zebrad \ + --mount=type=bind,source=Cargo.toml,target=Cargo.toml \ + --mount=type=bind,source=Cargo.lock,target=Cargo.lock \ + --mount=type=cache,target=${APP_HOME}/target/ \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/usr/local/cargo/registry/ \ +cargo build --locked --release --features "${FEATURES}" --package zebrad --bin zebrad && \ +cp ${APP_HOME}/target/release/zebrad /usr/local/bin # This stage is only used when deploying nodes or when only the resulting zebrad binary is needed # @@ -196,8 +181,7 @@ RUN apt-get update && \ curl \ rocksdb-tools \ gosu \ - && \ - rm -rf /var/lib/apt/lists/* /tmp/* + && rm -rf /var/lib/apt/lists/* /tmp/* # Create a non-privileged user that the app will run under. # Running as root inside the container is running as root in the Docker host @@ -215,6 +199,7 @@ RUN addgroup --system --gid ${GID} ${USER} \ --system \ --disabled-login \ --shell /bin/bash \ + --home ${APP_HOME} \ --uid "${UID}" \ --gid "${GID}" \ ${USER} @@ -224,14 +209,15 @@ ARG FEATURES ENV FEATURES=${FEATURES} # Path and name of the config file +# These are set to a default value when not defined in the environment ENV ZEBRA_CONF_DIR=${ZEBRA_CONF_DIR:-/etc/zebrad} ENV ZEBRA_CONF_FILE=${ZEBRA_CONF_FILE:-zebrad.toml} RUN mkdir -p ${ZEBRA_CONF_DIR} && chown ${UID}:${UID} ${ZEBRA_CONF_DIR} \ && chown ${UID}:${UID} ${APP_HOME} -COPY --from=release ${APP_HOME}/target/release/zebrad /usr/local/bin -COPY --from=release ${APP_HOME}/entrypoint.sh /etc/zebrad +COPY --from=release /usr/local/bin/zebrad /usr/local/bin +COPY --from=release /etc/zebrad/entrypoint.sh /etc/zebrad # Expose configured ports EXPOSE 8233 18233 From 17d7f914a8fae07fd3b63e05b4f35e18500d53d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 18:28:11 +0000 Subject: [PATCH 21/46] build(deps): bump tj-actions/changed-files in the devops group (#8835) Bumps the devops group with 1 update: [tj-actions/changed-files](https://github.com/tj-actions/changed-files). Updates `tj-actions/changed-files` from 45.0.0 to 45.0.1 - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v45.0.0...v45.0.1) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-patch dependency-group: devops ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index 3137dee49db..87b60204746 100644 --- a/.github/workflows/ci-lint.yml +++ b/.github/workflows/ci-lint.yml @@ -44,7 +44,7 @@ jobs: - name: Rust files id: changed-files-rust - uses: tj-actions/changed-files@v45.0.0 + uses: tj-actions/changed-files@v45.0.1 with: files: | **/*.rs @@ -56,7 +56,7 @@ jobs: - name: Workflow files id: changed-files-workflows - uses: tj-actions/changed-files@v45.0.0 + uses: tj-actions/changed-files@v45.0.1 with: files: | .github/workflows/*.yml From 151199782912d085d1ab0bfc6fa68cd061e0e867 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Fri, 6 Sep 2024 12:24:15 -0300 Subject: [PATCH 22/46] fix clippy lints (#8855) --- zebra-state/src/service/finalized_state/zebra_db/block.rs | 1 + zebrad/src/components/mempool/downloads.rs | 1 + zebrad/tests/common/checkpoints.rs | 2 +- zebrad/tests/common/get_block_template_rpcs/get_peer_info.rs | 2 +- zebrad/tests/common/get_block_template_rpcs/submit_block.rs | 2 +- zebrad/tests/common/lightwalletd/send_transaction_test.rs | 2 +- 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/zebra-state/src/service/finalized_state/zebra_db/block.rs b/zebra-state/src/service/finalized_state/zebra_db/block.rs index e10fd3b43b4..4dc3a801ef3 100644 --- a/zebra-state/src/service/finalized_state/zebra_db/block.rs +++ b/zebra-state/src/service/finalized_state/zebra_db/block.rs @@ -290,6 +290,7 @@ impl ZebraDb { /// /// - Propagates any errors from writing to the DB /// - Propagates any errors from updating history and note commitment trees + #[allow(clippy::unwrap_in_result)] pub(in super::super) fn write_block( &mut self, finalized: FinalizedBlock, diff --git a/zebrad/src/components/mempool/downloads.rs b/zebrad/src/components/mempool/downloads.rs index b37f988dcc8..eeda6bd9567 100644 --- a/zebrad/src/components/mempool/downloads.rs +++ b/zebrad/src/components/mempool/downloads.rs @@ -240,6 +240,7 @@ where /// /// Returns the action taken in response to the queue request. #[instrument(skip(self, gossiped_tx), fields(txid = %gossiped_tx.id()))] + #[allow(clippy::unwrap_in_result)] pub fn download_if_needed_and_verify( &mut self, gossiped_tx: Gossip, diff --git a/zebrad/tests/common/checkpoints.rs b/zebrad/tests/common/checkpoints.rs index 602525fd926..c1c0ae44716 100644 --- a/zebrad/tests/common/checkpoints.rs +++ b/zebrad/tests/common/checkpoints.rs @@ -136,7 +136,7 @@ pub async fn run(network: Network) -> Result<()> { ?zebra_rpc_address, "waiting for zebrad to open its RPC port...", ); - zebrad.expect_stdout_line_matches(&format!("Opened RPC endpoint at {zebra_rpc_address}"))?; + zebrad.expect_stdout_line_matches(format!("Opened RPC endpoint at {zebra_rpc_address}"))?; tracing::info!( ?network, diff --git a/zebrad/tests/common/get_block_template_rpcs/get_peer_info.rs b/zebrad/tests/common/get_block_template_rpcs/get_peer_info.rs index 4ca0bc797ad..dd30954948c 100644 --- a/zebrad/tests/common/get_block_template_rpcs/get_peer_info.rs +++ b/zebrad/tests/common/get_block_template_rpcs/get_peer_info.rs @@ -34,7 +34,7 @@ pub(crate) async fn run() -> Result<()> { let rpc_address = zebra_rpc_address.expect("getpeerinfo test must have RPC port"); // Wait until port is open. - zebrad.expect_stdout_line_matches(&format!("Opened RPC endpoint at {rpc_address}"))?; + zebrad.expect_stdout_line_matches(format!("Opened RPC endpoint at {rpc_address}"))?; tracing::info!(?rpc_address, "zebrad opened its RPC port",); diff --git a/zebrad/tests/common/get_block_template_rpcs/submit_block.rs b/zebrad/tests/common/get_block_template_rpcs/submit_block.rs index 28f48fb2c14..399efc8d99e 100644 --- a/zebrad/tests/common/get_block_template_rpcs/submit_block.rs +++ b/zebrad/tests/common/get_block_template_rpcs/submit_block.rs @@ -59,7 +59,7 @@ pub(crate) async fn run() -> Result<()> { ?rpc_address, "spawned isolated zebrad with shorter chain, waiting for zebrad to open its RPC port..." ); - zebrad.expect_stdout_line_matches(&format!("Opened RPC endpoint at {rpc_address}"))?; + zebrad.expect_stdout_line_matches(format!("Opened RPC endpoint at {rpc_address}"))?; tracing::info!(?rpc_address, "zebrad opened its RPC port",); diff --git a/zebrad/tests/common/lightwalletd/send_transaction_test.rs b/zebrad/tests/common/lightwalletd/send_transaction_test.rs index f9087771595..bee6cf78356 100644 --- a/zebrad/tests/common/lightwalletd/send_transaction_test.rs +++ b/zebrad/tests/common/lightwalletd/send_transaction_test.rs @@ -118,7 +118,7 @@ pub async fn run() -> Result<()> { ?zebra_rpc_address, "spawned isolated zebrad with shorter chain, waiting for zebrad to open its RPC port..." ); - zebrad.expect_stdout_line_matches(&format!("Opened RPC endpoint at {zebra_rpc_address}"))?; + zebrad.expect_stdout_line_matches(format!("Opened RPC endpoint at {zebra_rpc_address}"))?; tracing::info!( ?zebra_rpc_address, From 554a37d20a08f02312508bc6c4e18844ec44ff21 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 9 Sep 2024 10:02:35 -0300 Subject: [PATCH 23/46] feat(rpc): Add a `stop` rpc method (#8839) * add a `stop` rpc method * add todo comment * add a ticket number to the TODO Co-authored-by: Marek --------- Co-authored-by: Marek Co-authored-by: Pili Guerra --- openapi.yaml | 85 +++++++++++++------ zebra-rpc/src/methods.rs | 25 ++++++ zebra-utils/src/bin/openapi-generator/main.rs | 1 + 3 files changed, 85 insertions(+), 26 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 10ac6bfdf61..e7793967118 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -28,7 +28,7 @@ paths: default: getinfo id: type: string - default: VuJXrxLSw8 + default: QWlDS9bxlK params: type: array items: {} @@ -61,7 +61,7 @@ paths: default: getblockchaininfo id: type: string - default: HDVqYXM9m6 + default: XSg3wvZykA params: type: array items: {} @@ -99,7 +99,7 @@ paths: default: getaddressbalance id: type: string - default: Xw5TDBKXGl + default: GEd1QJWprH params: type: array items: {} @@ -147,7 +147,7 @@ paths: default: sendrawtransaction id: type: string - default: QaJv2bXyZu + default: nhQi7D6Oru params: type: array items: {} @@ -196,7 +196,7 @@ paths: default: getblock id: type: string - default: k0DACJrgZs + default: qIEYMzgbJZ params: type: array items: {} @@ -239,7 +239,7 @@ paths: default: getbestblockhash id: type: string - default: rIFaLhZwHF + default: P9UBS8IXXU params: type: array items: {} @@ -272,7 +272,7 @@ paths: default: getbestblockheightandhash id: type: string - default: oxrhh1swvh + default: gQNhsomx7N params: type: array items: {} @@ -305,7 +305,7 @@ paths: default: getrawmempool id: type: string - default: E7oUD34jk2 + default: c2ScL31PtX params: type: array items: {} @@ -343,7 +343,7 @@ paths: default: z_gettreestate id: type: string - default: Hp22XK728i + default: JQ0mENKbdm params: type: array items: {} @@ -393,7 +393,7 @@ paths: default: z_getsubtreesbyindex id: type: string - default: Cs69hg68pl + default: bZUCv4t0f4 params: type: array items: {} @@ -432,7 +432,7 @@ paths: default: getrawtransaction id: type: string - default: iu395PEErc + default: I0FAejAi4r params: type: array items: {} @@ -480,7 +480,7 @@ paths: default: getaddresstxids id: type: string - default: z3lOKfsQdp + default: '3fMzDHOglf' params: type: array items: {} @@ -528,7 +528,7 @@ paths: default: getaddressutxos id: type: string - default: '7U4Q4dSxej' + default: LE2AR8Tr6X params: type: array items: {} @@ -554,6 +554,39 @@ paths: error: type: string default: Invalid parameters + /stop: + post: + tags: + - control + description: Stop the running zebrad process. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + method: + type: string + default: stop + id: + type: string + default: PbxxqB0ZpF + params: + type: array + items: {} + default: '[]' + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + result: + type: object + default: 'null' /getblockcount: post: tags: @@ -571,7 +604,7 @@ paths: default: getblockcount id: type: string - default: '8yw3EX7Cwi' + default: WO6BAIKSCg params: type: array items: {} @@ -609,7 +642,7 @@ paths: default: getblockhash id: type: string - default: ndDYksCl9E + default: vHpKNIQRLF params: type: array items: {} @@ -657,7 +690,7 @@ paths: default: getblocktemplate id: type: string - default: lJi2hfxty1 + default: L04jp5F2QW params: type: array items: {} @@ -695,7 +728,7 @@ paths: default: submitblock id: type: string - default: '9fEFOdTQle' + default: Izn7vhiMaA params: type: array items: {} @@ -728,7 +761,7 @@ paths: default: getmininginfo id: type: string - default: Dytpq4f3lF + default: SgyuBQbMik params: type: array items: {} @@ -761,7 +794,7 @@ paths: default: getnetworksolps id: type: string - default: yX3woRnOaN + default: FXg2iH3eaX params: type: array items: {} @@ -794,7 +827,7 @@ paths: default: getnetworkhashps id: type: string - default: AyAZMtbezv + default: '2PWjf8QqfI' params: type: array items: {} @@ -827,7 +860,7 @@ paths: default: getpeerinfo id: type: string - default: nNcrsu3ZAR + default: OE9s5wkP0w params: type: array items: {} @@ -865,7 +898,7 @@ paths: default: validateaddress id: type: string - default: LGyfO7zTjW + default: '6FS4iGA4Ht' params: type: array items: {} @@ -903,7 +936,7 @@ paths: default: z_validateaddress id: type: string - default: '2Q09a2Nh4N' + default: utp8tN61yU params: type: array items: {} @@ -941,7 +974,7 @@ paths: default: getblocksubsidy id: type: string - default: nv6lOWCRso + default: dgNZGo7lNa params: type: array items: {} @@ -984,7 +1017,7 @@ paths: default: getdifficulty id: type: string - default: '2O3A0PF1SS' + default: KEJv30D2MI params: type: array items: {} @@ -1022,7 +1055,7 @@ paths: default: z_listunifiedreceivers id: type: string - default: XYgGcDIx2X + default: lfBqvYghGm params: type: array items: {} diff --git a/zebra-rpc/src/methods.rs b/zebra-rpc/src/methods.rs index 471d542922c..cb894182c1f 100644 --- a/zebra-rpc/src/methods.rs +++ b/zebra-rpc/src/methods.rs @@ -301,6 +301,18 @@ pub trait Rpc { &self, address_strings: AddressStrings, ) -> BoxFuture>>; + + #[rpc(name = "stop")] + /// Stop the running zebrad process. + /// + /// # Notes + /// + /// Only works if the network of the running zebrad process is `Regtest`. + /// + /// zcashd reference: [`stop`](https://zcash.github.io/rpc/stop.html) + /// method: post + /// tags: control + fn stop(&self) -> Result<()>; } /// RPC method implementations. @@ -1344,6 +1356,19 @@ where } .boxed() } + + fn stop(&self) -> Result<()> { + if self.network.is_regtest() { + // TODO: Use graceful termination in `stop` RPC (#8850) + std::process::exit(0); + } else { + Err(Error { + code: ErrorCode::MethodNotFound, + message: "stop is only available on regtest networks".to_string(), + data: None, + }) + } + } } /// Returns the best chain tip height of `latest_chain_tip`, diff --git a/zebra-utils/src/bin/openapi-generator/main.rs b/zebra-utils/src/bin/openapi-generator/main.rs index fd0e9fe9b2b..15e5446d855 100644 --- a/zebra-utils/src/bin/openapi-generator/main.rs +++ b/zebra-utils/src/bin/openapi-generator/main.rs @@ -543,6 +543,7 @@ fn get_default_properties(method_name: &str) -> Result default_property(type_, items.clone(), GetInfo::default())?, + "stop" => default_property(type_, items.clone(), ())?, // transaction "sendrawtransaction" => { default_property(type_, items.clone(), SentTransactionHash::default())? From 082cdad1c1f00a622d21c83a84cb4bfa6797fe06 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 9 Sep 2024 18:51:37 -0300 Subject: [PATCH 24/46] feat(rpc): Add a `generate` rpc method (#8849) * implement `generate` rpc method * update openapi --------- Co-authored-by: Pili Guerra --- openapi.yaml | 102 +++++++++++++----- .../src/methods/get_block_template_rpcs.rs | 77 ++++++++++++- 2 files changed, 150 insertions(+), 29 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index e7793967118..abc70299814 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -28,7 +28,7 @@ paths: default: getinfo id: type: string - default: QWlDS9bxlK + default: dX2SRjFwfc params: type: array items: {} @@ -61,7 +61,7 @@ paths: default: getblockchaininfo id: type: string - default: XSg3wvZykA + default: LoRrjyRM4l params: type: array items: {} @@ -99,7 +99,7 @@ paths: default: getaddressbalance id: type: string - default: GEd1QJWprH + default: WWIvpPiJo0 params: type: array items: {} @@ -147,7 +147,7 @@ paths: default: sendrawtransaction id: type: string - default: nhQi7D6Oru + default: '5tVg2R9ZeI' params: type: array items: {} @@ -196,7 +196,7 @@ paths: default: getblock id: type: string - default: qIEYMzgbJZ + default: vZ5KPOdiue params: type: array items: {} @@ -239,7 +239,7 @@ paths: default: getbestblockhash id: type: string - default: P9UBS8IXXU + default: IifeYgN2ZK params: type: array items: {} @@ -272,7 +272,7 @@ paths: default: getbestblockheightandhash id: type: string - default: gQNhsomx7N + default: tNLKsWqtNW params: type: array items: {} @@ -305,7 +305,7 @@ paths: default: getrawmempool id: type: string - default: c2ScL31PtX + default: IZ6todle9t params: type: array items: {} @@ -343,7 +343,7 @@ paths: default: z_gettreestate id: type: string - default: JQ0mENKbdm + default: SSZAwyUO6t params: type: array items: {} @@ -393,7 +393,7 @@ paths: default: z_getsubtreesbyindex id: type: string - default: bZUCv4t0f4 + default: '3fJMQ0Hfxt' params: type: array items: {} @@ -432,7 +432,7 @@ paths: default: getrawtransaction id: type: string - default: I0FAejAi4r + default: RTdE1YnNxy params: type: array items: {} @@ -480,7 +480,7 @@ paths: default: getaddresstxids id: type: string - default: '3fMzDHOglf' + default: ifahwzVoYe params: type: array items: {} @@ -528,7 +528,7 @@ paths: default: getaddressutxos id: type: string - default: LE2AR8Tr6X + default: PcPdZ7aiKy params: type: array items: {} @@ -571,7 +571,7 @@ paths: default: stop id: type: string - default: PbxxqB0ZpF + default: rWlJLGe7VJ params: type: array items: {} @@ -604,7 +604,7 @@ paths: default: getblockcount id: type: string - default: WO6BAIKSCg + default: f4p3Cb4sDu params: type: array items: {} @@ -642,7 +642,7 @@ paths: default: getblockhash id: type: string - default: vHpKNIQRLF + default: '3QXvqbEWqb' params: type: array items: {} @@ -690,7 +690,7 @@ paths: default: getblocktemplate id: type: string - default: L04jp5F2QW + default: GXKjn81k0D params: type: array items: {} @@ -728,7 +728,7 @@ paths: default: submitblock id: type: string - default: Izn7vhiMaA + default: cwGy92Mwn9 params: type: array items: {} @@ -761,7 +761,7 @@ paths: default: getmininginfo id: type: string - default: SgyuBQbMik + default: '4ZFY9ljh5I' params: type: array items: {} @@ -794,7 +794,7 @@ paths: default: getnetworksolps id: type: string - default: FXg2iH3eaX + default: tJlKGzARjU params: type: array items: {} @@ -827,7 +827,7 @@ paths: default: getnetworkhashps id: type: string - default: '2PWjf8QqfI' + default: '7pUkOt26PB' params: type: array items: {} @@ -860,7 +860,7 @@ paths: default: getpeerinfo id: type: string - default: OE9s5wkP0w + default: JjnSrPKeyS params: type: array items: {} @@ -898,7 +898,7 @@ paths: default: validateaddress id: type: string - default: '6FS4iGA4Ht' + default: pxZQt6VQ9U params: type: array items: {} @@ -936,7 +936,7 @@ paths: default: z_validateaddress id: type: string - default: utp8tN61yU + default: x2R2oRhdZE params: type: array items: {} @@ -974,7 +974,7 @@ paths: default: getblocksubsidy id: type: string - default: dgNZGo7lNa + default: vkhYJS3FH8 params: type: array items: {} @@ -1017,7 +1017,7 @@ paths: default: getdifficulty id: type: string - default: KEJv30D2MI + default: bC6q9c3xYO params: type: array items: {} @@ -1055,7 +1055,7 @@ paths: default: z_listunifiedreceivers id: type: string - default: lfBqvYghGm + default: EQvPXkcJC2 params: type: array items: {} @@ -1071,3 +1071,51 @@ paths: result: type: object default: '{"orchard":"orchard address if any","sapling":"sapling address if any","p2pkh":"p2pkh address if any","p2sh":"p2sh address if any"}' + /generate: + post: + tags: + - generating + description: |- + Mine blocks immediately. Returns the block hashes of the generated blocks. + + **Request body `params` arguments:** + + - `num_blocks` - Number of blocks to be generated. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + method: + type: string + default: generate + id: + type: string + default: w41FKROii3 + params: + type: array + items: {} + default: '[1]' + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + result: + type: object + default: '{}' + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + default: Invalid parameters diff --git a/zebra-rpc/src/methods/get_block_template_rpcs.rs b/zebra-rpc/src/methods/get_block_template_rpcs.rs index c8c83e9315a..826f8d3e930 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs.rs @@ -19,7 +19,7 @@ use zebra_chain::{ Network, NetworkKind, NetworkUpgrade, POW_AVERAGING_WINDOW, }, primitives, - serialization::ZcashDeserializeInto, + serialization::{ZcashDeserializeInto, ZcashSerialize}, transparent::{ self, EXTRA_ZEBRA_COINBASE_DATA, MAX_COINBASE_DATA_LEN, MAX_COINBASE_HEIGHT_DATA_LEN, }, @@ -47,7 +47,9 @@ use crate::methods::{ // TODO: move the types/* modules directly under get_block_template_rpcs, // and combine any modules with the same names. types::{ - get_block_template::GetBlockTemplate, + get_block_template::{ + proposal::TimeSource, proposal_block_from_template, GetBlockTemplate, + }, get_mining_info, long_poll::LongPollInput, peer_info::PeerInfo, @@ -283,6 +285,22 @@ pub trait GetBlockTemplateRpc { &self, address: String, ) -> BoxFuture>; + + #[rpc(name = "generate")] + /// Mine blocks immediately. Returns the block hashes of the generated blocks. + /// + /// # Parameters + /// + /// - `num_blocks`: (numeric, required, example=1) Number of blocks to be generated. + /// + /// # Notes + /// + /// Only works if the network of the running zebrad process is `Regtest`. + /// + /// zcashd reference: [`generate`](https://zcash.github.io/rpc/generate.html) + /// method: post + /// tags: generating + fn generate(&self, num_blocks: u32) -> BoxFuture>>; } /// RPC method implementations. @@ -1357,6 +1375,61 @@ where } .boxed() } + + fn generate(&self, num_blocks: u32) -> BoxFuture>> { + let rpc: GetBlockTemplateRpcImpl< + Mempool, + State, + Tip, + BlockVerifierRouter, + SyncStatus, + AddressBook, + > = self.clone(); + let network = self.network.clone(); + + async move { + if !network.is_regtest() { + return Err(Error { + code: ErrorCode::ServerError(0), + message: "generate is only supported on regtest".to_string(), + data: None, + }); + } + + let mut block_hashes = Vec::new(); + for _ in 0..num_blocks { + let block_template = rpc.get_block_template(None).await.map_server_error()?; + + let get_block_template::Response::TemplateMode(block_template) = block_template + else { + return Err(Error { + code: ErrorCode::ServerError(0), + message: "error generating block template".to_string(), + data: None, + }); + }; + + let proposal_block = proposal_block_from_template( + &block_template, + TimeSource::CurTime, + NetworkUpgrade::current(&network, Height(block_template.height)), + ) + .map_server_error()?; + let hex_proposal_block = + HexData(proposal_block.zcash_serialize_to_vec().map_server_error()?); + + let _submit = rpc + .submit_block(hex_proposal_block, None) + .await + .map_server_error()?; + + block_hashes.push(GetBlockHash(proposal_block.hash())); + } + + Ok(block_hashes) + } + .boxed() + } } // Put support functions in a submodule, to keep this file small. From 3f94303bb24e23f5ee4c3aff39c65d6d3d813243 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 18 Sep 2024 08:05:25 -0300 Subject: [PATCH 25/46] feat(rpc): Add more fields to `getmininginfo` call (#8860) * add additional fields to getmininginfo * update openapi spec * fix zebra-state standalone build * make sure fields are not present when tip is 0 --- openapi.yaml | 58 +++++++++---------- zebra-chain/src/chain_tip/mock.rs | 2 +- .../src/methods/get_block_template_rpcs.rs | 30 ++++++++++ .../types/get_mining_info.rs | 23 +++++++- .../snapshots/get_mining_info@mainnet_10.snap | 2 + .../snapshots/get_mining_info@testnet_10.snap | 2 + zebra-state/src/request.rs | 7 +++ zebra-state/src/response.rs | 6 +- zebra-state/src/service.rs | 43 ++++++++++++++ 9 files changed, 141 insertions(+), 32 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index abc70299814..58a754c9731 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -28,7 +28,7 @@ paths: default: getinfo id: type: string - default: dX2SRjFwfc + default: uf2E54tQkk params: type: array items: {} @@ -61,7 +61,7 @@ paths: default: getblockchaininfo id: type: string - default: LoRrjyRM4l + default: Sbre3vivr8 params: type: array items: {} @@ -99,7 +99,7 @@ paths: default: getaddressbalance id: type: string - default: WWIvpPiJo0 + default: f5qarOBgzK params: type: array items: {} @@ -147,7 +147,7 @@ paths: default: sendrawtransaction id: type: string - default: '5tVg2R9ZeI' + default: IlNHvAcSMS params: type: array items: {} @@ -196,7 +196,7 @@ paths: default: getblock id: type: string - default: vZ5KPOdiue + default: s9678BM3Lc params: type: array items: {} @@ -239,7 +239,7 @@ paths: default: getbestblockhash id: type: string - default: IifeYgN2ZK + default: FGQPJY8Tp8 params: type: array items: {} @@ -272,7 +272,7 @@ paths: default: getbestblockheightandhash id: type: string - default: tNLKsWqtNW + default: c2MfkL7xP9 params: type: array items: {} @@ -305,7 +305,7 @@ paths: default: getrawmempool id: type: string - default: IZ6todle9t + default: BugnNFhJpA params: type: array items: {} @@ -343,7 +343,7 @@ paths: default: z_gettreestate id: type: string - default: SSZAwyUO6t + default: fCUQvR1BVa params: type: array items: {} @@ -393,7 +393,7 @@ paths: default: z_getsubtreesbyindex id: type: string - default: '3fJMQ0Hfxt' + default: TtPnptV6EU params: type: array items: {} @@ -432,7 +432,7 @@ paths: default: getrawtransaction id: type: string - default: RTdE1YnNxy + default: QqYeOGSzje params: type: array items: {} @@ -480,7 +480,7 @@ paths: default: getaddresstxids id: type: string - default: ifahwzVoYe + default: AsWWVyqp8x params: type: array items: {} @@ -528,7 +528,7 @@ paths: default: getaddressutxos id: type: string - default: PcPdZ7aiKy + default: Qscn5dUFgD params: type: array items: {} @@ -571,7 +571,7 @@ paths: default: stop id: type: string - default: rWlJLGe7VJ + default: WuIaPXV5fO params: type: array items: {} @@ -604,7 +604,7 @@ paths: default: getblockcount id: type: string - default: f4p3Cb4sDu + default: '5F9M7Wp0oI' params: type: array items: {} @@ -642,7 +642,7 @@ paths: default: getblockhash id: type: string - default: '3QXvqbEWqb' + default: f7hdgVjctr params: type: array items: {} @@ -690,7 +690,7 @@ paths: default: getblocktemplate id: type: string - default: GXKjn81k0D + default: pq0uXn3YGs params: type: array items: {} @@ -728,7 +728,7 @@ paths: default: submitblock id: type: string - default: cwGy92Mwn9 + default: bs4v4JmVw3 params: type: array items: {} @@ -761,7 +761,7 @@ paths: default: getmininginfo id: type: string - default: '4ZFY9ljh5I' + default: pp5xV6v3pm params: type: array items: {} @@ -776,7 +776,7 @@ paths: properties: result: type: object - default: '{"networksolps":0,"networkhashps":0,"chain":"","testnet":false}' + default: '{"blocks":0,"networksolps":0,"networkhashps":0,"chain":"","testnet":false}' /getnetworksolps: post: tags: @@ -794,7 +794,7 @@ paths: default: getnetworksolps id: type: string - default: tJlKGzARjU + default: '7bU98TeCV6' params: type: array items: {} @@ -827,7 +827,7 @@ paths: default: getnetworkhashps id: type: string - default: '7pUkOt26PB' + default: fskOJeXqjo params: type: array items: {} @@ -860,7 +860,7 @@ paths: default: getpeerinfo id: type: string - default: JjnSrPKeyS + default: jPV8ufjDdt params: type: array items: {} @@ -898,7 +898,7 @@ paths: default: validateaddress id: type: string - default: pxZQt6VQ9U + default: xOyxICseV9 params: type: array items: {} @@ -936,7 +936,7 @@ paths: default: z_validateaddress id: type: string - default: x2R2oRhdZE + default: xa6PoC4uN6 params: type: array items: {} @@ -974,7 +974,7 @@ paths: default: getblocksubsidy id: type: string - default: vkhYJS3FH8 + default: vYEVtnVK9o params: type: array items: {} @@ -1017,7 +1017,7 @@ paths: default: getdifficulty id: type: string - default: bC6q9c3xYO + default: tVzSTZu2sD params: type: array items: {} @@ -1055,7 +1055,7 @@ paths: default: z_listunifiedreceivers id: type: string - default: EQvPXkcJC2 + default: le2NmJBmPt params: type: array items: {} @@ -1093,7 +1093,7 @@ paths: default: generate id: type: string - default: w41FKROii3 + default: vVVOWxHqlN params: type: array items: {} diff --git a/zebra-chain/src/chain_tip/mock.rs b/zebra-chain/src/chain_tip/mock.rs index 46ca5e89e5e..f1fc8fb6e27 100644 --- a/zebra-chain/src/chain_tip/mock.rs +++ b/zebra-chain/src/chain_tip/mock.rs @@ -106,7 +106,7 @@ impl ChainTip for MockChainTip { } fn best_tip_mined_transaction_ids(&self) -> Arc<[transaction::Hash]> { - unreachable!("Method not used in tests"); + Arc::new([]) } fn estimate_distance_to_network_chain_tip( diff --git a/zebra-rpc/src/methods/get_block_template_rpcs.rs b/zebra-rpc/src/methods/get_block_template_rpcs.rs index 826f8d3e930..2d50552cfec 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs.rs @@ -1012,9 +1012,39 @@ where fn get_mining_info(&self) -> BoxFuture> { let network = self.network.clone(); + let mut state = self.state.clone(); + + let chain_tip = self.latest_chain_tip.clone(); + let tip_height = chain_tip.best_tip_height().unwrap_or(Height(0)).0; + + let mut current_block_tx = None; + if tip_height > 0 { + let mined_tx_ids = chain_tip.best_tip_mined_transaction_ids(); + current_block_tx = + (!mined_tx_ids.is_empty()).then(|| mined_tx_ids.len().saturating_sub(1)); + } + let solution_rate_fut = self.get_network_sol_ps(None, None); async move { + // Get the current block size. + let mut current_block_size = None; + if tip_height > 0 { + let request = zebra_state::ReadRequest::TipBlockSize; + let response: zebra_state::ReadResponse = state + .ready() + .and_then(|service| service.call(request)) + .await + .map_server_error()?; + current_block_size = match response { + zebra_state::ReadResponse::TipBlockSize(Some(block_size)) => Some(block_size), + _ => None, + }; + } + Ok(get_mining_info::Response::new( + tip_height, + current_block_size, + current_block_tx, network, solution_rate_fut.await?, )) diff --git a/zebra-rpc/src/methods/get_block_template_rpcs/types/get_mining_info.rs b/zebra-rpc/src/methods/get_block_template_rpcs/types/get_mining_info.rs index a14d4a081e7..21627d509db 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs/types/get_mining_info.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs/types/get_mining_info.rs @@ -5,6 +5,18 @@ use zebra_chain::parameters::Network; /// Response to a `getmininginfo` RPC request. #[derive(Debug, Default, PartialEq, Eq, serde::Serialize)] pub struct Response { + /// The current tip height. + #[serde(rename = "blocks")] + tip_height: u32, + + /// The size of the last mined block if any. + #[serde(rename = "currentblocksize", skip_serializing_if = "Option::is_none")] + current_block_size: Option, + + /// The number of transactions in the last mined block if any. + #[serde(rename = "currentblocktx", skip_serializing_if = "Option::is_none")] + current_block_tx: Option, + /// The estimated network solution rate in Sol/s. networksolps: u64, @@ -20,8 +32,17 @@ pub struct Response { impl Response { /// Creates a new `getmininginfo` response - pub fn new(network: Network, networksolps: u64) -> Self { + pub fn new( + tip_height: u32, + current_block_size: Option, + current_block_tx: Option, + network: Network, + networksolps: u64, + ) -> Self { Self { + tip_height, + current_block_size, + current_block_tx, networksolps, networkhashps: networksolps, chain: network.bip70_network_name(), diff --git a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@mainnet_10.snap b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@mainnet_10.snap index 67ffde393c4..de309513443 100644 --- a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@mainnet_10.snap +++ b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@mainnet_10.snap @@ -3,6 +3,8 @@ source: zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs expression: get_mining_info --- { + "blocks": 1687104, + "currentblocksize": 1617, "networksolps": 2, "networkhashps": 2, "chain": "main", diff --git a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@testnet_10.snap b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@testnet_10.snap index fc728a8540f..2051e6913ce 100644 --- a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@testnet_10.snap +++ b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_mining_info@testnet_10.snap @@ -3,6 +3,8 @@ source: zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs expression: get_mining_info --- { + "blocks": 1842420, + "currentblocksize": 1618, "networksolps": 0, "networkhashps": 0, "chain": "test", diff --git a/zebra-state/src/request.rs b/zebra-state/src/request.rs index 28740a336bb..1863c56b2ed 100644 --- a/zebra-state/src/request.rs +++ b/zebra-state/src/request.rs @@ -1063,6 +1063,11 @@ pub enum ReadRequest { /// Returns [`ReadResponse::ValidBlockProposal`] when successful, or an error if /// the block fails contextual validation. CheckBlockProposalValidity(SemanticallyVerifiedBlock), + + #[cfg(feature = "getblocktemplate-rpcs")] + /// Returns [`ReadResponse::TipBlockSize(usize)`](ReadResponse::TipBlockSize) + /// with the current best chain tip block size in bytes. + TipBlockSize, } impl ReadRequest { @@ -1098,6 +1103,8 @@ impl ReadRequest { ReadRequest::SolutionRate { .. } => "solution_rate", #[cfg(feature = "getblocktemplate-rpcs")] ReadRequest::CheckBlockProposalValidity(_) => "check_block_proposal_validity", + #[cfg(feature = "getblocktemplate-rpcs")] + ReadRequest::TipBlockSize => "tip_block_size", } } diff --git a/zebra-state/src/response.rs b/zebra-state/src/response.rs index 22e610838de..77c252b0c75 100644 --- a/zebra-state/src/response.rs +++ b/zebra-state/src/response.rs @@ -229,6 +229,10 @@ pub enum ReadResponse { #[cfg(feature = "getblocktemplate-rpcs")] /// Response to [`ReadRequest::CheckBlockProposalValidity`] ValidBlockProposal, + + #[cfg(feature = "getblocktemplate-rpcs")] + /// Response to [`ReadRequest::TipBlockSize`] + TipBlockSize(Option), } /// A structure with the information needed from the state to build a `getblocktemplate` RPC response. @@ -315,7 +319,7 @@ impl TryFrom for Response { ReadResponse::ValidBlockProposal => Ok(Response::ValidBlockProposal), #[cfg(feature = "getblocktemplate-rpcs")] - ReadResponse::ChainInfo(_) | ReadResponse::SolutionRate(_) => { + ReadResponse::ChainInfo(_) | ReadResponse::SolutionRate(_) | ReadResponse::TipBlockSize(_) => { Err("there is no corresponding Response for this ReadResponse") } } diff --git a/zebra-state/src/service.rs b/zebra-state/src/service.rs index 2116ab10470..4f970be89d4 100644 --- a/zebra-state/src/service.rs +++ b/zebra-state/src/service.rs @@ -39,6 +39,9 @@ use zebra_chain::{ subtree::NoteCommitmentSubtreeIndex, }; +#[cfg(feature = "getblocktemplate-rpcs")] +use zebra_chain::{block::Height, serialization::ZcashSerialize}; + use crate::{ constants::{ MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA, @@ -1905,6 +1908,46 @@ impl Service for ReadStateService { }) .wait_for_panics() } + + #[cfg(feature = "getblocktemplate-rpcs")] + ReadRequest::TipBlockSize => { + let state = self.clone(); + + tokio::task::spawn_blocking(move || { + span.in_scope(move || { + // Get the best chain tip height. + let tip_height = state + .non_finalized_state_receiver + .with_watch_data(|non_finalized_state| { + read::tip_height(non_finalized_state.best_chain(), &state.db) + }) + .unwrap_or(Height(0)); + + // Get the block at the best chain tip height. + let block = state.non_finalized_state_receiver.with_watch_data( + |non_finalized_state| { + read::block( + non_finalized_state.best_chain(), + &state.db, + tip_height.into(), + ) + }, + ); + + // The work is done in the future. + timer.finish(module_path!(), line!(), "ReadRequest::TipBlockSize"); + + // Respond with the length of the obtained block if any. + match block { + Some(b) => Ok(ReadResponse::TipBlockSize(Some( + b.zcash_serialize_to_vec()?.len(), + ))), + None => Ok(ReadResponse::TipBlockSize(None)), + } + }) + }) + .wait_for_panics() + } } } } From 60d09a4e62e8fa7cdf282f2a85c109c81fa905bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:39:38 +0000 Subject: [PATCH 26/46] build(deps): bump tj-actions/changed-files in the devops group (#8874) Bumps the devops group with 1 update: [tj-actions/changed-files](https://github.com/tj-actions/changed-files). Updates `tj-actions/changed-files` from 45.0.1 to 45.0.2 - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v45.0.1...v45.0.2) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-patch dependency-group: devops ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index 87b60204746..a2ea13523b8 100644 --- a/.github/workflows/ci-lint.yml +++ b/.github/workflows/ci-lint.yml @@ -44,7 +44,7 @@ jobs: - name: Rust files id: changed-files-rust - uses: tj-actions/changed-files@v45.0.1 + uses: tj-actions/changed-files@v45.0.2 with: files: | **/*.rs @@ -56,7 +56,7 @@ jobs: - name: Workflow files id: changed-files-workflows - uses: tj-actions/changed-files@v45.0.1 + uses: tj-actions/changed-files@v45.0.2 with: files: | .github/workflows/*.yml From c5d8eb5f83d2189dbae6917e05200f78694a6215 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 18 Sep 2024 17:14:41 -0300 Subject: [PATCH 27/46] fix(rpc): modify shutdown used in `stop()` (#8863) * modify shutdown used in `stop()` * use conditional compilation * add note * fix conditional compilation --- Cargo.lock | 19 +++++++++++++++++++ zebra-rpc/Cargo.toml | 2 ++ zebra-rpc/src/methods.rs | 26 ++++++++++++++++++++------ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae84f840965..22f5d505038 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -692,6 +692,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chacha20" version = "0.9.1" @@ -2650,6 +2656,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if 1.0.0", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -6154,6 +6172,7 @@ dependencies = [ "jsonrpc-core", "jsonrpc-derive", "jsonrpc-http-server", + "nix", "proptest", "prost", "rand 0.8.5", diff --git a/zebra-rpc/Cargo.toml b/zebra-rpc/Cargo.toml index e45df94b000..babae9123f1 100644 --- a/zebra-rpc/Cargo.toml +++ b/zebra-rpc/Cargo.toml @@ -87,6 +87,8 @@ tracing = "0.1.39" hex = { version = "0.4.3", features = ["serde"] } serde = { version = "1.0.204", features = ["serde_derive"] } +# For the `stop` RPC method. +nix = { version = "0.29.0", features = ["signal"] } zcash_primitives = { workspace = true, features = ["transparent-inputs"] } diff --git a/zebra-rpc/src/methods.rs b/zebra-rpc/src/methods.rs index cb894182c1f..8becc5bb79c 100644 --- a/zebra-rpc/src/methods.rs +++ b/zebra-rpc/src/methods.rs @@ -302,17 +302,18 @@ pub trait Rpc { address_strings: AddressStrings, ) -> BoxFuture>>; - #[rpc(name = "stop")] /// Stop the running zebrad process. /// /// # Notes /// - /// Only works if the network of the running zebrad process is `Regtest`. + /// - Works for non windows targets only. + /// - Works only if the network of the running zebrad process is `Regtest`. /// /// zcashd reference: [`stop`](https://zcash.github.io/rpc/stop.html) /// method: post /// tags: control - fn stop(&self) -> Result<()>; + #[rpc(name = "stop")] + fn stop(&self) -> Result; } /// RPC method implementations. @@ -1357,10 +1358,17 @@ where .boxed() } - fn stop(&self) -> Result<()> { + fn stop(&self) -> Result { + #[cfg(not(target_os = "windows"))] if self.network.is_regtest() { - // TODO: Use graceful termination in `stop` RPC (#8850) - std::process::exit(0); + match nix::sys::signal::raise(nix::sys::signal::SIGINT) { + Ok(_) => Ok("Zebra server stopping".to_string()), + Err(error) => Err(Error { + code: ErrorCode::InternalError, + message: format!("Failed to shut down: {}", error), + data: None, + }), + } } else { Err(Error { code: ErrorCode::MethodNotFound, @@ -1368,6 +1376,12 @@ where data: None, }) } + #[cfg(target_os = "windows")] + Err(Error { + code: ErrorCode::MethodNotFound, + message: "stop is not available in windows targets".to_string(), + data: None, + }) } } From aec07f24ffe1021c5963cb7b259a445f85db6a22 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Thu, 19 Sep 2024 13:31:33 +0100 Subject: [PATCH 28/46] ref(ci): consolidate cached states workflows and scripts (#8865) * ref(ci): consolidate cached states workflows and scripts We've been using multiple approaches to locate and retrieve cached states in GCP. However, this has made it difficult to reuse the same methods across new workflows or different scenarios. To address this, we've streamlined the process to make it more reusable in other contexts. This change will support deploying instances from both the `main` branch and `release`, simplifying future implementations and speeding up the process. Changes: - Use a single bash script (`gcp-get-cached-disks.sh`) to get cached states names and availability - Move script logic from `sub-find-cached-disks.yml` to `gcp-get-cached-disks.sh` and adapt `sub-find-cached-disks.yml` to allow to output available disks and disks names. - Simplify parameters usage in `sub-deploy-integration-tests-gcp.yml` and convert the `Find ${{ inputs.test_id }} cached state disk` step into an independent job, to be able to use the `sub-find-cached-disks.yml` reusable workflow - Remove repetition in `sub-ci-integration-tests-gcp.yml` * ref(tests): Use the `ZEBRA_CACHED_STATE_DIR` env var across tests We had a technical debt with some tests using a hardcoded value for the cache directory (`/zebrad-cache`), which generated inconsistency across disks and cached states directories. Changes: - Allow sync tests to use the `ZEBRA_CACHED_STATE_DIR` as the cache directory, if specified - Update the `entrypoint.sh` to reflect this change - Add the `ZEBRA_CACHED_STATE_DIR` variable to the missing tests in `sub-ci-integration-tests-gcp.yml`, and remove extra parameters to call reusable workflows. --- .../scripts/gcp-get-available-disks.sh | 42 ------- .../workflows/scripts/gcp-get-cached-disks.sh | 114 ++++++++++++------ .../sub-ci-integration-tests-gcp.yml | 54 ++------- .../sub-deploy-integration-tests-gcp.yml | 109 +++++++---------- .github/workflows/sub-find-cached-disks.yml | 73 +++++------ docker/entrypoint.sh | 14 +-- zebrad/tests/acceptance.rs | 24 ++-- zebrad/tests/common/sync.rs | 16 ++- 8 files changed, 194 insertions(+), 252 deletions(-) delete mode 100755 .github/workflows/scripts/gcp-get-available-disks.sh diff --git a/.github/workflows/scripts/gcp-get-available-disks.sh b/.github/workflows/scripts/gcp-get-available-disks.sh deleted file mode 100755 index 667c6f36c4b..00000000000 --- a/.github/workflows/scripts/gcp-get-available-disks.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - -# Description: -# Check if there are cached state disks available for subsequent jobs to use. -# -# This lookup uses the state version from constants.rs. -# It accepts disks generated by any branch, including draft and unmerged PRs. -# -# If the disk exists, sets the corresponding output to "true": -# - lwd_tip_disk -# - zebra_tip_disk -# - zebra_checkpoint_disk - -set -euxo pipefail - - -LOCAL_STATE_VERSION=$(grep -oE "DATABASE_FORMAT_VERSION: .* [0-9]+" "${GITHUB_WORKSPACE}/zebra-state/src/constants.rs" | grep -oE "[0-9]+" | tail -n1) -echo "STATE_VERSION: ${LOCAL_STATE_VERSION}" - -# Function to find a disk image and output its name -find_disk_image() { -local base_name="${1}" -local disk_type="${2}" -local disk_pattern="${base_name}-cache" -local output_var="${base_name}_${disk_type}_disk" -local disk_image - -disk_image=$(gcloud compute images list --filter="status=READY AND name~${disk_pattern}-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-${disk_type}" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) - -if [[ -z "${disk_image}" ]]; then - echo "No ${disk_type^^} disk found for ${base_name^^} on network: ${NETWORK}" - echo "${output_var}=false" >> "${GITHUB_OUTPUT}" -else - echo "Disk: ${disk_image}" - echo "${output_var}=true" >> "${GITHUB_OUTPUT}" -fi -} - -# Find and output LWD and Zebra disks -find_disk_image "lwd" "tip" -find_disk_image "zebrad" "tip" -find_disk_image "zebrad" "checkpoint" diff --git a/.github/workflows/scripts/gcp-get-cached-disks.sh b/.github/workflows/scripts/gcp-get-cached-disks.sh index 9b05c257096..0f38addf10f 100755 --- a/.github/workflows/scripts/gcp-get-cached-disks.sh +++ b/.github/workflows/scripts/gcp-get-cached-disks.sh @@ -1,20 +1,33 @@ #!/usr/bin/env bash -# Description: # This script finds a cached Google Cloud Compute image based on specific criteria. -# It prioritizes images from the current commit, falls back to the main branch, -# and finally checks other branches if needed. The selected image is used for -# setting up the environment in a CI/CD pipeline. +# +# If there are multiple disks: +# - prefer images generated from the same commit, then +# - if prefer_main_cached_state is true, prefer images from the `main` branch, then +# - use any images from any other branch or commit. +# +# Within each of these categories: +# - prefer newer images to older images +# +# The selected image is used for setting up the environment in a CI/CD pipeline. +# It also checks if specific disk types are available for subsequent jobs. set -eo pipefail -# Function to find and report a cached disk image +# Extract local state version +echo "Extracting local state version..." +LOCAL_STATE_VERSION=$(grep -oE "DATABASE_FORMAT_VERSION: .* [0-9]+" "${GITHUB_WORKSPACE}/zebra-state/src/constants.rs" | grep -oE "[0-9]+" | tail -n1) +echo "STATE_VERSION: ${LOCAL_STATE_VERSION}" + +# Function to find a cached disk image based on the git pattern (commit, main, or any branch) find_cached_disk_image() { - local search_pattern="${1}" + local git_pattern="${1}" local git_source="${2}" local disk_name + local disk_search_pattern="${DISK_PREFIX}-${git_pattern}-v${LOCAL_STATE_VERSION}-${NETWORK}-${DISK_SUFFIX}" - disk_name=$(gcloud compute images list --filter="status=READY AND name~${search_pattern}" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) + disk_name=$(gcloud compute images list --filter="status=READY AND name~${disk_search_pattern}" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) # Use >&2 to redirect to stderr and avoid sending wrong assignments to stdout if [[ -n "${disk_name}" ]]; then @@ -27,46 +40,71 @@ find_cached_disk_image() { fi } -# Extract local state version -echo "Extracting local state version..." -LOCAL_STATE_VERSION=$(grep -oE "DATABASE_FORMAT_VERSION: .* [0-9]+" "${GITHUB_WORKSPACE}/zebra-state/src/constants.rs" | grep -oE "[0-9]+" | tail -n1) -echo "STATE_VERSION: ${LOCAL_STATE_VERSION}" +# Check if both $DISK_PREFIX and $DISK_SUFFIX are set, as they are required to find a cached disk image +if [[ -n "${DISK_PREFIX}" && -n "${DISK_SUFFIX}" ]]; then + # Find the most suitable cached disk image + echo "Finding the most suitable cached disk image..." + CACHED_DISK_NAME="" + + # First, try to find a cached disk image from the current commit + CACHED_DISK_NAME=$(find_cached_disk_image ".+-${GITHUB_SHA_SHORT}" "commit") -# Define DISK_PREFIX based on the requiring state directory -if [[ "${NEEDS_LWD_STATE}" == "true" ]]; then - DISK_PREFIX="${LWD_STATE_DIR}" + # If no cached disk image is found + if [[ -z "${CACHED_DISK_NAME}" ]]; then + # Check if main branch images are preferred + if [[ "${PREFER_MAIN_CACHED_STATE}" == "true" ]]; then + CACHED_DISK_NAME=$(find_cached_disk_image "main-[0-9a-f]+" "main branch") + # Else, try to find one from any branch + else + CACHED_DISK_NAME=$(find_cached_disk_image ".+-[0-9a-f]+" "any branch") + fi + fi + + # Handle case where no suitable disk image is found + if [[ -z "${CACHED_DISK_NAME}" ]]; then + echo "No suitable cached state disk available." + echo "Cached state test jobs must depend on the cached state rebuild job." + exit 1 + fi + + echo "Selected Disk: ${CACHED_DISK_NAME}" else - DISK_PREFIX="${ZEBRA_STATE_DIR:-${DISK_PREFIX}}" + echo "DISK_PREFIX or DISK_SUFFIX is not set. Skipping disk image search." fi -# Find the most suitable cached disk image -echo "Finding the most suitable cached disk image..." -if [[ -z "${CACHED_DISK_NAME}" ]]; then - # Try to find a cached disk image from the current commit - COMMIT_DISK_PREFIX="${DISK_PREFIX}-.+-${GITHUB_SHA_SHORT}-v${LOCAL_STATE_VERSION}-${NETWORK}-${DISK_SUFFIX}" - CACHED_DISK_NAME=$(find_cached_disk_image "${COMMIT_DISK_PREFIX}" "commit") - # If no cached disk image is found, try to find one from the main branch - if [[ "${PREFER_MAIN_CACHED_STATE}" == "true" ]]; then - MAIN_DISK_PREFIX="${DISK_PREFIX}-main-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-${DISK_SUFFIX}" - CACHED_DISK_NAME=$(find_cached_disk_image "${MAIN_DISK_PREFIX}" "main branch") - # Else, try to find one from any branch +# Function to find and output available disk image types (e.g., lwd_tip_disk, zebra_tip_disk, zebra_checkpoint_disk) +find_available_disk_type() { + local base_name="${1}" + local disk_type="${2}" + local disk_pattern="${base_name}-cache" + local output_var="${base_name}_${disk_type}_disk" + local disk_name + + disk_name=$(gcloud compute images list --filter="status=READY AND name~${disk_pattern}-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-${disk_type}" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) + + # Use >&2 to redirect to stderr and avoid sending wrong assignments to stdout + if [[ -n "${disk_name}" ]]; then + echo "Found ${disk_type^^} disk: ${disk_name} for ${base_name^^} on network: ${NETWORK}" >&2 + disk_description=$(gcloud compute images describe "${disk_name}" --format="value(DESCRIPTION)") + echo "Description: ${disk_description}" >&2 + echo "true" # This is the actual return value when a disk is found else - ANY_DISK_PREFIX="${DISK_PREFIX}-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-${DISK_SUFFIX}" - CACHED_DISK_NAME=$(find_cached_disk_image "${ANY_DISK_PREFIX}" "any branch") + echo "No ${disk_type^^} disk found for ${base_name^^} on network: ${NETWORK}" >&2 + echo "false" # This is the actual return value when no disk is found fi +} +if [[ -n "${NETWORK}" ]]; then + # Check for specific disk images (lwd_tip_disk, zebra_tip_disk, zebra_checkpoint_disk) + echo "Checking for specific disk images..." + LWD_TIP_DISK=$(find_available_disk_type "lwd" "tip") + ZEBRA_TIP_DISK=$(find_available_disk_type "zebrad" "tip") + ZEBRA_CHECKPOINT_DISK=$(find_available_disk_type "zebrad" "checkpoint") fi -# Handle case where no suitable disk image is found -if [[ -z "${CACHED_DISK_NAME}" ]]; then - echo "No suitable cached state disk available." - echo "Expected pattern: ${COMMIT_DISK_PREFIX}" - echo "Cached state test jobs must depend on the cached state rebuild job." - exit 1 -fi - -echo "Selected Disk: ${CACHED_DISK_NAME}" - # Exporting variables for subsequent steps echo "Exporting variables for subsequent steps..." export CACHED_DISK_NAME="${CACHED_DISK_NAME}" export LOCAL_STATE_VERSION="${LOCAL_STATE_VERSION}" +export LWD_TIP_DISK="${LWD_TIP_DISK}" +export ZEBRA_TIP_DISK="${ZEBRA_TIP_DISK}" +export ZEBRA_CHECKPOINT_DISK="${ZEBRA_CHECKPOINT_DISK}" diff --git a/.github/workflows/sub-ci-integration-tests-gcp.yml b/.github/workflows/sub-ci-integration-tests-gcp.yml index 76cb168feb9..3ff5ab1e79a 100644 --- a/.github/workflows/sub-ci-integration-tests-gcp.yml +++ b/.github/workflows/sub-ci-integration-tests-gcp.yml @@ -31,6 +31,10 @@ on: #! #! The job names in `ci-integration-tests-gcp.yml`, `ci-integration-tests-gcp.patch.yml` and #! `ci-integration-tests-gcp.patch-external.yml` must be kept in sync. +#! +#! The test variables ZEBRA_CACHED_STATE_DIR and LIGHTWALLETD_DATA_DIR used in some steps are set in the +#! `sub-deploy-integration-tests-gcp.yml` workflow file as inputs. If modified in this file, they must +#! also be updated in the `sub-deploy-integration-tests-gcp.yml` file. jobs: # to also run a job on Mergify head branches, # add `|| (github.event_name == 'push' && startsWith(github.head_ref, 'mergify/merge-queue/'))`: @@ -79,7 +83,7 @@ jobs: app_name: zebrad test_id: sync-to-checkpoint test_description: Test sync up to mandatory checkpoint - test_variables: "-e NETWORK=${{ inputs.network || vars.ZCASH_NETWORK }} -e TEST_DISK_REBUILD=1 -e ZEBRA_FORCE_USE_COLOR=1" + test_variables: "-e NETWORK=${{ inputs.network || vars.ZCASH_NETWORK }} -e TEST_DISK_REBUILD=1 -e ZEBRA_FORCE_USE_COLOR=1 -e ZEBRA_CACHED_STATE_DIR=/var/cache/zebrad-cache" needs_zebra_state: false saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} @@ -108,7 +112,7 @@ jobs: app_name: zebrad test_id: sync-past-checkpoint test_description: Test full validation sync from a cached state - test_variables: "-e NETWORK=${{ inputs.network || vars.ZCASH_NETWORK }} -e TEST_CHECKPOINT_SYNC=1 -e ZEBRA_FORCE_USE_COLOR=1" + test_variables: "-e NETWORK=${{ inputs.network || vars.ZCASH_NETWORK }} -e TEST_CHECKPOINT_SYNC=1 -e ZEBRA_FORCE_USE_COLOR=1 -e ZEBRA_CACHED_STATE_DIR=/var/cache/zebrad-cache" needs_zebra_state: true saves_to_disk: false disk_suffix: checkpoint @@ -138,13 +142,12 @@ jobs: test_description: Test a full sync up to the tip # The value of FULL_SYNC_MAINNET_TIMEOUT_MINUTES is currently ignored. # TODO: update the test to use {{ input.network }} instead? - test_variables: "-e NETWORK=Mainnet -e FULL_SYNC_MAINNET_TIMEOUT_MINUTES=0 -e ZEBRA_FORCE_USE_COLOR=1" + test_variables: "-e NETWORK=Mainnet -e FULL_SYNC_MAINNET_TIMEOUT_MINUTES=0 -e ZEBRA_FORCE_USE_COLOR=1 -e ZEBRA_CACHED_STATE_DIR=/var/cache/zebrad-cache" # This test runs for longer than 6 hours, so it needs multiple jobs is_long_test: true needs_zebra_state: false saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} - disk_suffix: tip height_grep_text: 'current_height.*=.*Height.*\(' secrets: inherit # We want to prevent multiple full zebrad syncs running at the same time, @@ -184,9 +187,6 @@ jobs: # update the disk on every PR, to increase CI speed saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" height_grep_text: 'current_height.*=.*Height.*\(' secrets: inherit @@ -217,9 +217,6 @@ jobs: needs_zebra_state: true # test-update-sync updates the disk on every PR, so we don't need to do it here saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" height_grep_text: 'current_height.*=.*Height.*\(' secrets: inherit @@ -248,7 +245,7 @@ jobs: test_id: full-sync-testnet test_description: Test a full sync up to the tip on testnet # The value of FULL_SYNC_TESTNET_TIMEOUT_MINUTES is currently ignored. - test_variables: "-e NETWORK=Testnet -e FULL_SYNC_TESTNET_TIMEOUT_MINUTES=0 -e ZEBRA_FORCE_USE_COLOR=1" + test_variables: "-e NETWORK=Testnet -e FULL_SYNC_TESTNET_TIMEOUT_MINUTES=0 -e ZEBRA_FORCE_USE_COLOR=1 -e ZEBRA_CACHED_STATE_DIR=/var/cache/zebrad-cache" network: "Testnet" # A full testnet sync could take 2-10 hours in April 2023. # The time varies a lot due to the small number of nodes. @@ -256,7 +253,6 @@ jobs: needs_zebra_state: false saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} - disk_suffix: tip height_grep_text: 'current_height.*=.*Height.*\(' secrets: inherit # We want to prevent multiple full zebrad syncs running at the same time, @@ -300,9 +296,6 @@ jobs: # we don't have a test-update-sync-testnet job, so we need to update the disk here saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" height_grep_text: 'zebra_tip_height.*=.*Height.*\(' secrets: inherit @@ -335,10 +328,6 @@ jobs: saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} disk_prefix: lwd-cache - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" - lwd_state_dir: "lwd-cache" height_grep_text: "Waiting for block: " secrets: inherit # We want to prevent multiple lightwalletd full syncs running at the same time, @@ -372,10 +361,6 @@ jobs: saves_to_disk: true force_save_to_disk: ${{ inputs.force_save_to_disk || false }} disk_prefix: lwd-cache - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" - lwd_state_dir: "lwd-cache" height_grep_text: "Waiting for block: " secrets: inherit @@ -401,9 +386,6 @@ jobs: test_variables: "-e NETWORK=${{ inputs.network || vars.ZCASH_NETWORK }} -e TEST_LWD_RPC_CALL=1 -e ZEBRA_TEST_LIGHTWALLETD=1 -e ZEBRA_FORCE_USE_COLOR=1 -e ZEBRA_CACHED_STATE_DIR=/var/cache/zebrad-cache" needs_zebra_state: true saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" secrets: inherit # Test that Zebra can handle a lightwalletd send transaction RPC call, using a cached Zebra tip state @@ -427,10 +409,6 @@ jobs: needs_zebra_state: true needs_lwd_state: true saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" - lwd_state_dir: "lwd-cache" secrets: inherit # Test that Zebra can handle gRPC wallet calls, using a cached Zebra tip state @@ -454,10 +432,6 @@ jobs: needs_zebra_state: true needs_lwd_state: true saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" - lwd_state_dir: "lwd-cache" secrets: inherit ## getblocktemplate-rpcs using cached Zebra state on mainnet @@ -485,9 +459,6 @@ jobs: needs_zebra_state: true needs_lwd_state: false saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" secrets: inherit # Test that Zebra can handle a submit block RPC call, using a cached Zebra tip state @@ -511,9 +482,6 @@ jobs: needs_zebra_state: true needs_lwd_state: false saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" secrets: inherit # Test that the scanner can continue scanning where it was left when zebrad restarts. @@ -537,9 +505,6 @@ jobs: needs_zebra_state: true needs_lwd_state: false saves_to_disk: true - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" secrets: inherit # Test that the scan task registers keys, deletes keys, and subscribes to results for keys while running. @@ -563,9 +528,6 @@ jobs: needs_zebra_state: true needs_lwd_state: false saves_to_disk: false - disk_suffix: tip - root_state_path: "/var/cache" - zebra_state_dir: "zebrad-cache" secrets: inherit failure-issue: diff --git a/.github/workflows/sub-deploy-integration-tests-gcp.yml b/.github/workflows/sub-deploy-integration-tests-gcp.yml index 09af3dd310c..4d1d346ff1d 100644 --- a/.github/workflows/sub-deploy-integration-tests-gcp.yml +++ b/.github/workflows/sub-deploy-integration-tests-gcp.yml @@ -35,23 +35,15 @@ on: # Cached state # - # TODO: find a better name - root_state_path: - required: false - type: string - default: '/zebrad-cache' - description: 'Cached state base directory path' - # TODO: find a better name zebra_state_dir: required: false type: string - default: '' + default: '/var/cache/zebrad-cache' description: 'Zebra cached state directory and input image prefix to search in GCP' - # TODO: find a better name lwd_state_dir: required: false type: string - default: '' + default: '/var/cache/lwd-cache' description: 'Lightwalletd cached state directory and input image prefix to search in GCP' disk_prefix: required: false @@ -61,6 +53,7 @@ on: disk_suffix: required: false type: string + default: 'tip' description: 'Image name suffix' needs_zebra_state: required: true @@ -104,6 +97,29 @@ env: CACHED_STATE_UPDATE_LIMIT: 576 jobs: + # Find a cached state disk for ${{ inputs.test_id }}, matching all of: + # - disk cached state prefix -> zebrad-cache or lwd-cache + # - state version (from the source code) - v{N} + # - network (network) - mainnet or testnet + # - disk target height kind (disk_suffix) - checkpoint or tip + # + # If the test needs a lightwalletd state (needs_lwd_state) set the input disk_prefix accordingly + # - To lwd-cache if needed + # - To zebrad-cache if not + # + # Passes the disk name to subsequent jobs using `cached_disk_name` output + # Passes the state version to subsequent jobs using `state_version` output + # + get-disk-name: + name: Get disk name + uses: ./.github/workflows/sub-find-cached-disks.yml + with: + network: ${{ inputs.network || vars.ZCASH_NETWORK }} + disk_prefix: ${{ inputs.needs_lwd_state && 'lwd-cache' || inputs.needs_zebra_state && 'zebrad-cache' }} + disk_suffix: ${{ inputs.disk_suffix }} + prefer_main_cached_state: ${{ inputs.prefer_main_cached_state }} + test_id: ${{ inputs.test_id }} + # Show all the test logs, then follow the logs of the test we just launched, until it finishes. # Then check the result of the test. # @@ -111,9 +127,14 @@ jobs: test-result: name: Run ${{ inputs.test_id }} test runs-on: zfnd-runners + needs: [ get-disk-name ] + if: ${{ !cancelled() && !failure() }} timeout-minutes: ${{ inputs.is_long_test && 7200 || 180 }} outputs: - cached_disk_name: ${{ steps.get-disk-name.outputs.cached_disk_name }} + cached_disk_name: ${{ needs.get-disk-name.outputs.cached_disk_name }} + state_version: ${{ needs.get-disk-name.outputs.state_version }} + env: + CACHED_DISK_NAME: ${{ needs.get-disk-name.outputs.cached_disk_name }} permissions: contents: 'read' id-token: 'write' @@ -158,47 +179,8 @@ jobs: - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2.1.1 - # Find a cached state disk for this job, matching all of: - # - disk cached state (lwd_state_dir/zebra_state_dir or disk_prefix) - zebrad-cache or lwd-cache - # - state version (from the source code) - v{N} - # - network (network) - mainnet or testnet - # - disk target height kind (disk_suffix) - checkpoint or tip - # - # If the test needs a lightwalletd state (needs_lwd_state) set the variable DISK_PREFIX accordingly - # - To ${{ inputs.lwd_state_dir }}" if needed - # - To ${{ inputs.zebra_state_dir || inputs.disk_prefix }} if not - # - # If there are multiple disks: - # - prefer images generated from the same commit, then - # - if prefer_main_cached_state is true, prefer images from the `main` branch, then - # - use any images from any other branch or commit. - # Within each of these categories: - # - prefer newer images to older images - # - # Passes the disk name to subsequent steps using $CACHED_DISK_NAME env variable - # Passes the state version to subsequent steps using $STATE_VERSION env variable - # - # TODO: move this script into a file, and call it from sub-find-cached-disks.yml as well. - - name: Find ${{ inputs.test_id }} cached state disk - id: get-disk-name - if: ${{ inputs.needs_zebra_state || inputs.needs_lwd_state }} - env: - GITHUB_SHA_SHORT: ${{ env.GITHUB_SHA_SHORT }} - NEEDS_LWD_STATE: ${{ inputs.needs_lwd_state }} - LWD_STATE_DIR: ${{ inputs.lwd_state_dir }} - ZEBRA_STATE_DIR: ${{ inputs.zebra_state_dir }} - DISK_PREFIX: ${{ inputs.disk_prefix }} - NETWORK: ${{ env.NETWORK }} # use lowercase version from env, not input - DISK_SUFFIX: ${{ inputs.disk_suffix }} - PREFER_MAIN_CACHED_STATE: ${{ inputs.prefer_main_cached_state }} - run: | - source ./.github/workflows/scripts/gcp-get-cached-disks.sh - echo "STATE_VERSION=${LOCAL_STATE_VERSION}" >> "${GITHUB_ENV}" - echo "CACHED_DISK_NAME=${CACHED_DISK_NAME}" >> "${GITHUB_ENV}" - echo "cached_disk_name=${CACHED_DISK_NAME}" >> "${GITHUB_OUTPUT}" - # Create a Compute Engine virtual machine and attach a cached state disk using the - # $CACHED_DISK_NAME variable as the source image to populate the disk cached state + # $CACHED_DISK_NAME env as the source image to populate the disk cached state # if the test needs it. - name: Create ${{ inputs.test_id }} GCP compute instance id: create-instance @@ -256,8 +238,7 @@ jobs: # # The disk mounted in the VM is located at /dev/$DISK_NAME, we mount the root `/` of this disk to the docker # container, and might have two different paths (if lightwalletd state is needed): - # - /var/cache/zebrad-cache -> ${{ inputs.root_state_path }}/${{ inputs.zebra_state_dir }} -> $ZEBRA_CACHED_STATE_DIR - # - /var/cache/lwd-cache -> ${{ inputs.root_state_path }}/${{ inputs.lwd_state_dir }} -> $LIGHTWALLETD_DATA_DIR + # - ${{ inputs.zebra_state_dir }} and ${{ inputs.lwd_state_dir }} # # Currently we do this by mounting the same disk at both paths. # @@ -268,7 +249,7 @@ jobs: # These paths must match the variables used by the tests in Rust, which are also set in # `ci-unit-tests-docker.yml` to be able to run this tests. # - # Although we're mounting the disk root to both directories, Zebra and Lightwalletd + # Although we're mounting the disk root to both directories, Zebra and Lightwalletd, tests # will only respect the values from $ZEBRA_CACHED_STATE_DIR and $LIGHTWALLETD_DATA_DIR, # the inputs like ${{ inputs.zebra_state_dir }} and ${{ inputs.lwd_state_dir }} # are only used to match those variables paths. @@ -286,12 +267,12 @@ jobs: # Extract the correct disk name based on the device-name DISK_NAME=$(ls -l /dev/disk/by-id | grep -oE "google-${{ inputs.test_id }}-${{ env.GITHUB_SHA_SHORT }} -> ../../[^ ]+" | grep -oE "/[^/]+$" | cut -c 2-) - MOUNT_FLAGS="--mount type=volume,volume-driver=local,volume-opt=device=/dev/$DISK_NAME,volume-opt=type=ext4,dst=${{ inputs.root_state_path }}/${{ inputs.zebra_state_dir }}" + MOUNT_FLAGS="--mount type=volume,volume-driver=local,volume-opt=device=/dev/$DISK_NAME,volume-opt=type=ext4,dst=${{ inputs.zebra_state_dir }}" # Check if we need to mount for Lightwalletd state # lightwalletd-full-sync reads Zebra and writes lwd, so it is handled specially. if [[ "${{ inputs.needs_lwd_state }}" == "true" || "${{ inputs.test_id }}" == "lwd-full-sync" ]]; then - MOUNT_FLAGS="$MOUNT_FLAGS --mount type=volume,volume-driver=local,volume-opt=device=/dev/$DISK_NAME,volume-opt=type=ext4,dst=${{ inputs.root_state_path }}/${{ inputs.lwd_state_dir }}" + MOUNT_FLAGS="$MOUNT_FLAGS --mount type=volume,volume-driver=local,volume-opt=device=/dev/$DISK_NAME,volume-opt=type=ext4,dst=${{ inputs.lwd_state_dir }}" fi sudo docker run \ @@ -401,6 +382,9 @@ jobs: # Normally, if a job is skipped, all the jobs that depend on it are also skipped. # So we need to override the default success() check to make this job run. if: ${{ !cancelled() && !failure() && (inputs.saves_to_disk || inputs.force_save_to_disk) }} + env: + STATE_VERSION: ${{ needs.test-result.outputs.state_version }} + CACHED_DISK_NAME: ${{ needs.test-result.outputs.cached_disk_name }} permissions: contents: 'read' id-token: 'write' @@ -457,17 +441,6 @@ jobs: - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2.1.1 - # Get the state version from the local constants.rs file to be used in the image creation, - # as the state version is part of the disk image name. - # - # Passes the state version to subsequent steps using $STATE_VERSION env variable - - name: Get state version from constants.rs - run: | - LOCAL_STATE_VERSION=$(grep -oE "DATABASE_FORMAT_VERSION: .* [0-9]+" $GITHUB_WORKSPACE/zebra-state/src/constants.rs | grep -oE "[0-9]+" | tail -n1) - echo "STATE_VERSION: $LOCAL_STATE_VERSION" - - echo "STATE_VERSION=$LOCAL_STATE_VERSION" >> "$GITHUB_ENV" - # Sets the $UPDATE_SUFFIX env var to "-u" if updating a previous cached state, # and the empty string otherwise. # @@ -641,7 +614,7 @@ jobs: - name: Get original cached state height from google cloud run: | ORIGINAL_HEIGHT="0" - ORIGINAL_DISK_NAME="${{ format('{0}', needs.test-result.outputs.cached_disk_name) }}" + ORIGINAL_DISK_NAME="${{ format('{0}', env.CACHED_DISK_NAME) }}" if [[ -n "$ORIGINAL_DISK_NAME" ]]; then ORIGINAL_HEIGHT=$(gcloud compute images list --filter="status=READY AND name=$ORIGINAL_DISK_NAME" --format="value(labels.height)") diff --git a/.github/workflows/sub-find-cached-disks.yml b/.github/workflows/sub-find-cached-disks.yml index 79fdbff8efb..00254c14be5 100644 --- a/.github/workflows/sub-find-cached-disks.yml +++ b/.github/workflows/sub-find-cached-disks.yml @@ -14,22 +14,43 @@ on: description: 'The Zcash network used to look up the disks' required: true type: string + disk_prefix: + required: false + type: string + disk_suffix: + required: false + type: string + prefer_main_cached_state: + required: false + type: boolean + test_id: + description: 'The test ID requiring the cached state disks' + required: false + type: string outputs: + state_version: + description: 'The version of the cached state disks' + value: ${{ jobs.get-cached-disks.outputs.state_version }} + cached_disk_name: + description: 'The name of the cached state disk' + value: ${{ jobs.get-cached-disks.outputs.cached_disk_name }} lwd_tip_disk: description: 'true if there is a lightwalletd and Zebra cached state disk, synced near the chain tip' - value: ${{ jobs.get-available-disks.outputs.lwd_tip_disk }} + value: ${{ jobs.get-cached-disks.outputs.lwd_tip_disk }} zebra_tip_disk: description: 'true if there is a Zebra cached state disk synced near the chain tip' - value: ${{ jobs.get-available-disks.outputs.zebra_tip_disk }} + value: ${{ jobs.get-cached-disks.outputs.zebra_tip_disk }} zebra_checkpoint_disk: description: 'true if there is a Zebra cached state disk synced to the mandatory Zebra checkpoint' - value: ${{ jobs.get-available-disks.outputs.zebra_checkpoint_disk }} + value: ${{ jobs.get-cached-disks.outputs.zebra_checkpoint_disk }} jobs: - get-available-disks: - name: Check if cached state disks exist + get-cached-disks: + name: Get ${{ inputs.test_id || inputs.network }} cached disk runs-on: ubuntu-latest outputs: + state_version: ${{ steps.get-available-disks.outputs.state_version }} + cached_disk_name: ${{ steps.get-available-disks.outputs.cached_disk_name }} lwd_tip_disk: ${{ steps.get-available-disks.outputs.lwd_tip_disk }} zebra_tip_disk: ${{ steps.get-available-disks.outputs.zebra_tip_disk }} zebra_checkpoint_disk: ${{ steps.get-available-disks.outputs.zebra_checkpoint_disk }} @@ -63,38 +84,18 @@ jobs: echo "NETWORK=${NETWORK_CAPS,,}" >> $GITHUB_ENV # Check if there are cached state disks available for subsequent jobs to use. - - name: Check if cached state disks exist + - name: Check if cached state disks exists id: get-available-disks env: - GITHUB_WORKSPACE: ${{ env.GITHUB_WORKSPACE }} + GITHUB_SHA_SHORT: ${{ env.GITHUB_SHA_SHORT }} NETWORK: ${{ env.NETWORK }} # use lowercase version from env, not input - # TODO: Use the `gcp-get-available-disks.sh` script instead of the inline script, - # as this is crashing. And it might related to the returned JSON values. + DISK_PREFIX: ${{ inputs.disk_prefix }} + DISK_SUFFIX: ${{ inputs.disk_suffix }} + PREFER_MAIN_CACHED_STATE: ${{ inputs.prefer_main_cached_state }} run: | - # ./.github/workflows/scripts/gcp-get-available-disks.sh - LOCAL_STATE_VERSION=$(grep -oE "DATABASE_FORMAT_VERSION: .* [0-9]+" "$GITHUB_WORKSPACE/zebra-state/src/constants.rs" | grep -oE "[0-9]+" | tail -n1) - echo "STATE_VERSION: $LOCAL_STATE_VERSION" - LWD_TIP_DISK=$(gcloud compute images list --filter="status=READY AND name~lwd-cache-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-tip" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) - if [[ -z "$LWD_TIP_DISK" ]]; then - echo "No TIP disk found for lightwalletd on network: ${NETWORK}" - echo "lwd_tip_disk=${{ toJSON(false) }}" >> "$GITHUB_OUTPUT" - else - echo "Disk: $LWD_TIP_DISK" - echo "lwd_tip_disk=${{ toJSON(true) }}" >> "$GITHUB_OUTPUT" - fi - ZEBRA_TIP_DISK=$(gcloud compute images list --filter="status=READY AND name~zebrad-cache-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-tip" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) - if [[ -z "$ZEBRA_TIP_DISK" ]]; then - echo "No TIP disk found for Zebra on network: ${NETWORK}" - echo "zebra_tip_disk=${{ toJSON(false) }}" >> "$GITHUB_OUTPUT" - else - echo "Disk: $ZEBRA_TIP_DISK" - echo "zebra_tip_disk=${{ toJSON(true) }}" >> "$GITHUB_OUTPUT" - fi - ZEBRA_CHECKPOINT_DISK=$(gcloud compute images list --filter="status=READY AND name~zebrad-cache-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-checkpoint" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1) - if [[ -z "$ZEBRA_CHECKPOINT_DISK" ]]; then - echo "No CHECKPOINT disk found for Zebra on network: ${NETWORK}" - echo "zebra_checkpoint_disk=${{ toJSON(false) }}" >> "$GITHUB_OUTPUT" - else - echo "Disk: $ZEBRA_CHECKPOINT_DISK" - echo "zebra_checkpoint_disk=${{ toJSON(true) }}" >> "$GITHUB_OUTPUT" - fi + source ./.github/workflows/scripts/gcp-get-cached-disks.sh + echo "state_version=${LOCAL_STATE_VERSION}" >> "${GITHUB_OUTPUT}" + echo "cached_disk_name=${CACHED_DISK_NAME}" >> "${GITHUB_OUTPUT}" + echo "lwd_tip_disk=${LWD_TIP_DISK}" >> "${GITHUB_OUTPUT}" + echo "zebra_tip_disk=${ZEBRA_TIP_DISK}" >> "${GITHUB_OUTPUT}" + echo "zebra_checkpoint_disk=${ZEBRA_CHECKPOINT_DISK}" >> "${GITHUB_OUTPUT}" diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index b67cf5ee5b5..b6613e97157 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -250,23 +250,20 @@ case "$1" in # Run a Zebra full sync test on mainnet. run_cargo_test "${ENTRYPOINT_FEATURES}" "full_sync_mainnet" # List directory generated by test - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - check_directory_files "/zebrad-cache" + check_directory_files "${ZEBRA_CACHED_STATE_DIR}" elif [[ -n "${FULL_SYNC_TESTNET_TIMEOUT_MINUTES}" ]]; then # Run a Zebra full sync test on testnet. run_cargo_test "${ENTRYPOINT_FEATURES}" "full_sync_testnet" # List directory generated by test - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - check_directory_files "/zebrad-cache" + check_directory_files "${ZEBRA_CACHED_STATE_DIR}" elif [[ "${TEST_DISK_REBUILD}" -eq "1" ]]; then # Run a Zebra sync up to the mandatory checkpoint. # # TODO: use environmental variables instead of Rust features (part of #2995) run_cargo_test "test_sync_to_mandatory_checkpoint_${NETWORK,,},${ENTRYPOINT_FEATURES}" "sync_to_mandatory_checkpoint_${NETWORK,,}" - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - check_directory_files "/zebrad-cache" + check_directory_files "${ZEBRA_CACHED_STATE_DIR}" elif [[ "${TEST_UPDATE_SYNC}" -eq "1" ]]; then # Run a Zebra sync starting at the cached tip, and syncing to the latest tip. @@ -279,8 +276,7 @@ case "$1" in # Run a Zebra sync starting at the cached mandatory checkpoint, and syncing past it. # # List directory used by test - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - check_directory_files "/zebrad-cache" + check_directory_files "${ZEBRA_CACHED_STATE_DIR}" # TODO: use environmental variables instead of Rust features (part of #2995) run_cargo_test "test_sync_past_mandatory_checkpoint_${NETWORK,,},${ENTRYPOINT_FEATURES}" "sync_past_mandatory_checkpoint_${NETWORK,,}" @@ -368,4 +364,4 @@ case "$1" in exec "$@" fi ;; -esac \ No newline at end of file +esac diff --git a/zebrad/tests/acceptance.rs b/zebrad/tests/acceptance.rs index c21b0a0e3e3..cd3572ce3f2 100644 --- a/zebrad/tests/acceptance.rs +++ b/zebrad/tests/acceptance.rs @@ -29,9 +29,10 @@ //! - `FULL_SYNC_MAINNET_TIMEOUT_MINUTES` env variable: The total number of minutes we //! will allow this test to run or give up. Value for the Mainnet full sync tests. //! - `FULL_SYNC_TESTNET_TIMEOUT_MINUTES` env variable: The total number of minutes we -//! will allow this test to run or give up. Value for the Testnet ful sync tests. -//! - `/zebrad-cache` directory: For some sync tests, this needs to be created in -//! the file system, the created directory should have write permissions. +//! will allow this test to run or give up. Value for the Testnet full sync tests. +//! - `ZEBRA_CACHED_STATE_DIR` env variable: The path to a Zebra cached state directory. +//! If not set, it defaults to `/zebrad-cache`. For some sync tests, this directory needs to be +//! created in the file system with write permissions. //! //! Here are some examples on how to run each of the tests: //! @@ -40,13 +41,15 @@ //! //! $ cargo test sync_large_checkpoints_mempool_mainnet -- --ignored --nocapture //! -//! $ sudo mkdir /zebrad-cache -//! $ sudo chmod 777 /zebrad-cache +//! $ export ZEBRA_CACHED_STATE_DIR="/zebrad-cache" +//! $ sudo mkdir -p "$ZEBRA_CACHED_STATE_DIR" +//! $ sudo chmod 777 "$ZEBRA_CACHED_STATE_DIR" //! $ export FULL_SYNC_MAINNET_TIMEOUT_MINUTES=600 //! $ cargo test full_sync_mainnet -- --ignored --nocapture //! -//! $ sudo mkdir /zebrad-cache -//! $ sudo chmod 777 /zebrad-cache +//! $ export ZEBRA_CACHED_STATE_DIR="/zebrad-cache" +//! $ sudo mkdir -p "$ZEBRA_CACHED_STATE_DIR" +//! $ sudo chmod 777 "$ZEBRA_CACHED_STATE_DIR" //! $ export FULL_SYNC_TESTNET_TIMEOUT_MINUTES=600 //! $ cargo test full_sync_testnet -- --ignored --nocapture //! ``` @@ -67,9 +70,10 @@ //! at least the `ZEBRA_TEST_LIGHTWALLETD` environment variable is present: //! //! - `ZEBRA_TEST_LIGHTWALLETD` env variable: Needs to be present to run any of the lightwalletd tests. -//! - `ZEBRA_CACHED_STATE_DIR` env var: The path to a zebra blockchain database. -//! - `LIGHTWALLETD_DATA_DIR` env variable. The path to a lightwalletd database. -//! - `--features lightwalletd-grpc-tests` cargo flag. The flag given to cargo to build the source code of the running test. +//! - `ZEBRA_CACHED_STATE_DIR` env variable: The path to a Zebra cached state directory. +//! If not set, it defaults to `/zebrad-cache`. +//! - `LIGHTWALLETD_DATA_DIR` env variable: The path to a lightwalletd database. +//! - `--features lightwalletd-grpc-tests` cargo flag: The flag given to cargo to build the source code of the running test. //! //! Here are some examples of running each test: //! diff --git a/zebrad/tests/common/sync.rs b/zebrad/tests/common/sync.rs index ff5234c2b1e..bac394099f5 100644 --- a/zebrad/tests/common/sync.rs +++ b/zebrad/tests/common/sync.rs @@ -5,7 +5,7 @@ //! Test functions in this file will not be run. //! This file is only for test library code. -use std::{path::PathBuf, time::Duration}; +use std::{env, path::PathBuf, time::Duration}; use tempfile::TempDir; @@ -326,10 +326,20 @@ pub fn check_sync_logs_until( Ok(zebrad) } +/// Returns the cache directory for Zebra's state. +/// +/// It checks the `ZEBRA_CACHED_STATE_DIR` environment variable and returns its value if set. +/// Otherwise, it defaults to `"/zebrad-cache"`. +fn get_zebra_cached_state_dir() -> PathBuf { + env::var("ZEBRA_CACHED_STATE_DIR") + .unwrap_or_else(|_| "/zebrad-cache".to_string()) + .into() +} + /// Returns a test config for caching Zebra's state up to the mandatory checkpoint. pub fn cached_mandatory_checkpoint_test_config(network: &Network) -> Result { let mut config = persistent_test_config(network)?; - config.state.cache_dir = "/zebrad-cache".into(); + config.state.cache_dir = get_zebra_cached_state_dir(); // To get to the mandatory checkpoint, we need to sync lots of blocks. // (Most tests use a smaller limit to minimise redundant block downloads.) @@ -377,7 +387,7 @@ pub fn create_cached_database_height( config.state.debug_stop_at_height = Some(height.0); config.consensus.checkpoint_sync = checkpoint_sync; - let dir = PathBuf::from("/zebrad-cache"); + let dir = get_zebra_cached_state_dir(); let mut child = dir .with_exact_config(&config)? .spawn_child(args!["start"])? From 8870b2c60eb898b2bb441fc02122decd9cd51b9f Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Thu, 19 Sep 2024 14:12:09 +0100 Subject: [PATCH 29/46] feat(cd): deploy instances with attached cached states (#8868) * ref(ci): consolidate cached states workflows and scripts We've been using multiple approaches to locate and retrieve cached states in GCP. However, this has made it difficult to reuse the same methods across new workflows or different scenarios. To address this, we've streamlined the process to make it more reusable in other contexts. This change will support deploying instances from both the `main` branch and `release`, simplifying future implementations and speeding up the process. Changes: - Use a single bash script (`gcp-get-cached-disks.sh`) to get cached states names and availability - Move script logic from `sub-find-cached-disks.yml` to `gcp-get-cached-disks.sh` and adapt `sub-find-cached-disks.yml` to allow to output available disks and disks names. - Simplify parameters usage in `sub-deploy-integration-tests-gcp.yml` and convert the `Find ${{ inputs.test_id }} cached state disk` step into an independent job, to be able to use the `sub-find-cached-disks.yml` reusable workflow - Remove repetition in `sub-ci-integration-tests-gcp.yml` * ref(tests): Use the `ZEBRA_CACHED_STATE_DIR` env var across tests We had a technical debt with some tests using a hardcoded value for the cache directory (`/zebrad-cache`), which generated inconsistency across disks and cached states directories. Changes: - Allow sync tests to use the `ZEBRA_CACHED_STATE_DIR` as the cache directory, if specified - Update the `entrypoint.sh` to reflect this change - Add the `ZEBRA_CACHED_STATE_DIR` variable to the missing tests in `sub-ci-integration-tests-gcp.yml`, and remove extra parameters to call reusable workflows. * feat(cd): deploy instances with cached states * fix(cd): allow deploying from branch * fix(cd): add missing `CACHED_DISK_NAME` env --- .github/workflows/cd-deploy-nodes-gcp.yml | 107 ++++++++++++++-------- 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/.github/workflows/cd-deploy-nodes-gcp.yml b/.github/workflows/cd-deploy-nodes-gcp.yml index 4e90f7392c2..fcd14715e8a 100644 --- a/.github/workflows/cd-deploy-nodes-gcp.yml +++ b/.github/workflows/cd-deploy-nodes-gcp.yml @@ -42,27 +42,26 @@ on: type: boolean default: false - # TODO: Temporarily disabled to reduce network load, see #6894. - #push: - # # Skip main branch updates where Rust code and dependencies aren't modified. - # branches: - # - main - # paths: - # # code and tests - # - '**/*.rs' - # # hard-coded checkpoints and proptest regressions - # - '**/*.txt' - # # dependencies - # - '**/Cargo.toml' - # - '**/Cargo.lock' - # # configuration files - # - '.cargo/config.toml' - # - '**/clippy.toml' - # # workflow definitions - # - 'docker/**' - # - '.dockerignore' - # - '.github/workflows/cd-deploy-nodes-gcp.yml' - # - '.github/workflows/sub-build-docker-image.yml' + push: + # Skip main branch updates where Rust code and dependencies aren't modified. + branches: + - main + paths: + # code and tests + - '**/*.rs' + # hard-coded checkpoints and proptest regressions + - '**/*.txt' + # dependencies + - '**/Cargo.toml' + - '**/Cargo.lock' + # configuration files + - '.cargo/config.toml' + - '**/clippy.toml' + # workflow definitions + - 'docker/**' + - '.dockerignore' + - '.github/workflows/cd-deploy-nodes-gcp.yml' + - '.github/workflows/sub-build-docker-image.yml' # Only runs the Docker image tests, doesn't deploy any instances pull_request: @@ -176,6 +175,19 @@ jobs: test_variables: '-e NETWORK -e ZEBRA_CONF_PATH="zebrad/tests/common/configs/v1.0.0-rc.2.toml"' network: ${{ inputs.network || vars.ZCASH_NETWORK }} + # Finds a `tip` cached state disk for zebra from the main branch + # + # Passes the disk name to subsequent jobs using `cached_disk_name` output + # + get-disk-name: + name: Get disk name + uses: ./.github/workflows/sub-find-cached-disks.yml + with: + network: ${{ inputs.network || vars.ZCASH_NETWORK }} + disk_prefix: zebrad-cache + disk_suffix: tip + prefer_main_cached_state: true + # Deploy Managed Instance Groups (MiGs) for Mainnet and Testnet, # with one node in the configured GCP region. # @@ -196,9 +208,11 @@ jobs: matrix: network: [Mainnet, Testnet] name: Deploy ${{ matrix.network }} nodes - needs: [ build, versioning, test-configuration-file, test-zebra-conf-path ] + needs: [ build, versioning, test-configuration-file, test-zebra-conf-path, get-disk-name ] runs-on: ubuntu-latest timeout-minutes: 60 + env: + CACHED_DISK_NAME: ${{ needs.get-disk-name.outputs.cached_disk_name }} permissions: contents: 'read' id-token: 'write' @@ -240,24 +254,31 @@ jobs: # but the implementation is failing as it's requiring the disk names, contrary to what is stated in the official documentation - name: Create instance template for ${{ matrix.network }} run: | + NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}" + DISK_PARAMS="name=${NAME},device-name=${NAME},size=400GB,type=pd-ssd" + if [ -n "${{ env.CACHED_DISK_NAME }}" ]; then + DISK_PARAMS+=",image=${{ env.CACHED_DISK_NAME }}" + else + echo "No cached disk found for ${{ matrix.network }} in main branch" + exit 1 + fi gcloud compute instance-templates create-with-container zebrad-${{ needs.versioning.outputs.major_version || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK} \ - --boot-disk-size 300GB \ + --machine-type ${{ vars.GCP_SMALL_MACHINE }} \ + --boot-disk-size 50GB \ --boot-disk-type=pd-ssd \ --image-project=cos-cloud \ --image-family=cos-stable \ - --user-output-enabled \ - --metadata google-logging-enabled=true,google-logging-use-fluentbit=true,google-monitoring-enabled=true \ + --network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \ + --create-disk="${DISK_PARAMS}" \ + --container-mount-disk=mount-path='/var/cache/zebrad-cache',name=${NAME},mode=rw \ --container-stdin \ --container-tty \ --container-image ${{ vars.GAR_BASE }}/zebrad@${{ needs.build.outputs.image_digest }} \ --container-env "NETWORK=${{ matrix.network }},LOG_FILE=${{ vars.CD_LOG_FILE }},LOG_COLOR=false,SENTRY_DSN=${{ vars.SENTRY_DSN }}" \ - --create-disk=name=zebrad-cache-${{ env.GITHUB_SHA_SHORT }}-${NETWORK},device-name=zebrad-cache-${{ env.GITHUB_SHA_SHORT }}-${NETWORK},auto-delete=yes,size=300GB,type=pd-ssd,mode=rw \ - --container-mount-disk=mount-path='/var/cache/zebrad-cache',name=zebrad-cache-${{ env.GITHUB_SHA_SHORT }}-${NETWORK},mode=rw \ - --machine-type ${{ vars.GCP_SMALL_MACHINE }} \ - --network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \ --service-account ${{ vars.GCP_DEPLOYMENTS_SA }} \ --scopes cloud-platform \ - --labels=app=zebrad,environment=prod,network=${NETWORK},github_ref=${{ env.GITHUB_REF_SLUG_URL }} \ + --metadata google-logging-enabled=true,google-logging-use-fluentbit=true,google-monitoring-enabled=true \ + --labels=app=zebrad,environment=staging,network=${NETWORK},github_ref=${{ env.GITHUB_REF_SLUG_URL }} \ --tags zebrad # Check if our destination instance group exists already @@ -297,9 +318,11 @@ jobs: # Note: this instances are not automatically replaced or deleted deploy-instance: name: Deploy single ${{ inputs.network }} instance - needs: [ build, test-configuration-file, test-zebra-conf-path ] + needs: [ build, test-configuration-file, test-zebra-conf-path, get-disk-name ] runs-on: ubuntu-latest timeout-minutes: 30 + env: + CACHED_DISK_NAME: ${{ needs.get-disk-name.outputs.cached_disk_name }} permissions: contents: 'read' id-token: 'write' @@ -340,22 +363,30 @@ jobs: # Create instance template from container image - name: Manual deploy of a single ${{ inputs.network }} instance running zebrad run: | + NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}" + DISK_PARAMS="name=${NAME},device-name=${NAME},size=400GB,type=pd-ssd" + if [ -n "${{ env.CACHED_DISK_NAME }}" ]; then + DISK_PARAMS+=",image=${{ env.CACHED_DISK_NAME }}" + else + echo "No cached disk found for ${{ matrix.network }} in main branch" + exit 1 + fi gcloud compute instances create-with-container "zebrad-${{ env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}" \ - --boot-disk-size 300GB \ + --machine-type ${{ vars.GCP_SMALL_MACHINE }} \ + --boot-disk-size 50GB \ --boot-disk-type=pd-ssd \ --image-project=cos-cloud \ --image-family=cos-stable \ - --user-output-enabled \ - --metadata google-logging-enabled=true,google-logging-use-fluentbit=true,google-monitoring-enabled=true \ + --network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \ + --create-disk="${DISK_PARAMS}" \ + --container-mount-disk=mount-path='/var/cache/zebrad-cache',name=${NAME},mode=rw \ --container-stdin \ --container-tty \ --container-image ${{ vars.GAR_BASE }}/zebrad@${{ needs.build.outputs.image_digest }} \ --container-env "NETWORK=${{ inputs.network }},LOG_FILE=${{ inputs.log_file }},LOG_COLOR=false,SENTRY_DSN=${{ vars.SENTRY_DSN }}" \ - --create-disk=name=zebrad-cache-${{ env.GITHUB_SHA_SHORT }}-${NETWORK},device-name=zebrad-cache-${{ env.GITHUB_SHA_SHORT }}-${NETWORK},auto-delete=yes,size=300GB,type=pd-ssd,mode=rw \ - --container-mount-disk=mount-path='/var/cache/zebrad-cache',name=zebrad-cache-${{ env.GITHUB_SHA_SHORT }}-${NETWORK},mode=rw \ - --machine-type ${{ vars.GCP_SMALL_MACHINE }} \ - --network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \ --service-account ${{ vars.GCP_DEPLOYMENTS_SA }} \ + --scopes cloud-platform \ + --metadata google-logging-enabled=true,google-monitoring-enabled=true \ --labels=app=zebrad,environment=qa,network=${NETWORK},github_ref=${{ env.GITHUB_REF_SLUG_URL }} \ --tags zebrad \ --zone ${{ vars.GCP_ZONE }} From 69519884565bf357ba8a81153f52588bc9882f88 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Thu, 19 Sep 2024 18:25:40 +0100 Subject: [PATCH 30/46] chore(docker): remove debugging output by default (#8870) --- docker/entrypoint.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index b6613e97157..d71be57805d 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -10,8 +10,6 @@ # 4. Node Startup: Starts the node, allowing it to begin its operations. # -# Show the commands we are executing -set -x # Exit if a command fails set -e # Exit if any command in a pipeline fails From c8280d488f08476ae1aa33103380fb5823f2d5e8 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Fri, 20 Sep 2024 13:36:20 -0300 Subject: [PATCH 31/46] feat(tests): Move the RPC tests framework from zcashd (#8866) * move the rpc-tests framework from zcashd * ignore pycache * remove all tests from the list except getmininginfo * iimprove a bit the readme * change some env variable names * add cache, add reindex test * fix the paralell framework * fix env variables * change tests order * update docs with env variable name change * fix binary location * reduce base config * restore env var * ignore stderr in the output --- .gitignore | 6 + zebra-rpc/qa/README.md | 88 + zebra-rpc/qa/base_config.toml | 12 + zebra-rpc/qa/pull-tester/rpc-tests.py | 401 ++++ zebra-rpc/qa/pull-tester/tests_config.ini | 19 + zebra-rpc/qa/rpc-tests/create_cache.py | 31 + zebra-rpc/qa/rpc-tests/getmininginfo.py | 47 + zebra-rpc/qa/rpc-tests/reindex.py | 54 + .../qa/rpc-tests/test_framework/__init__.py | 0 .../qa/rpc-tests/test_framework/authproxy.py | 166 ++ .../qa/rpc-tests/test_framework/bignum.py | 100 + .../qa/rpc-tests/test_framework/blockstore.py | 142 ++ .../qa/rpc-tests/test_framework/blocktools.py | 110 + .../qa/rpc-tests/test_framework/comptool.py | 446 ++++ .../qa/rpc-tests/test_framework/coverage.py | 107 + .../qa/rpc-tests/test_framework/equihash.py | 294 +++ .../qa/rpc-tests/test_framework/flyclient.py | 207 ++ zebra-rpc/qa/rpc-tests/test_framework/key.py | 215 ++ .../qa/rpc-tests/test_framework/mininode.py | 2131 +++++++++++++++++ .../qa/rpc-tests/test_framework/netutil.py | 157 ++ .../qa/rpc-tests/test_framework/proxy.py | 157 ++ .../qa/rpc-tests/test_framework/script.py | 979 ++++++++ .../qa/rpc-tests/test_framework/socks5.py | 162 ++ .../test_framework/test_framework.py | 211 ++ zebra-rpc/qa/rpc-tests/test_framework/util.py | 802 +++++++ .../qa/rpc-tests/test_framework/zip244.py | 294 +++ .../qa/rpc-tests/test_framework/zip317.py | 39 + 27 files changed, 7377 insertions(+) create mode 100644 zebra-rpc/qa/README.md create mode 100644 zebra-rpc/qa/base_config.toml create mode 100755 zebra-rpc/qa/pull-tester/rpc-tests.py create mode 100755 zebra-rpc/qa/pull-tester/tests_config.ini create mode 100755 zebra-rpc/qa/rpc-tests/create_cache.py create mode 100755 zebra-rpc/qa/rpc-tests/getmininginfo.py create mode 100755 zebra-rpc/qa/rpc-tests/reindex.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/__init__.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/authproxy.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/bignum.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/blockstore.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/blocktools.py create mode 100755 zebra-rpc/qa/rpc-tests/test_framework/comptool.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/coverage.py create mode 100755 zebra-rpc/qa/rpc-tests/test_framework/equihash.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/flyclient.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/key.py create mode 100755 zebra-rpc/qa/rpc-tests/test_framework/mininode.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/netutil.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/proxy.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/script.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/socks5.py create mode 100755 zebra-rpc/qa/rpc-tests/test_framework/test_framework.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/util.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/zip244.py create mode 100644 zebra-rpc/qa/rpc-tests/test_framework/zip317.py diff --git a/.gitignore b/.gitignore index b4af6c0b81e..8bccc34ffc0 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,9 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk + +# Python pycache +__pycache__/ + +# RPC tests cache +zebra-rpc/qa/cache/ diff --git a/zebra-rpc/qa/README.md b/zebra-rpc/qa/README.md new file mode 100644 index 00000000000..cc46d7b54ef --- /dev/null +++ b/zebra-rpc/qa/README.md @@ -0,0 +1,88 @@ +The [pull-tester](/pull-tester/) folder contains a script to call +multiple tests from the [rpc-tests](/rpc-tests/) folder. + +Every pull request to the zebra repository is built and run through +the regression test suite. You can also run all or only individual +tests locally. + +Test dependencies +================= + +Before running the tests, the following must be installed. + +Unix +---- + +The `zmq`, `toml` and `base58` Python libraries are required. On Ubuntu or Debian-based +distributions they can be installed via: +``` +sudo apt-get install python3-zmq python3-base58 +``` + +OS X +------ + +``` +pip3 install pyzmq base58 toml +``` + +Running tests locally +===================== + +Make sure `zebrad` binary exists in the `../target/debug/` folder or set the binary path with: +``` +export CARGO_BIN_EXE_zebrad=/path/to/zebrad +``` + +You can run any single test by calling + + ./qa/pull-tester/rpc-tests.py + +Run the regression test suite with + + ./qa/pull-tester/rpc-tests.py + +By default, tests will be run in parallel. To specify how many jobs to run, +append `--jobs=n` (default n=4). + +If you want to create a basic coverage report for the RPC test suite, append `--coverage`. + +Possible options, which apply to each individual test run: + +``` + -h, --help show this help message and exit + --nocleanup Leave zcashds and test.* datadir on exit or error + --noshutdown Don't stop zcashds after the test execution + --srcdir=SRCDIR Source directory containing zcashd/zcash-cli + (default: ../../src) + --tmpdir=TMPDIR Root directory for datadirs + --tracerpc Print out all RPC calls as they are made + --coveragedir=COVERAGEDIR + Write tested RPC commands into this directory +``` + +If you set the environment variable `PYTHON_DEBUG=1` you will get some debug +output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.py wallet`). + +A 200-block -regtest blockchain and wallets for four nodes +is created the first time a regression test is run and +is stored in the cache/ directory. Each node has the miner +subsidy from 25 mature blocks (25*10=250 ZEC) in its wallet. + +After the first run, the cache/ blockchain and wallets are +copied into a temporary directory and used as the initial +test state. + +If you get into a bad state, you should be able +to recover with: + +```bash +rm -rf cache +killall zcashd +``` + +Writing tests +============= +You are encouraged to write tests for new or existing features. +Further information about the test framework and individual RPC +tests is found in [rpc-tests](rpc-tests). diff --git a/zebra-rpc/qa/base_config.toml b/zebra-rpc/qa/base_config.toml new file mode 100644 index 00000000000..502a2a75b1d --- /dev/null +++ b/zebra-rpc/qa/base_config.toml @@ -0,0 +1,12 @@ +[mining] +miner_address = "t27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v" + +[network] +listen_addr = "127.0.0.1:0" +network = "Regtest" + +[rpc] +listen_addr = "127.0.0.1:0" + +[state] +cache_dir = "" diff --git a/zebra-rpc/qa/pull-tester/rpc-tests.py b/zebra-rpc/qa/pull-tester/rpc-tests.py new file mode 100755 index 00000000000..00194f0aa53 --- /dev/null +++ b/zebra-rpc/qa/pull-tester/rpc-tests.py @@ -0,0 +1,401 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2020-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +""" +rpc-tests.py - run regression test suite + +This module calls down into individual test cases via subprocess. It will +forward all unrecognized arguments onto the individual test scripts. + +RPC tests are disabled on Windows by default. Use --force to run them anyway. + +For a description of arguments recognized by test scripts, see +`qa/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. + +""" + +import argparse +import configparser +import os +import time +import shutil +import sys +import subprocess +import tempfile +import re + +SERIAL_SCRIPTS = [ + # These tests involve enough shielded spends (consuming all CPU + # cores) that we can't run them in parallel. +] + +FLAKY_SCRIPTS = [ + # These tests have intermittent failures that we haven't diagnosed yet. +] + +BASE_SCRIPTS= [ + # Scripts that are run by the travis build process + # Longest test should go first, to favor running tests in parallel + 'reindex.py', + 'getmininginfo.py'] + +ZMQ_SCRIPTS = [ + # ZMQ test can only be run if bitcoin was built with zmq-enabled. + # call rpc_tests.py with --nozmq to explicitly exclude these tests. +] + +EXTENDED_SCRIPTS = [ + # These tests are not run by the travis build process. + # Longest test should go first, to favor running tests in parallel +] + +ALL_SCRIPTS = SERIAL_SCRIPTS + FLAKY_SCRIPTS + BASE_SCRIPTS + ZMQ_SCRIPTS + EXTENDED_SCRIPTS + +def main(): + # Parse arguments and pass through unrecognised args + parser = argparse.ArgumentParser(add_help=False, + usage='%(prog)s [rpc-test.py options] [script options] [scripts]', + description=__doc__, + epilog=''' + Help text and arguments for individual test script:''', + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') + parser.add_argument('--deterministic', '-d', action='store_true', help='make the output a bit closer to deterministic in order to compare runs.') + parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude. Do not include the .py extension in the name.') + parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') + parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') + parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') + parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.') + parser.add_argument('--machines', '-m', type=int, default=-1, help='how many machines to shard the tests over. must also provide individual shard index. Default=-1 (no sharding).') + parser.add_argument('--rpcgroup', '-r', type=int, default=-1, help='individual shard index. must also provide how many machines to shard the tests over. Default=-1 (no sharding).') + parser.add_argument('--nozmq', action='store_true', help='do not run the zmq tests') + args, unknown_args = parser.parse_known_args() + + # Create a set to store arguments and create the passon string + tests = set(arg for arg in unknown_args if arg[:2] != "--") + passon_args = [arg for arg in unknown_args if arg[:2] == "--"] + + # Read config generated by configure. + config = configparser.ConfigParser() + config.read_file(open(os.path.dirname(__file__) + "/tests_config.ini")) + + enable_wallet = config["components"].getboolean("ENABLE_WALLET") + enable_utils = config["components"].getboolean("ENABLE_UTILS") + enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") + enable_zmq = config["components"].getboolean("ENABLE_ZMQ") and not args.nozmq + + if config["environment"]["EXEEXT"] == ".exe" and not args.force: + # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 + print("Tests currently disabled on Windows by default. Use --force option to enable") + sys.exit(0) + + if not (enable_wallet and enable_utils and enable_bitcoind): + print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") + print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") + sys.exit(0) + + # python3-zmq may not be installed. Handle this gracefully and with some helpful info + if enable_zmq: + try: + import zmq + zmq # Silences pyflakes + except ImportError: + print("ERROR: \"import zmq\" failed. Use --nozmq to run without the ZMQ tests." + "To run zmq tests, see dependency info in /qa/README.md.") + raise + + # Build list of tests + if tests: + # Individual tests have been specified. Run specified tests that exist + # in the ALL_SCRIPTS list. Accept the name with or without .py extension. + test_list = [t for t in ALL_SCRIPTS if + (t in tests or re.sub(".py$", "", t) in tests)] + + print("Running individually selected tests: ") + for t in test_list: + print("\t" + t) + else: + # No individual tests have been specified. Run base tests, and + # optionally ZMQ tests and extended tests. + test_list = SERIAL_SCRIPTS + FLAKY_SCRIPTS + BASE_SCRIPTS + if enable_zmq: + test_list += ZMQ_SCRIPTS + if args.extended: + test_list += EXTENDED_SCRIPTS + # TODO: BASE_SCRIPTS and EXTENDED_SCRIPTS are sorted by runtime + # (for parallel running efficiency). This combined list will is no + # longer sorted. + + # Remove the test cases that the user has explicitly asked to exclude. + if args.exclude: + for exclude_test in args.exclude.split(','): + if exclude_test + ".py" in test_list: + test_list.remove(exclude_test + ".py") + + if not test_list: + print("No valid test scripts specified. Check that your test is in one " + "of the test lists in rpc-tests.py, or run rpc-tests.py with no arguments to run all tests") + sys.exit(0) + + if args.help: + # Print help for rpc-tests.py, then print help of the first script and exit. + parser.print_help() + subprocess.check_call((config["environment"]["SRCDIR"] + '/qa/rpc-tests/' + test_list[0]).split() + ['-h']) + sys.exit(0) + + + if (args.rpcgroup == -1) != (args.machines == -1): + print("ERROR: Please use both -m and -r options when using parallel rpc_groups.") + sys.exit(0) + if args.machines == 0: + print("ERROR: -m/--machines must be greater than 0") + sys.exit(0) + if args.machines > 0 and (args.rpcgroup >= args.machines): + print("ERROR: -r/--rpcgroup must be less than -m/--machines") + sys.exit(0) + if args.rpcgroup != -1 and args.machines != -1 and args.machines > args.rpcgroup: + # Ceiling division using floor division, by inverting the world. + # https://stackoverflow.com/a/17511341 + k = -(len(test_list) // -args.machines) + split_list = list(test_list[i*k:(i+1)*k] for i in range(args.machines)) + tests_to_run = split_list[args.rpcgroup] + else: + tests_to_run = test_list + all_passed = run_tests( + RPCTestHandler, + tests_to_run, + config["environment"]["SRCDIR"], + config["environment"]["BUILDDIR"], + config["environment"]["EXEEXT"], + args.jobs, + args.coverage, + args.deterministic, + passon_args) + sys.exit(not all_passed) + +def run_tests(test_handler, test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, deterministic=False, args=[]): + BOLD = ("","") + if os.name == 'posix': + # primitive formatting on supported + # terminal via ANSI escape sequences: + BOLD = ('\033[0m', '\033[1m') + + #Set env vars + if "CARGO_BIN_EXE_zebrad" not in os.environ: + os.environ["CARGO_BIN_EXE_zebrad"] = os.path.join("..", "target", "debug", "zebrad") + + tests_dir = src_dir + '/qa/rpc-tests/' + + flags = ["--srcdir={}/src".format(build_dir)] + args + flags.append("--cachedir=%s/qa/cache" % build_dir) + + if enable_coverage: + coverage = RPCCoverage() + flags.append(coverage.flag) + print("Initializing coverage directory at %s\n" % coverage.dir) + else: + coverage = None + + if len(test_list) > 1 and jobs > 1: + # Populate cache + subprocess.check_output([tests_dir + 'create_cache.py'] + flags) + + #Run Tests + time_sum = 0 + time0 = time.time() + + job_queue = test_handler(jobs, tests_dir, test_list, flags) + + max_len_name = len(max(test_list, key=len)) + total_count = 0 + passed_count = 0 + results = [] + try: + for _ in range(len(test_list)): + (name, stdout, stderr, passed, duration) = job_queue.get_next(deterministic) + time_sum += duration + + print('\n' + BOLD[1] + name + BOLD[0] + ":") + print('' if passed else stdout + '\n', end='') + # TODO: Zebrad always produce the welcome message in the stderr. + # Ignoring stderr output here until that is fixed. + #print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') + print("Pass: %s%s%s" % (BOLD[1], passed, BOLD[0]), end='') + if deterministic: + print("\n", end='') + else: + print(", Duration: %s s" % (duration,)) + total_count += 1 + if passed: + passed_count += 1 + + new_result = "%s | %s" % (name.ljust(max_len_name), str(passed).ljust(6)) + if not deterministic: + new_result += (" | %s s" % (duration,)) + results.append(new_result) + except (InterruptedError, KeyboardInterrupt): + print('\nThe following tests were running when interrupted:') + for j in job_queue.jobs: + print("•", j[0]) + print('\n', end='') + + all_passed = passed_count == total_count + + if all_passed: + success_rate = "True" + else: + success_rate = "%d/%d" % (passed_count, total_count) + header = "%s | PASSED" % ("TEST".ljust(max_len_name),) + footer = "%s | %s" % ("ALL".ljust(max_len_name), str(success_rate).ljust(6)) + if not deterministic: + header += " | DURATION" + footer += " | %s s (accumulated)\nRuntime: %s s" % (time_sum, int(time.time() - time0)) + print( + BOLD[1] + header + BOLD[0] + "\n\n" + + "\n".join(sorted(results)) + "\n" + + BOLD[1] + footer + BOLD[0]) + + if coverage: + coverage.report_rpc_coverage() + + print("Cleaning up coverage data") + coverage.cleanup() + + return all_passed + +class RPCTestHandler: + """ + Trigger the testscrips passed in via the list. + """ + + def __init__(self, num_tests_parallel, tests_dir, test_list=None, flags=None): + assert(num_tests_parallel >= 1) + self.num_jobs = num_tests_parallel + self.tests_dir = tests_dir + self.test_list = test_list + self.flags = flags + self.num_running = 0 + # In case there is a graveyard of zombie bitcoinds, we can apply a + # pseudorandom offset to hopefully jump over them. + # (625 is PORT_RANGE/MAX_NODES) + self.portseed_offset = int(time.time() * 1000) % 625 + self.jobs = [] + + def start_test(self, args, stdout, stderr): + return subprocess.Popen( + args, + universal_newlines=True, + stdout=stdout, + stderr=stderr) + + def get_next(self, deterministic): + while self.num_running < self.num_jobs and self.test_list: + # Add tests + self.num_running += 1 + t = self.test_list.pop(0) + port_seed = ["--portseed={}".format(len(self.test_list) + self.portseed_offset)] + log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) + log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) + self.jobs.append((t, + time.time(), + self.start_test((self.tests_dir + t).split() + self.flags + port_seed, + log_stdout, + log_stderr), + log_stdout, + log_stderr)) + # Run serial scripts on their own. We always run these first, + # so we won't have added any other jobs yet. + if t in SERIAL_SCRIPTS: + break + if not self.jobs: + raise IndexError('pop from empty list') + while True: + # Return first proc that finishes + time.sleep(.5) + for j in self.jobs: + (name, time0, proc, log_out, log_err) = j + if proc.poll() is not None: + log_out.seek(0), log_err.seek(0) + [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)] + log_out.close(), log_err.close() + # We can't check for an empty stderr in Zebra so we just check for the return code. + passed = proc.returncode == 0 + self.num_running -= 1 + self.jobs.remove(j) + return name, stdout, stderr, passed, int(time.time() - time0) + if not deterministic: + print('.', end='', flush=True) + + +class RPCCoverage(object): + """ + Coverage reporting utilities for pull-tester. + + Coverage calculation works by having each test script subprocess write + coverage files into a particular directory. These files contain the RPC + commands invoked during testing, as well as a complete listing of RPC + commands per `bitcoin-cli help` (`rpc_interface.txt`). + + After all tests complete, the commands run are combined and diff'd against + the complete list to calculate uncovered RPC commands. + + See also: qa/rpc-tests/test_framework/coverage.py + + """ + def __init__(self): + self.dir = tempfile.mkdtemp(prefix="coverage") + self.flag = '--coveragedir=%s' % self.dir + + def report_rpc_coverage(self): + """ + Print out RPC commands that were unexercised by tests. + + """ + uncovered = self._get_uncovered_rpc_commands() + + if uncovered: + print("Uncovered RPC commands:") + print("".join((" - %s\n" % i) for i in sorted(uncovered))) + else: + print("All RPC commands covered.") + + def cleanup(self): + return shutil.rmtree(self.dir) + + def _get_uncovered_rpc_commands(self): + """ + Return a set of currently untested RPC commands. + + """ + # This is shared from `qa/rpc-tests/test-framework/coverage.py` + reference_filename = 'rpc_interface.txt' + coverage_file_prefix = 'coverage.' + + coverage_ref_filename = os.path.join(self.dir, reference_filename) + coverage_filenames = set() + all_cmds = set() + covered_cmds = set() + + if not os.path.isfile(coverage_ref_filename): + raise RuntimeError("No coverage reference found") + + with open(coverage_ref_filename, 'r', encoding='utf8') as f: + all_cmds.update([i.strip() for i in f.readlines()]) + + for root, dirs, files in os.walk(self.dir): + for filename in files: + if filename.startswith(coverage_file_prefix): + coverage_filenames.add(os.path.join(root, filename)) + + for filename in coverage_filenames: + with open(filename, 'r', encoding='utf8') as f: + covered_cmds.update([i.strip() for i in f.readlines()]) + + return all_cmds - covered_cmds + + +if __name__ == '__main__': + main() diff --git a/zebra-rpc/qa/pull-tester/tests_config.ini b/zebra-rpc/qa/pull-tester/tests_config.ini new file mode 100755 index 00000000000..f3df78bc0f2 --- /dev/null +++ b/zebra-rpc/qa/pull-tester/tests_config.ini @@ -0,0 +1,19 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Copyright (c) 2020-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# These environment variables are set by the build process and read by +# rpc-tests.py + +[environment] +SRCDIR=. +BUILDDIR=. +EXEEXT= + +[components] +# Which components are enabled. These are commented out by `configure` if they were disabled when running config. +ENABLE_WALLET=true +ENABLE_UTILS=true +ENABLE_BITCOIND=true +ENABLE_ZMQ=false diff --git a/zebra-rpc/qa/rpc-tests/create_cache.py b/zebra-rpc/qa/rpc-tests/create_cache.py new file mode 100755 index 00000000000..4403e4ae312 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/create_cache.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2020-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Helper script to create the cache +# (see BitcoinTestFramework.setup_chain) +# + +from test_framework.test_framework import BitcoinTestFramework + +class CreateCache(BitcoinTestFramework): + + def __init__(self): + super().__init__() + + # Test network and test nodes are not required: + self.num_nodes = 0 + self.nodes = [] + + def setup_network(self): + pass + + def run_test(self): + pass + +if __name__ == '__main__': + CreateCache().main() + diff --git a/zebra-rpc/qa/rpc-tests/getmininginfo.py b/zebra-rpc/qa/rpc-tests/getmininginfo.py new file mode 100755 index 00000000000..ddd024aed2c --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/getmininginfo.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_nodes + + +class GetMiningInfoTest(BitcoinTestFramework): + ''' + Test getmininginfo. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.cache_behavior = 'clean' + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + self.is_network_split = False + self.sync_all() + + def run_test(self): + node = self.nodes[0] + + info = node.getmininginfo() + assert(info['blocks'] == 0) + # No blocks have been mined yet, so these fields should not be present. + assert('currentblocksize' not in info) + assert('currentblocktx' not in info) + + node.generate(1) + + info = node.getmininginfo() + assert(info['blocks'] == 1) + # One block has been mined, so these fields should now be present. + assert('currentblocksize' in info) + assert('currentblocktx' in info) + assert(info['currentblocksize'] > 0) + # The transaction count doesn't include the coinbase + assert(info['currentblocktx'] == 0) + + +if __name__ == '__main__': + GetMiningInfoTest().main() diff --git a/zebra-rpc/qa/rpc-tests/reindex.py b/zebra-rpc/qa/rpc-tests/reindex.py new file mode 100755 index 00000000000..a301c377ee0 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/reindex.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2017-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test -reindex and -reindex-chainstate with CheckBlockIndex +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + start_node, stop_node, wait_bitcoinds +import time + +class ReindexTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.cache_behavior = 'clean' + self.num_nodes = 1 + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + self.nodes.append(start_node(0, self.options.tmpdir)) + + def reindex(self, justchainstate=False): + # When zebra reindexes, it will only do it up to the finalized chain height. + # This happens after the first 100 blocks, so we need to generate 100 blocks + # for the reindex to be able to catch block 1. + finalized_height = 100 + + self.nodes[0].generate(finalized_height) + blockcount = self.nodes[0].getblockcount() - (finalized_height - 1) + + stop_node(self.nodes[0], 0) + wait_bitcoinds() + + self.nodes[0]=start_node(0, self.options.tmpdir) + + while self.nodes[0].getblockcount() < blockcount: + time.sleep(0.1) + assert_equal(self.nodes[0].getblockcount(), blockcount) + print("Success") + + def run_test(self): + self.reindex(False) + self.reindex(True) + self.reindex(False) + self.reindex(True) + +if __name__ == '__main__': + ReindexTest().main() diff --git a/zebra-rpc/qa/rpc-tests/test_framework/__init__.py b/zebra-rpc/qa/rpc-tests/test_framework/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/zebra-rpc/qa/rpc-tests/test_framework/authproxy.py b/zebra-rpc/qa/rpc-tests/test_framework/authproxy.py new file mode 100644 index 00000000000..e555706365e --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/authproxy.py @@ -0,0 +1,166 @@ +""" + Copyright 2011 Jeff Garzik + + AuthServiceProxy has the following improvements over python-jsonrpc's + ServiceProxy class: + + - HTTP connections persist for the life of the AuthServiceProxy object + (if server supports HTTP/1.1) + - sends protocol 'version', per JSON-RPC 1.1 + - sends proper, incrementing 'id' + - sends Basic HTTP authentication headers + - parses all JSON numbers that look like floats as Decimal + - uses standard Python json lib + + Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: + + Copyright (c) 2007 Jan-Klaas Kollhof + + This file is part of jsonrpc. + + jsonrpc is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this software; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" + +import base64 +import decimal +import json +import logging +from http.client import HTTPConnection, HTTPSConnection, BadStatusLine +from urllib.parse import urlparse + +USER_AGENT = "AuthServiceProxy/0.1" + +HTTP_TIMEOUT = 600 + +log = logging.getLogger("BitcoinRPC") + +class JSONRPCException(Exception): + def __init__(self, rpc_error): + Exception.__init__(self, rpc_error.get("message")) + self.error = rpc_error + +def EncodeDecimal(o): + if isinstance(o, decimal.Decimal): + return str(o) + raise TypeError(repr(o) + " is not JSON serializable") + + +class AuthServiceProxy(): + __id_count = 0 + + def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): + self.__service_url = service_url + self._service_name = service_name + self.__url = urlparse(service_url) + (user, passwd) = (self.__url.username, self.__url.password) + try: + user = user.encode('utf8') + except AttributeError: + pass + try: + passwd = passwd.encode('utf8') + except AttributeError: + pass + authpair = user + b':' + passwd + self.__auth_header = b'Basic ' + base64.b64encode(authpair) + + self.timeout = timeout + self._set_conn(connection) + + def _set_conn(self, connection=None): + port = 80 if self.__url.port is None else self.__url.port + if connection: + self.__conn = connection + self.timeout = connection.timeout + elif self.__url.scheme == 'https': + self.__conn = HTTPSConnection(self.__url.hostname, port, timeout=self.timeout) + else: + self.__conn = HTTPConnection(self.__url.hostname, port, timeout=self.timeout) + + def __getattr__(self, name): + if name.startswith('__') and name.endswith('__'): + # Python internal stuff + raise AttributeError + if self._service_name is not None: + name = "%s.%s" % (self._service_name, name) + return AuthServiceProxy(self.__service_url, name, connection=self.__conn) + + def _request(self, method, path, postdata): + ''' + Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout). + This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5. + ''' + headers = {'Host': self.__url.hostname, + 'User-Agent': USER_AGENT, + 'Authorization': self.__auth_header, + 'Content-type': 'application/json'} + try: + self.__conn.request(method, path, postdata, headers) + return self._get_response() + except Exception as e: + # If connection was closed, try again. + # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. + # ConnectionResetError happens on FreeBSD with Python 3.4. + # This can be simplified now that we depend on Python 3 (previously, we could not + # refer to BrokenPipeError or ConnectionResetError which did not exist on Python 2) + if ((isinstance(e, BadStatusLine) and e.line == "''") + or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): + self.__conn.close() + self.__conn.request(method, path, postdata, headers) + return self._get_response() + else: + raise + + def __call__(self, *args): + AuthServiceProxy.__id_count += 1 + + log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name, + json.dumps(args, default=EncodeDecimal))) + postdata = json.dumps({'version': '1.1', + 'method': self._service_name, + 'params': args, + 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) + response = self._request('POST', self.__url.path, postdata) + if response['error'] is not None: + raise JSONRPCException(response['error']) + elif 'result' not in response: + raise JSONRPCException({ + 'code': -343, 'message': 'missing JSON-RPC result'}) + else: + return response['result'] + + def _batch(self, rpc_call_list): + postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal) + log.debug("--> "+postdata) + return self._request('POST', self.__url.path, postdata) + + def _get_response(self): + http_response = self.__conn.getresponse() + if http_response is None: + raise JSONRPCException({ + 'code': -342, 'message': 'missing HTTP response from server'}) + + content_type = http_response.getheader('Content-Type') + if content_type != 'application/json': + raise JSONRPCException({ + 'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)}) + + responsedata = http_response.read().decode('utf8') + response = json.loads(responsedata, parse_float=decimal.Decimal) + if "error" in response and response["error"] is None: + log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) + else: + log.debug("<-- "+responsedata) + return response diff --git a/zebra-rpc/qa/rpc-tests/test_framework/bignum.py b/zebra-rpc/qa/rpc-tests/test_framework/bignum.py new file mode 100644 index 00000000000..f56cea98e7a --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/bignum.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# +# bignum.py +# +# This file is copied from python-bitcoinlib. +# +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# + +"""Bignum routines""" + +import struct + + +# generic big endian MPI format + +def bn_bytes(v, have_ext=False): + ext = 0 + if have_ext: + ext = 1 + return ((v.bit_length()+7)//8) + ext + +def bn2bin(v): + s = bytearray() + i = bn_bytes(v) + while i > 0: + s.append((v >> ((i-1) * 8)) & 0xff) + i -= 1 + return s + +def bin2bn(s): + l = 0 + for ch in s: + l = (l << 8) | ch + return l + +def bn2mpi(v): + have_ext = False + if v.bit_length() > 0: + have_ext = (v.bit_length() & 0x07) == 0 + + neg = False + if v < 0: + neg = True + v = -v + + s = struct.pack(b">I", bn_bytes(v, have_ext)) + ext = bytearray() + if have_ext: + ext.append(0) + v_bin = bn2bin(v) + if neg: + if have_ext: + ext[0] |= 0x80 + else: + v_bin[0] |= 0x80 + return s + ext + v_bin + +def mpi2bn(s): + if len(s) < 4: + return None + s_size = bytes(s[:4]) + v_len = struct.unpack(b">I", s_size)[0] + if len(s) != (v_len + 4): + return None + if v_len == 0: + return 0 + + v_str = bytearray(s[4:]) + neg = False + i = v_str[0] + if i & 0x80: + neg = True + i &= ~0x80 + v_str[0] = i + + v = bin2bn(v_str) + + if neg: + return -v + return v + +# bitcoin-specific little endian format, with implicit size +def mpi2vch(s): + r = s[4:] # strip size + r = r[::-1] # reverse string, converting BE->LE + return r + +def bn2vch(v): + return bytes(mpi2vch(bn2mpi(v))) + +def vch2mpi(s): + r = struct.pack(b">I", len(s)) # size + r += s[::-1] # reverse string, converting LE->BE + return r + +def vch2bn(s): + return mpi2bn(vch2mpi(s)) + diff --git a/zebra-rpc/qa/rpc-tests/test_framework/blockstore.py b/zebra-rpc/qa/rpc-tests/test_framework/blockstore.py new file mode 100644 index 00000000000..e83ee5fab58 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/blockstore.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +# BlockStore: a helper class that keeps a map of blocks and implements +# helper functions for responding to getheaders and getdata, +# and for constructing a getheaders message +# + +from .mininode import CBlock, CBlockHeader, CBlockLocator, CTransaction, msg_block, msg_headers, msg_tx + +import sys +from io import BytesIO +import dbm.ndbm + +class BlockStore(): + def __init__(self, datadir): + self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') + self.currentBlock = 0 + self.headers_map = dict() + + def close(self): + self.blockDB.close() + + def get(self, blockhash): + serialized_block = None + try: + serialized_block = self.blockDB[repr(blockhash)] + except KeyError: + return None + f = BytesIO(serialized_block) + ret = CBlock() + ret.deserialize(f) + ret.calc_sha256() + return ret + + def get_header(self, blockhash): + try: + return self.headers_map[blockhash] + except KeyError: + return None + + # Note: this pulls full blocks out of the database just to retrieve + # the headers -- perhaps we could keep a separate data structure + # to avoid this overhead. + def headers_for(self, locator, hash_stop, current_tip=None): + if current_tip is None: + current_tip = self.currentBlock + current_block_header = self.get_header(current_tip) + if current_block_header is None: + return None + + response = msg_headers() + headersList = [ current_block_header ] + maxheaders = 2000 + while (headersList[0].sha256 not in locator.vHave): + prevBlockHash = headersList[0].hashPrevBlock + prevBlockHeader = self.get_header(prevBlockHash) + if prevBlockHeader is not None: + headersList.insert(0, prevBlockHeader) + else: + break + headersList = headersList[:maxheaders] # truncate if we have too many + hashList = [x.sha256 for x in headersList] + index = len(headersList) + if (hash_stop in hashList): + index = hashList.index(hash_stop)+1 + response.headers = headersList[:index] + return response + + def add_block(self, block): + block.calc_sha256() + try: + self.blockDB[repr(block.sha256)] = bytes(block.serialize()) + except TypeError as e: + print("Unexpected error: ", sys.exc_info()[0], e.args) + self.currentBlock = block.sha256 + self.headers_map[block.sha256] = CBlockHeader(block) + + def add_header(self, header): + self.headers_map[header.sha256] = header + + def get_blocks(self, inv): + responses = [] + for i in inv: + if (i.type == 2): # MSG_BLOCK + block = self.get(i.hash) + if block is not None: + responses.append(msg_block(block)) + return responses + + def get_locator(self, current_tip=None): + if current_tip is None: + current_tip = self.currentBlock + r = [] + counter = 0 + step = 1 + lastBlock = self.get(current_tip) + while lastBlock is not None: + r.append(lastBlock.hashPrevBlock) + for i in range(step): + lastBlock = self.get(lastBlock.hashPrevBlock) + if lastBlock is None: + break + counter += 1 + if counter > 10: + step *= 2 + locator = CBlockLocator() + locator.vHave = r + return locator + +class TxStore(object): + def __init__(self, datadir): + self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c') + + def close(self): + self.txDB.close() + + def get(self, txhash): + serialized_tx = None + try: + serialized_tx = self.txDB[repr(txhash)] + except KeyError: + return None + f = BytesIO(serialized_tx) + ret = CTransaction() + ret.deserialize(f) + ret.calc_sha256() + return ret + + def add_transaction(self, tx): + tx.calc_sha256() + try: + self.txDB[repr(tx.sha256)] = bytes(tx.serialize()) + except TypeError as e: + print("Unexpected error: ", sys.exc_info()[0], e.args) + + def get_transactions(self, inv): + responses = [] + for i in inv: + if (i.type == 1): # MSG_TX + tx = self.get(i.hash) + if tx is not None: + responses.append(msg_tx(tx)) + return responses diff --git a/zebra-rpc/qa/rpc-tests/test_framework/blocktools.py b/zebra-rpc/qa/rpc-tests/test_framework/blocktools.py new file mode 100644 index 00000000000..9c6fa430d2d --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/blocktools.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# blocktools.py - utilities for manipulating blocks and transactions +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2017-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from hashlib import blake2b + +from .mininode import ( + CBlock, CTransaction, CTxIn, CTxOut, COutPoint, + BLOSSOM_POW_TARGET_SPACING_RATIO, +) +from .script import CScript, OP_0, OP_EQUAL, OP_HASH160, OP_TRUE, OP_CHECKSIG + +# Create a block (with regtest difficulty) +def create_block(hashprev, coinbase, nTime=None, nBits=None, hashBlockCommitments=None): + block = CBlock() + if nTime is None: + import time + block.nTime = int(time.time()+600) + else: + block.nTime = nTime + block.hashPrevBlock = hashprev + if hashBlockCommitments is None: + # By default NUs up to Sapling are active from block 1, so we set this to the empty root. + hashBlockCommitments = 0x3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb + block.hashBlockCommitments = hashBlockCommitments + if nBits is None: + block.nBits = 0x200f0f0f # difficulty retargeting is disabled in REGTEST chainparams + else: + block.nBits = nBits + block.vtx.append(coinbase) + block.hashMerkleRoot = block.calc_merkle_root() + block.hashAuthDataRoot = block.calc_auth_data_root() + block.calc_sha256() + return block + +def derive_block_commitments_hash(chain_history_root, auth_data_root): + digest = blake2b( + digest_size=32, + person=b'ZcashBlockCommit') + digest.update(chain_history_root) + digest.update(auth_data_root) + digest.update(b'\x00' * 32) + return digest.digest() + +def serialize_script_num(value): + r = bytearray(0) + if value == 0: + return r + neg = value < 0 + absvalue = -value if neg else value + while (absvalue): + r.append(int(absvalue & 0xff)) + absvalue >>= 8 + if r[-1] & 0x80: + r.append(0x80 if neg else 0) + elif neg: + r[-1] |= 0x80 + return r + +# Create a coinbase transaction, assuming no miner fees. +# If pubkey is passed in, the coinbase output will be a P2PK output; +# otherwise an anyone-can-spend output. +def create_coinbase(height, pubkey=None, after_blossom=False, outputs=[], lockboxvalue=0): + coinbase = CTransaction() + coinbase.nExpiryHeight = height + coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), + CScript([height, OP_0]), 0xffffffff)) + coinbaseoutput = CTxOut() + coinbaseoutput.nValue = int(12.5*100000000) + if after_blossom: + coinbaseoutput.nValue //= BLOSSOM_POW_TARGET_SPACING_RATIO + halvings = height // 150 # regtest + coinbaseoutput.nValue >>= halvings + coinbaseoutput.nValue -= lockboxvalue + + if (pubkey != None): + coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG]) + else: + coinbaseoutput.scriptPubKey = CScript([OP_TRUE]) + coinbase.vout = [ coinbaseoutput ] + + if len(outputs) == 0 and halvings == 0: # regtest + froutput = CTxOut() + froutput.nValue = coinbaseoutput.nValue // 5 + # regtest + fraddr = bytearray([0x67, 0x08, 0xe6, 0x67, 0x0d, 0xb0, 0xb9, 0x50, + 0xda, 0xc6, 0x80, 0x31, 0x02, 0x5c, 0xc5, 0xb6, + 0x32, 0x13, 0xa4, 0x91]) + froutput.scriptPubKey = CScript([OP_HASH160, fraddr, OP_EQUAL]) + coinbaseoutput.nValue -= froutput.nValue + coinbase.vout.append(froutput) + + coinbaseoutput.nValue -= sum(output.nValue for output in outputs) + assert coinbaseoutput.nValue >= 0, coinbaseoutput.nValue + coinbase.vout.extend(outputs) + coinbase.calc_sha256() + return coinbase + +# Create a transaction with an anyone-can-spend output, that spends the +# nth output of prevtx. +def create_transaction(prevtx, n, sig, value): + tx = CTransaction() + assert(n < len(prevtx.vout)) + tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) + tx.vout.append(CTxOut(value, b"")) + tx.calc_sha256() + return tx diff --git a/zebra-rpc/qa/rpc-tests/test_framework/comptool.py b/zebra-rpc/qa/rpc-tests/test_framework/comptool.py new file mode 100755 index 00000000000..47e4efb3272 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/comptool.py @@ -0,0 +1,446 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2017-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from .blockstore import BlockStore, TxStore +from .mininode import ( + CBlock, + CBlockHeader, + CTransaction, + CInv, + msg_block, + msg_getheaders, + msg_headers, + msg_inv, + msg_mempool, + msg_ping, + mininode_lock, + MAX_INV_SZ, + NodeConn, + NodeConnCB, +) +from .util import p2p_port + +import time + +''' +This is a tool for comparing two or more bitcoinds to each other +using a script provided. + +To use, create a class that implements get_tests(), and pass it in +as the test generator to TestManager. get_tests() should be a python +generator that returns TestInstance objects. See below for definition. + +In practice get_tests is always implemented on a subclass of ComparisonTestFramework. +''' + +# TestNode behaves as follows: +# Configure with a BlockStore and TxStore +# on_inv: log the message but don't request +# on_headers: log the chain tip +# on_pong: update ping response map (for synchronization) +# on_getheaders: provide headers via BlockStore +# on_getdata: provide blocks via BlockStore + +def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): + attempt = 0 + elapsed = 0 + + while attempt < attempts and elapsed < timeout: + with mininode_lock: + if predicate(): + return True + attempt += 1 + elapsed += 0.05 + time.sleep(0.05) + + return False + +class RejectResult(object): + ''' + Outcome that expects rejection of a transaction or block. + ''' + def __init__(self, code, reason=b''): + self.code = code + self.reason = reason + def match(self, other): + if self.code != other.code: + return False + return other.reason.startswith(self.reason) + def __repr__(self): + return '%i:%s' % (self.code,self.reason or '*') + +class TestNode(NodeConnCB): + + def __init__(self, block_store, tx_store): + NodeConnCB.__init__(self) + self.create_callback_map() + self.conn = None + self.bestblockhash = None + self.block_store = block_store + self.block_request_map = {} + self.tx_store = tx_store + self.tx_request_map = {} + self.block_reject_map = {} + self.tx_reject_map = {} + + # When the pingmap is non-empty we're waiting for + # a response + self.pingMap = {} + self.lastInv = [] + self.closed = False + + def on_close(self, conn): + self.closed = True + + def add_connection(self, conn): + self.conn = conn + + def on_headers(self, conn, message): + if len(message.headers) > 0: + best_header = message.headers[-1] + best_header.calc_sha256() + self.bestblockhash = best_header.sha256 + + def on_getheaders(self, conn, message): + response = self.block_store.headers_for(message.locator, message.hashstop) + if response is not None: + conn.send_message(response) + + def on_getdata(self, conn, message): + [conn.send_message(r) for r in self.block_store.get_blocks(message.inv)] + [conn.send_message(r) for r in self.tx_store.get_transactions(message.inv)] + + for i in message.inv: + if i.type == 1: + self.tx_request_map[i.hash] = True + elif i.type == 2: + self.block_request_map[i.hash] = True + + def on_inv(self, conn, message): + self.lastInv = [x.hash for x in message.inv] + + def on_pong(self, conn, message): + try: + del self.pingMap[message.nonce] + except KeyError: + raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) + + def on_reject(self, conn, message): + if message.message == b'tx': + self.tx_reject_map[message.data] = RejectResult(message.code, message.reason) + if message.message == b'block': + self.block_reject_map[message.data] = RejectResult(message.code, message.reason) + + def send_inv(self, obj): + mtype = 2 if isinstance(obj, CBlock) else 1 + self.conn.send_message(msg_inv([CInv(mtype, obj.sha256)])) + + def send_getheaders(self): + # We ask for headers from their last tip. + m = msg_getheaders() + m.locator = self.block_store.get_locator(self.bestblockhash) + self.conn.send_message(m) + + def send_header(self, header): + m = msg_headers() + m.headers.append(header) + self.conn.send_message(m) + + # This assumes BIP31 + def send_ping(self, nonce): + self.pingMap[nonce] = True + self.conn.send_message(msg_ping(nonce)) + + def received_ping_response(self, nonce): + return nonce not in self.pingMap + + def send_mempool(self): + self.lastInv = [] + self.conn.send_message(msg_mempool()) + +# TestInstance: +# +# Instances of these are generated by the test generator, and fed into the +# comptool. +# +# "blocks_and_transactions" should be an array of +# [obj, True/False/None, hash/None]: +# - obj is either a CBlock, CBlockHeader, or a CTransaction, and +# - the second value indicates whether the object should be accepted +# into the blockchain or mempool (for tests where we expect a certain +# answer), or "None" if we don't expect a certain answer and are just +# comparing the behavior of the nodes being tested. +# - the third value is the hash to test the tip against (if None or omitted, +# use the hash of the block) +# - NOTE: if a block header, no test is performed; instead the header is +# just added to the block_store. This is to facilitate block delivery +# when communicating with headers-first clients (when withholding an +# intermediate block). +# sync_every_block: if True, then each block will be inv'ed, synced, and +# nodes will be tested based on the outcome for the block. If False, +# then inv's accumulate until all blocks are processed (or max inv size +# is reached) and then sent out in one inv message. Then the final block +# will be synced across all connections, and the outcome of the final +# block will be tested. +# sync_every_tx: analogous to behavior for sync_every_block, except if outcome +# on the final tx is None, then contents of entire mempool are compared +# across all connections. (If outcome of final tx is specified as true +# or false, then only the last tx is tested against outcome.) + +class TestInstance(object): + def __init__(self, objects=None, sync_every_block=True, sync_every_tx=False): + self.blocks_and_transactions = objects if objects else [] + self.sync_every_block = sync_every_block + self.sync_every_tx = sync_every_tx + +class TestManager(object): + + def __init__(self, testgen, datadir): + self.test_generator = testgen + self.connections = [] + self.test_nodes = [] + self.block_store = BlockStore(datadir) + self.tx_store = TxStore(datadir) + self.ping_counter = 1 + + def add_all_connections(self, nodes): + for i in range(len(nodes)): + # Create a p2p connection to each node + test_node = TestNode(self.block_store, self.tx_store) + self.test_nodes.append(test_node) + self.connections.append(NodeConn('127.0.0.1', p2p_port(i), nodes[i], test_node)) + # Make sure the TestNode (callback class) has a reference to its + # associated NodeConn + test_node.add_connection(self.connections[-1]) + + def wait_for_disconnections(self): + def disconnected(): + return all(node.closed for node in self.test_nodes) + return wait_until(disconnected, timeout=10) + + def wait_for_verack(self): + def veracked(): + return all(node.verack_received for node in self.test_nodes) + return wait_until(veracked, timeout=10) + + def wait_for_pings(self, counter): + def received_pongs(): + return all(node.received_ping_response(counter) for node in self.test_nodes) + return wait_until(received_pongs) + + # sync_blocks: Wait for all connections to request the blockhash given + # then send get_headers to find out the tip of each node, and synchronize + # the response by using a ping (and waiting for pong with same nonce). + def sync_blocks(self, blockhash, num_blocks): + def blocks_requested(): + return all( + blockhash in node.block_request_map and node.block_request_map[blockhash] + for node in self.test_nodes + ) + + # --> error if not requested + if not wait_until(blocks_requested, attempts=20*num_blocks): + # print [ c.cb.block_request_map for c in self.connections ] + raise AssertionError("Not all nodes requested block") + + # Send getheaders message + [ c.cb.send_getheaders() for c in self.connections ] + + # Send ping and wait for response -- synchronization hack + [ c.cb.send_ping(self.ping_counter) for c in self.connections ] + self.wait_for_pings(self.ping_counter) + self.ping_counter += 1 + + # Analogous to sync_block (see above) + def sync_transaction(self, txhash, num_events): + # Wait for nodes to request transaction (50ms sleep * 20 tries * num_events) + def transaction_requested(): + return all( + txhash in node.tx_request_map and node.tx_request_map[txhash] + for node in self.test_nodes + ) + + # --> error if not requested + if not wait_until(transaction_requested, attempts=20*num_events): + # print [ c.cb.tx_request_map for c in self.connections ] + raise AssertionError("Not all nodes requested transaction") + + # Get the mempool + [ c.cb.send_mempool() for c in self.connections ] + + # Send ping and wait for response -- synchronization hack + [ c.cb.send_ping(self.ping_counter) for c in self.connections ] + self.wait_for_pings(self.ping_counter) + self.ping_counter += 1 + + # Sort inv responses from each node + with mininode_lock: + [ c.cb.lastInv.sort() for c in self.connections ] + + # Verify that the tip of each connection all agree with each other, and + # with the expected outcome (if given) + def check_results(self, blockhash, outcome): + with mininode_lock: + for c in self.connections: + if outcome is None: + if c.cb.bestblockhash != self.connections[0].cb.bestblockhash: + return False + elif isinstance(outcome, RejectResult): # Check that block was rejected w/ code + if c.cb.bestblockhash == blockhash: + return False + if blockhash not in c.cb.block_reject_map: + print('Block not in reject map: %064x' % (blockhash)) + return False + if not outcome.match(c.cb.block_reject_map[blockhash]): + print('Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash)) + return False + elif ((c.cb.bestblockhash == blockhash) != outcome): + if outcome is True and blockhash in c.cb.block_reject_map: + print('Block rejected with %s instead of accepted: %064x' % (c.cb.block_reject_map[blockhash], blockhash)) + return False + return True + + # Either check that the mempools all agree with each other, or that + # txhash's presence in the mempool matches the outcome specified. + # This is somewhat of a strange comparison, in that we're either comparing + # a particular tx to an outcome, or the entire mempools altogether; + # perhaps it would be useful to add the ability to check explicitly that + # a particular tx's existence in the mempool is the same across all nodes. + def check_mempool(self, txhash, outcome): + with mininode_lock: + for c in self.connections: + if outcome is None: + # Make sure the mempools agree with each other + if c.cb.lastInv != self.connections[0].cb.lastInv: + # print c.rpc.getrawmempool() + return False + elif isinstance(outcome, RejectResult): # Check that tx was rejected w/ code + if txhash in c.cb.lastInv: + return False + if txhash not in c.cb.tx_reject_map: + print('Tx not in reject map: %064x' % (txhash)) + return False + if not outcome.match(c.cb.tx_reject_map[txhash]): + print('Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash)) + return False + elif ((txhash in c.cb.lastInv) != outcome): + # print c.rpc.getrawmempool(), c.cb.lastInv + return False + return True + + def run(self): + # Wait until verack is received + self.wait_for_verack() + + test_number = 1 + for test_instance in self.test_generator.get_tests(): + # We use these variables to keep track of the last block + # and last transaction in the tests, which are used + # if we're not syncing on every block or every tx. + [ block, block_outcome, tip ] = [ None, None, None ] + [ tx, tx_outcome ] = [ None, None ] + invqueue = [] + + for test_obj in test_instance.blocks_and_transactions: + b_or_t = test_obj[0] + outcome = test_obj[1] + # Determine if we're dealing with a block or tx + if isinstance(b_or_t, CBlock): # Block test runner + block = b_or_t + block_outcome = outcome + tip = block.sha256 + # each test_obj can have an optional third argument + # to specify the tip we should compare with + # (default is to use the block being tested) + if len(test_obj) >= 3: + tip = test_obj[2] + + # Add to shared block_store, set as current block + # If there was an open getdata request for the block + # previously, and we didn't have an entry in the + # block_store, then immediately deliver, because the + # node wouldn't send another getdata request while + # the earlier one is outstanding. + first_block_with_hash = True + if self.block_store.get(block.sha256) is not None: + first_block_with_hash = False + with mininode_lock: + self.block_store.add_block(block) + for c in self.connections: + if first_block_with_hash and block.sha256 in c.cb.block_request_map and c.cb.block_request_map[block.sha256] == True: + # There was a previous request for this block hash + # Most likely, we delivered a header for this block + # but never had the block to respond to the getdata + c.send_message(msg_block(block)) + else: + c.cb.block_request_map[block.sha256] = False + # Either send inv's to each node and sync, or add + # to invqueue for later inv'ing. + if (test_instance.sync_every_block): + # if we expect success, send inv and sync every block + # if we expect failure, just push the block and see what happens. + if outcome == True: + [ c.cb.send_inv(block) for c in self.connections ] + self.sync_blocks(block.sha256, 1) + else: + [ c.send_message(msg_block(block)) for c in self.connections ] + [ c.cb.send_ping(self.ping_counter) for c in self.connections ] + self.wait_for_pings(self.ping_counter) + self.ping_counter += 1 + if (not self.check_results(tip, outcome)): + raise AssertionError("Test failed at test %d" % test_number) + else: + invqueue.append(CInv(2, block.sha256)) + elif isinstance(b_or_t, CBlockHeader): + block_header = b_or_t + self.block_store.add_header(block_header) + [ c.cb.send_header(block_header) for c in self.connections ] + + else: # Tx test runner + assert(isinstance(b_or_t, CTransaction)) + tx = b_or_t + tx_outcome = outcome + # Add to shared tx store and clear map entry + with mininode_lock: + self.tx_store.add_transaction(tx) + for c in self.connections: + c.cb.tx_request_map[tx.sha256] = False + # Again, either inv to all nodes or save for later + if (test_instance.sync_every_tx): + [ c.cb.send_inv(tx) for c in self.connections ] + self.sync_transaction(tx.sha256, 1) + if (not self.check_mempool(tx.sha256, outcome)): + raise AssertionError("Test failed at test %d" % test_number) + else: + invqueue.append(CInv(1, tx.sha256)) + # Ensure we're not overflowing the inv queue + if len(invqueue) == MAX_INV_SZ: + [ c.send_message(msg_inv(invqueue)) for c in self.connections ] + invqueue = [] + + # Do final sync if we weren't syncing on every block or every tx. + if (not test_instance.sync_every_block and block is not None): + if len(invqueue) > 0: + [ c.send_message(msg_inv(invqueue)) for c in self.connections ] + invqueue = [] + self.sync_blocks(block.sha256, len(test_instance.blocks_and_transactions)) + if (not self.check_results(tip, block_outcome)): + raise AssertionError("Block test failed at test %d" % test_number) + if (not test_instance.sync_every_tx and tx is not None): + if len(invqueue) > 0: + [ c.send_message(msg_inv(invqueue)) for c in self.connections ] + invqueue = [] + self.sync_transaction(tx.sha256, len(test_instance.blocks_and_transactions)) + if (not self.check_mempool(tx.sha256, tx_outcome)): + raise AssertionError("Mempool test failed at test %d" % test_number) + + print("Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]) + test_number += 1 + + [ c.disconnect_node() for c in self.connections ] + self.wait_for_disconnections() + self.block_store.close() + self.tx_store.close() diff --git a/zebra-rpc/qa/rpc-tests/test_framework/coverage.py b/zebra-rpc/qa/rpc-tests/test_framework/coverage.py new file mode 100644 index 00000000000..02e1b7b4da6 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/coverage.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2020-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +""" +This module contains utilities for doing coverage analysis on the RPC +interface. + +It provides a way to track which RPC commands are exercised during +testing. + +""" +import os + + +REFERENCE_FILENAME = 'rpc_interface.txt' + + +class AuthServiceProxyWrapper(object): + """ + An object that wraps AuthServiceProxy to record specific RPC calls. + + """ + def __init__(self, auth_service_proxy_instance, coverage_logfile=None): + """ + Kwargs: + auth_service_proxy_instance (AuthServiceProxy): the instance + being wrapped. + coverage_logfile (str): if specified, write each service_name + out to a file when called. + + """ + self.auth_service_proxy_instance = auth_service_proxy_instance + self.coverage_logfile = coverage_logfile + + def __getattr__(self, *args, **kwargs): + return_val = self.auth_service_proxy_instance.__getattr__( + *args, **kwargs) + + return AuthServiceProxyWrapper(return_val, self.coverage_logfile) + + def __call__(self, *args, **kwargs): + """ + Delegates to AuthServiceProxy, then writes the particular RPC method + called to a file. + + """ + return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs) + rpc_method = self.auth_service_proxy_instance._service_name + + if self.coverage_logfile: + with open(self.coverage_logfile, 'a+', encoding='utf8') as f: + f.write("%s\n" % rpc_method) + + return return_val + + @property + def url(self): + return self.auth_service_proxy_instance.url + + +def get_filename(dirname, n_node): + """ + Get a filename unique to the test process ID and node. + + This file will contain a list of RPC commands covered. + """ + pid = str(os.getpid()) + return os.path.join( + dirname, "coverage.pid%s.node%s.txt" % (pid, str(n_node))) + + +def write_all_rpc_commands(dirname, node): + """ + Write out a list of all RPC functions available in `bitcoin-cli` for + coverage comparison. This will only happen once per coverage + directory. + + Args: + dirname (str): temporary test dir + node (AuthServiceProxy): client + + Returns: + bool. if the RPC interface file was written. + + """ + filename = os.path.join(dirname, REFERENCE_FILENAME) + + if os.path.isfile(filename): + return False + + help_output = node.help().split('\n') + commands = set() + + for line in help_output: + line = line.strip() + + # Ignore blanks and headers + if line and not line.startswith('='): + commands.add("%s\n" % line.split()[0]) + + with open(filename, 'w', encoding='utf8') as f: + f.writelines(list(commands)) + + return True diff --git a/zebra-rpc/qa/rpc-tests/test_framework/equihash.py b/zebra-rpc/qa/rpc-tests/test_framework/equihash.py new file mode 100755 index 00000000000..e05544fb4c1 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/equihash.py @@ -0,0 +1,294 @@ +from operator import itemgetter +import struct +from functools import reduce + +DEBUG = False +VERBOSE = False + + +word_size = 32 +word_mask = (1<= 8 and word_size >= 7+bit_len + bit_len_mask = (1<= bit_len: + acc_bits -= bit_len + for x in range(byte_pad, out_width): + out[j+x] = ( + # Big-endian + acc_value >> (acc_bits+(8*(out_width-x-1))) + ) & ( + # Apply bit_len_mask across byte boundaries + (bit_len_mask >> (8*(out_width-x-1))) & 0xFF + ) + j += out_width + + return out + +def compress_array(inp, out_len, bit_len, byte_pad=0): + assert bit_len >= 8 and word_size >= 7+bit_len + + in_width = (bit_len+7)//8 + byte_pad + assert out_len == bit_len*len(inp)//(8*in_width) + out = bytearray(out_len) + + bit_len_mask = (1 << bit_len) - 1 + + # The acc_bits least-significant bits of acc_value represent a bit sequence + # in big-endian order. + acc_bits = 0; + acc_value = 0; + + j = 0 + for i in range(out_len): + # When we have fewer than 8 bits left in the accumulator, read the next + # input element. + if acc_bits < 8: + acc_value = ((acc_value << bit_len) & word_mask) | inp[j] + for x in range(byte_pad, in_width): + acc_value = acc_value | ( + ( + # Apply bit_len_mask across byte boundaries + inp[j+x] & ((bit_len_mask >> (8*(in_width-x-1))) & 0xFF) + ) << (8*(in_width-x-1))); # Big-endian + j += in_width + acc_bits += bit_len + + acc_bits -= 8 + out[i] = (acc_value >> acc_bits) & 0xFF + + return out + +def get_indices_from_minimal(minimal, bit_len): + eh_index_size = 4 + assert (bit_len+7)//8 <= eh_index_size + len_indices = 8*eh_index_size*len(minimal)//bit_len + byte_pad = eh_index_size - (bit_len+7)//8 + expanded = expand_array(minimal, len_indices, bit_len, byte_pad) + return [struct.unpack('>I', expanded[i:i+4])[0] for i in range(0, len_indices, eh_index_size)] + +def get_minimal_from_indices(indices, bit_len): + eh_index_size = 4 + assert (bit_len+7)//8 <= eh_index_size + len_indices = len(indices)*eh_index_size + min_len = bit_len*len_indices//(8*eh_index_size) + byte_pad = eh_index_size - (bit_len+7)//8 + byte_indices = bytearray(b''.join([struct.pack('>I', i) for i in indices])) + return compress_array(byte_indices, min_len, bit_len, byte_pad) + + +def hash_nonce(digest, nonce): + for i in range(8): + digest.update(struct.pack('> (32*i))) + +def hash_xi(digest, xi): + digest.update(struct.pack(' 0: + # 2b) Find next set of unordered pairs with collisions on first n/(k+1) bits + j = 1 + while j < len(X): + if not has_collision(X[-1][0], X[-1-j][0], i, collision_length): + break + j += 1 + + # 2c) Store tuples (X_i ^ X_j, (i, j)) on the table + for l in range(0, j-1): + for m in range(l+1, j): + # Check that there are no duplicate indices in tuples i and j + if distinct_indices(X[-1-l][1], X[-1-m][1]): + if X[-1-l][1][0] < X[-1-m][1][0]: + concat = X[-1-l][1] + X[-1-m][1] + else: + concat = X[-1-m][1] + X[-1-l][1] + Xc.append((xor(X[-1-l][0], X[-1-m][0]), concat)) + + # 2d) Drop this set + while j > 0: + X.pop(-1) + j -= 1 + # 2e) Replace previous list with new list + X = Xc + + # k+1) Find a collision on last 2n(k+1) bits + if DEBUG: + print('Final round:') + print('- Sorting list') + X.sort(key=itemgetter(0)) + if DEBUG and VERBOSE: + for Xi in X[-32:]: + print('%s %s' % (print_hash(Xi[0]), Xi[1])) + if DEBUG: print('- Finding collisions') + solns = [] + while len(X) > 0: + j = 1 + while j < len(X): + if not (has_collision(X[-1][0], X[-1-j][0], k, collision_length) and + has_collision(X[-1][0], X[-1-j][0], k+1, collision_length)): + break + j += 1 + + for l in range(0, j-1): + for m in range(l+1, j): + res = xor(X[-1-l][0], X[-1-m][0]) + if count_zeroes(res) == 8*hash_length and distinct_indices(X[-1-l][1], X[-1-m][1]): + if DEBUG and VERBOSE: + print('Found solution:') + print('- %s %s' % (print_hash(X[-1-l][0]), X[-1-l][1])) + print('- %s %s' % (print_hash(X[-1-m][0]), X[-1-m][1])) + if X[-1-l][1][0] < X[-1-m][1][0]: + solns.append(list(X[-1-l][1] + X[-1-m][1])) + else: + solns.append(list(X[-1-m][1] + X[-1-l][1])) + + # 2d) Drop this set + while j > 0: + X.pop(-1) + j -= 1 + return [get_minimal_from_indices(soln, collision_length+1) for soln in solns] + +def gbp_validate(digest, minimal, n, k): + validate_params(n, k) + collision_length = n//(k+1) + hash_length = (k+1)*((collision_length+7)//8) + indices_per_hash_output = 512//n + solution_width = (1 << k)*(collision_length+1)//8 + + if len(minimal) != solution_width: + print('Invalid solution length: %d (expected %d)' % \ + (len(minimal), solution_width)) + return False + + X = [] + for i in get_indices_from_minimal(minimal, collision_length+1): + r = i % indices_per_hash_output + # X_i = H(I||V||x_i) + curr_digest = digest.copy() + hash_xi(curr_digest, i//indices_per_hash_output) + tmp_hash = curr_digest.digest() + X.append(( + expand_array(bytearray(tmp_hash[r*n//8:(r+1)*n//8]), + hash_length, collision_length), + (i,) + )) + + for r in range(1, k+1): + Xc = [] + for i in range(0, len(X), 2): + if not has_collision(X[i][0], X[i+1][0], r, collision_length): + print('Invalid solution: invalid collision length between StepRows') + return False + if X[i+1][1][0] < X[i][1][0]: + print('Invalid solution: Index tree incorrectly ordered') + return False + if not distinct_indices(X[i][1], X[i+1][1]): + print('Invalid solution: duplicate indices') + return False + Xc.append((xor(X[i][0], X[i+1][0]), X[i][1] + X[i+1][1])) + X = Xc + + if len(X) != 1: + print('Invalid solution: incorrect length after end of rounds: %d' % len(X)) + return False + + if count_zeroes(X[0][0]) != 8*hash_length: + print('Invalid solution: incorrect number of zeroes: %d' % count_zeroes(X[0][0])) + return False + + return True + +def zcash_person(n, k): + return b'ZcashPoW' + struct.pack('= n): + raise ValueError('n must be larger than k') + if (((n//(k+1))+1) >= 32): + raise ValueError('Parameters must satisfy n/(k+1)+1 < 32') diff --git a/zebra-rpc/qa/rpc-tests/test_framework/flyclient.py b/zebra-rpc/qa/rpc-tests/test_framework/flyclient.py new file mode 100644 index 00000000000..71221bdc9fa --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/flyclient.py @@ -0,0 +1,207 @@ +from hashlib import blake2b +import struct +from typing import (List, Optional) + +from .mininode import (CBlockHeader, block_work_from_compact, ser_compactsize, ser_uint256) +from .util import (NU5_BRANCH_ID, NU6_BRANCH_ID) + +def H(msg: bytes, consensusBranchId: int) -> bytes: + digest = blake2b( + digest_size=32, + person=b'ZcashHistory' + struct.pack(" 'ZcashMMRNode': + '''Create a leaf node from a block''' + if v2_data is not None: + assert consensusBranchId in [NU5_BRANCH_ID, NU6_BRANCH_ID] + orchard_root = v2_data[0] + orchard_tx_count = v2_data[1] + else: + orchard_root = None + orchard_tx_count = None + + node = Z() + node.left_child = None + node.right_child = None + node.hashSubtreeCommitment = ser_uint256(block.rehash()) + node.nEarliestTimestamp = block.nTime + node.nLatestTimestamp = block.nTime + node.nEarliestTargetBits = block.nBits + node.nLatestTargetBits = block.nBits + node.hashEarliestSaplingRoot = sapling_root + node.hashLatestSaplingRoot = sapling_root + node.nSubTreeTotalWork = block_work_from_compact(block.nBits) + node.nEarliestHeight = height + node.nLatestHeight = height + node.nSaplingTxCount = sapling_tx_count + node.hashEarliestOrchardRoot = orchard_root + node.hashLatestOrchardRoot = orchard_root + node.nOrchardTxCount = orchard_tx_count + node.consensusBranchId = consensusBranchId + return node + + def serialize(self) -> bytes: + '''serializes a node''' + buf = b'' + buf += self.hashSubtreeCommitment + buf += struct.pack(" ZcashMMRNode: + parent = ZcashMMRNode() + parent.left_child = left_child + parent.right_child = right_child + parent.hashSubtreeCommitment = H( + left_child.serialize() + right_child.serialize(), + left_child.consensusBranchId, + ) + parent.nEarliestTimestamp = left_child.nEarliestTimestamp + parent.nLatestTimestamp = right_child.nLatestTimestamp + parent.nEarliestTargetBits = left_child.nEarliestTargetBits + parent.nLatestTargetBits = right_child.nLatestTargetBits + parent.hashEarliestSaplingRoot = left_child.hashEarliestSaplingRoot + parent.hashLatestSaplingRoot = right_child.hashLatestSaplingRoot + parent.nSubTreeTotalWork = left_child.nSubTreeTotalWork + right_child.nSubTreeTotalWork + parent.nEarliestHeight = left_child.nEarliestHeight + parent.nLatestHeight = right_child.nLatestHeight + parent.nSaplingTxCount = left_child.nSaplingTxCount + right_child.nSaplingTxCount + parent.hashEarliestOrchardRoot = left_child.hashEarliestOrchardRoot + parent.hashLatestOrchardRoot = right_child.hashLatestOrchardRoot + parent.nOrchardTxCount = ( + left_child.nOrchardTxCount + right_child.nOrchardTxCount + if left_child.nOrchardTxCount is not None and right_child.nOrchardTxCount is not None + else None) + parent.consensusBranchId = left_child.consensusBranchId + return parent + +def make_root_commitment(root: ZcashMMRNode) -> bytes: + '''Makes the root commitment for a blockheader''' + return H(root.serialize(), root.consensusBranchId) + +def get_peaks(node: ZcashMMRNode) -> List[ZcashMMRNode]: + peaks: List[ZcashMMRNode] = [] + + # Get number of leaves. + leaves = node.nLatestHeight - (node.nEarliestHeight - 1) + assert(leaves > 0) + + # Check if the number of leaves in this subtree is a power of two. + if (leaves & (leaves - 1)) == 0: + # This subtree is full, and therefore a single peak. This also covers + # the case of a single isolated leaf. + peaks.append(node) + else: + # This is one of the generated nodes; search within its children. + peaks.extend(get_peaks(node.left_child)) + peaks.extend(get_peaks(node.right_child)) + + return peaks + + +def bag_peaks(peaks: List[ZcashMMRNode]) -> ZcashMMRNode: + ''' + "Bag" a list of peaks, and return the final root + ''' + root = peaks[0] + for i in range(1, len(peaks)): + root = make_parent(root, peaks[i]) + return root + + +def append(root: ZcashMMRNode, leaf: ZcashMMRNode) -> ZcashMMRNode: + '''Append a leaf to an existing tree, return the new tree root''' + # recursively find a list of peaks in the current tree + peaks: List[ZcashMMRNode] = get_peaks(root) + merged: List[ZcashMMRNode] = [] + + # Merge peaks from right to left. + # This will produce a list of peaks in reverse order + current = leaf + for peak in peaks[::-1]: + current_leaves = current.nLatestHeight - (current.nEarliestHeight - 1) + peak_leaves = peak.nLatestHeight - (peak.nEarliestHeight - 1) + + if current_leaves == peak_leaves: + current = make_parent(peak, current) + else: + merged.append(current) + current = peak + merged.append(current) + + # finally, bag the merged peaks + return bag_peaks(merged[::-1]) + +def delete(root: ZcashMMRNode) -> ZcashMMRNode: + ''' + Delete the rightmost leaf node from an existing MMR + Return the new tree root + ''' + + n_leaves = root.nLatestHeight - (root.nEarliestHeight - 1) + # if there were an odd number of leaves, + # simply replace root with left_child + if n_leaves & 1: + return root.left_child + + # otherwise, we need to re-bag the peaks. + else: + # first peak + peaks = [root.left_child] + + # we do this traversing the right (unbalanced) side of the tree + # we keep the left side (balanced subtree or leaf) of each subtree + # until we reach a leaf + subtree_root = root.right_child + while subtree_root.left_child: + peaks.append(subtree_root.left_child) + subtree_root = subtree_root.right_child + + new_root = bag_peaks(peaks) + return new_root diff --git a/zebra-rpc/qa/rpc-tests/test_framework/key.py b/zebra-rpc/qa/rpc-tests/test_framework/key.py new file mode 100644 index 00000000000..ba3038fe044 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/key.py @@ -0,0 +1,215 @@ +# Copyright (c) 2011 Sam Rushing +# +# key.py - OpenSSL wrapper +# +# This file is modified from python-bitcoinlib. +# + +"""ECC secp256k1 crypto routines + +WARNING: This module does not mlock() secrets; your private keys may end up on +disk in swap! Use with caution! +""" + +import ctypes +import ctypes.util +import hashlib +import sys + +ssl = ctypes.cdll.LoadLibrary(ctypes.util.find_library ('ssl') or 'libeay32') + +ssl.BN_new.restype = ctypes.c_void_p +ssl.BN_new.argtypes = [] + +ssl.BN_bin2bn.restype = ctypes.c_void_p +ssl.BN_bin2bn.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_void_p] + +ssl.BN_CTX_free.restype = None +ssl.BN_CTX_free.argtypes = [ctypes.c_void_p] + +ssl.BN_CTX_new.restype = ctypes.c_void_p +ssl.BN_CTX_new.argtypes = [] + +ssl.ECDH_compute_key.restype = ctypes.c_int +ssl.ECDH_compute_key.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p] + +ssl.ECDSA_sign.restype = ctypes.c_int +ssl.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] + +ssl.ECDSA_verify.restype = ctypes.c_int +ssl.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p] + +ssl.EC_KEY_free.restype = None +ssl.EC_KEY_free.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p +ssl.EC_KEY_new_by_curve_name.argtypes = [ctypes.c_int] + +ssl.EC_KEY_get0_group.restype = ctypes.c_void_p +ssl.EC_KEY_get0_group.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_get0_public_key.restype = ctypes.c_void_p +ssl.EC_KEY_get0_public_key.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_set_private_key.restype = ctypes.c_int +ssl.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.EC_KEY_set_conv_form.restype = None +ssl.EC_KEY_set_conv_form.argtypes = [ctypes.c_void_p, ctypes.c_int] + +ssl.EC_KEY_set_public_key.restype = ctypes.c_int +ssl.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.i2o_ECPublicKey.restype = ctypes.c_void_p +ssl.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.EC_POINT_new.restype = ctypes.c_void_p +ssl.EC_POINT_new.argtypes = [ctypes.c_void_p] + +ssl.EC_POINT_free.restype = None +ssl.EC_POINT_free.argtypes = [ctypes.c_void_p] + +ssl.EC_POINT_mul.restype = ctypes.c_int +ssl.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] + +# this specifies the curve used with ECDSA. +NID_secp256k1 = 714 # from openssl/obj_mac.h + +# Thx to Sam Devlin for the ctypes magic 64-bit fix. +def _check_result(val, func, args): + if val == 0: + raise ValueError + else: + return ctypes.c_void_p (val) + +ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p +ssl.EC_KEY_new_by_curve_name.errcheck = _check_result + +class CECKey(object): + """Wrapper around OpenSSL's EC_KEY""" + + POINT_CONVERSION_COMPRESSED = 2 + POINT_CONVERSION_UNCOMPRESSED = 4 + + def __init__(self): + self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) + + def __del__(self): + if ssl: + ssl.EC_KEY_free(self.k) + self.k = None + + def set_secretbytes(self, secret): + priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new()) + group = ssl.EC_KEY_get0_group(self.k) + pub_key = ssl.EC_POINT_new(group) + ctx = ssl.BN_CTX_new() + if not ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx): + raise ValueError("Could not derive public key from the supplied secret.") + ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) + ssl.EC_KEY_set_private_key(self.k, priv_key) + ssl.EC_KEY_set_public_key(self.k, pub_key) + ssl.EC_POINT_free(pub_key) + ssl.BN_CTX_free(ctx) + return self.k + + def set_privkey(self, key): + self.mb = ctypes.create_string_buffer(key) + return ssl.d2i_ECPrivateKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) + + def set_pubkey(self, key): + self.mb = ctypes.create_string_buffer(key) + return ssl.o2i_ECPublicKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) + + def get_privkey(self): + size = ssl.i2d_ECPrivateKey(self.k, 0) + mb_pri = ctypes.create_string_buffer(size) + ssl.i2d_ECPrivateKey(self.k, ctypes.byref(ctypes.pointer(mb_pri))) + return mb_pri.raw + + def get_pubkey(self): + size = ssl.i2o_ECPublicKey(self.k, 0) + mb = ctypes.create_string_buffer(size) + ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb))) + return mb.raw + + def get_raw_ecdh_key(self, other_pubkey): + ecdh_keybuffer = ctypes.create_string_buffer(32) + r = ssl.ECDH_compute_key(ctypes.pointer(ecdh_keybuffer), 32, + ssl.EC_KEY_get0_public_key(other_pubkey.k), + self.k, 0) + if r != 32: + raise Exception('CKey.get_ecdh_key(): ECDH_compute_key() failed') + return ecdh_keybuffer.raw + + def get_ecdh_key(self, other_pubkey, kdf=lambda k: hashlib.sha256(k).digest()): + # FIXME: be warned it's not clear what the kdf should be as a default + r = self.get_raw_ecdh_key(other_pubkey) + return kdf(r) + + def sign(self, hash): + # FIXME: need unit tests for below cases + if not isinstance(hash, bytes): + raise TypeError('Hash must be bytes instance; got %r' % hash.__class__) + if len(hash) != 32: + raise ValueError('Hash must be exactly 32 bytes long') + + sig_size0 = ctypes.c_uint32() + sig_size0.value = ssl.ECDSA_size(self.k) + mb_sig = ctypes.create_string_buffer(sig_size0.value) + result = ssl.ECDSA_sign(0, hash, len(hash), mb_sig, ctypes.byref(sig_size0), self.k) + assert 1 == result + return mb_sig.raw[:sig_size0.value] + + def verify(self, hash, sig): + """Verify a DER signature""" + return ssl.ECDSA_verify(0, hash, len(hash), sig, len(sig), self.k) == 1 + + def set_compressed(self, compressed): + if compressed: + form = self.POINT_CONVERSION_COMPRESSED + else: + form = self.POINT_CONVERSION_UNCOMPRESSED + ssl.EC_KEY_set_conv_form(self.k, form) + + +class CPubKey(bytes): + """An encapsulated public key + + Attributes: + + is_valid - Corresponds to CPubKey.IsValid() + is_fullyvalid - Corresponds to CPubKey.IsFullyValid() + is_compressed - Corresponds to CPubKey.IsCompressed() + """ + + def __new__(cls, buf, _cec_key=None): + self = super(CPubKey, cls).__new__(cls, buf) + if _cec_key is None: + _cec_key = CECKey() + self._cec_key = _cec_key + self.is_fullyvalid = _cec_key.set_pubkey(self) != 0 + return self + + @property + def is_valid(self): + return len(self) > 0 + + @property + def is_compressed(self): + return len(self) == 33 + + def verify(self, hash, sig): + return self._cec_key.verify(hash, sig) + + def __str__(self): + return repr(self) + + def __repr__(self): + # Always have represent as b'' so test cases don't have to + # change for py2/3 + if sys.version > '3': + return '%s(%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + else: + return '%s(b%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + diff --git a/zebra-rpc/qa/rpc-tests/test_framework/mininode.py b/zebra-rpc/qa/rpc-tests/test_framework/mininode.py new file mode 100755 index 00000000000..d56fb8bf79c --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/mininode.py @@ -0,0 +1,2131 @@ +#!/usr/bin/env python3 +# Copyright (c) 2010 ArtForz -- public domain half-a-node +# Copyright (c) 2012 Jeff Garzik +# Copyright (c) 2010-2016 The Bitcoin Core developers +# Copyright (c) 2017-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# mininode.py - Bitcoin P2P network half-a-node +# +# This python code was modified from ArtForz' public domain half-a-node, as +# found in the mini-node branch of https://github.com/jgarzik/pynode. +# +# NodeConn: an object which manages p2p connectivity to a bitcoin node +# NodeConnCB: a base class that describes the interface for receiving +# callbacks with network messages from a NodeConn +# CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....: +# data structures that should map to corresponding structures in +# bitcoin/primitives +# msg_block, msg_tx, msg_headers, etc.: +# data structures that represent network messages +# ser_*, deser_*: functions that handle serialization/deserialization + + +import struct +import socket +import asyncore +import time +import sys +import random +from binascii import hexlify +from io import BytesIO +from codecs import encode +import hashlib +from threading import RLock +from threading import Thread +import logging +import copy +from hashlib import blake2b + +from .equihash import ( + gbp_basic, + gbp_validate, + hash_nonce, + zcash_person, +) +from .util import bytes_to_hex_str + + +BIP0031_VERSION = 60000 +SPROUT_PROTO_VERSION = 170002 # past bip-31 for ping/pong +OVERWINTER_PROTO_VERSION = 170003 +SAPLING_PROTO_VERSION = 170006 +BLOSSOM_PROTO_VERSION = 170008 +NU5_PROTO_VERSION = 170050 +# NU6_PROTO_VERSION = 170110 + +MY_SUBVERSION = b"/python-mininode-tester:0.0.3/" + +SPROUT_VERSION_GROUP_ID = 0x00000000 +OVERWINTER_VERSION_GROUP_ID = 0x03C48270 +SAPLING_VERSION_GROUP_ID = 0x892F2085 +ZIP225_VERSION_GROUP_ID = 0x26A7270A +# No transaction format change in Blossom. + +MAX_INV_SZ = 50000 + +COIN = 100000000 # 1 zec in zatoshis + +BLOSSOM_POW_TARGET_SPACING_RATIO = 2 + +# The placeholder value used for the auth digest of pre-v5 transactions. +LEGACY_TX_AUTH_DIGEST = (1 << 256) - 1 + +# Keep our own socket map for asyncore, so that we can track disconnects +# ourselves (to workaround an issue with closing an asyncore socket when +# using select) +mininode_socket_map = dict() + +# One lock for synchronizing all data access between the networking thread (see +# NetworkThread below) and the thread running the test logic. For simplicity, +# NodeConn acquires this lock whenever delivering a message to a NodeConnCB, +# and whenever adding anything to the send buffer (in send_message()). This +# lock should be acquired in the thread running the test logic to synchronize +# access to any data shared with the NodeConnCB or NodeConn. +mininode_lock = RLock() + +# Serialization/deserialization tools +def sha256(s): + return hashlib.new('sha256', s).digest() + +def hash256(s): + return sha256(sha256(s)) + +def nuparams(branch_id, height): + return '-nuparams=%x:%d' % (branch_id, height) + +def fundingstream(idx, start_height, end_height, addrs): + return '-fundingstream=%d:%d:%d:%s' % (idx, start_height, end_height, ",".join(addrs)) + +def ser_compactsize(n): + if n < 253: + return struct.pack("B", n) + elif n < 0x10000: + return struct.pack(">= 32 + return rs + + +def uint256_from_str(s): + r = 0 + t = struct.unpack("> 24) & 0xFF + v = (c & 0xFFFFFF) << (8 * (nbytes - 3)) + return v + + +def block_work_from_compact(c): + target = uint256_from_compact(c) + return 2**256 // (target + 1) + + +def deser_vector(f, c): + nit = struct.unpack("H", f.read(2))[0] + + def serialize(self): + r = b"" + r += struct.pack("H", self.port) + return r + + def __repr__(self): + return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, + self.ip, self.port) + + +class CInv(object): + typemap = { + 0: b"Error", + 1: b"TX", + 2: b"Block", + 5: b"WTX", + } + + def __init__(self, t=0, h=0, h_aux=0): + self.type = t + self.hash = h + self.hash_aux = h_aux + if self.type == 1: + self.hash_aux = LEGACY_TX_AUTH_DIGEST + + def deserialize(self, f): + self.type = struct.unpack(" 0: + flags = struct.unpack("B", f.read(1))[0] + self.enableSpends = (flags & ORCHARD_FLAGS_ENABLE_SPENDS) != 0 + self.enableOutputs = (flags & ORCHARD_FLAGS_ENABLE_OUTPUTS) != 0 + self.valueBalance = struct.unpack(" 0: + r += struct.pack("B", self.flags()) + r += struct.pack(" 0 + if has_sapling: + self.valueBalance = struct.unpack(" 0: + self.anchor = deser_uint256(f) + for i in range(len(self.spends)): + self.spends[i].zkproof = Groth16Proof() + self.spends[i].zkproof.deserialize(f) + for i in range(len(self.spends)): + self.spends[i].spendAuthSig = RedJubjubSignature() + self.spends[i].spendAuthSig.deserialize(f) + for i in range(len(self.outputs)): + self.outputs[i].zkproof = Groth16Proof() + self.outputs[i].zkproof.deserialize(f) + if has_sapling: + self.bindingSig = RedJubjubSignature() + self.bindingSig.deserialize(f) + + def serialize(self): + r = b"" + r += ser_vector(self.spends) + r += ser_vector(self.outputs) + has_sapling = (len(self.spends) + len(self.outputs)) > 0 + if has_sapling: + r += struct.pack(" 0: + r += ser_uint256(self.anchor) + for spend in self.spends: + r += spend.zkproof.serialize() + for spend in self.spends: + r += spend.spendAuthSig.serialize() + for output in self.outputs: + r += output.zkproof.serialize() + if has_sapling: + r += self.bindingSig.serialize() + return r + + def __repr__(self): + return "SaplingBundle(spends=%r, outputs=%r, valueBalance=%i, bindingSig=%064x)" \ + % ( + self.spends, + self.outputs, + self.valueBalance, + self.bindingSig, + ) + + +G1_PREFIX_MASK = 0x02 +G2_PREFIX_MASK = 0x0a + +class ZCProof(object): + def __init__(self): + self.g_A = None + self.g_A_prime = None + self.g_B = None + self.g_B_prime = None + self.g_C = None + self.g_C_prime = None + self.g_K = None + self.g_H = None + + def deserialize(self, f): + def deser_g1(self, f): + leadingByte = struct.unpack("> 31) + self.nVersion = header & 0x7FFFFFFF + self.nVersionGroupId = (struct.unpack("= 2: + self.vJoinSplit = deser_vector(f, JSDescription) + if len(self.vJoinSplit) > 0: + self.joinSplitPubKey = deser_uint256(f) + self.joinSplitSig = f.read(64) + + if isSaplingV4 and not (len(self.shieldedSpends) == 0 and len(self.shieldedOutputs) == 0): + self.bindingSig = RedJubjubSignature() + self.bindingSig.deserialize(f) + + self.sha256 = None + self.hash = None + + def serialize(self): + header = (int(self.fOverwintered)<<31) | self.nVersion + isOverwinterV3 = (self.fOverwintered and + self.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID and + self.nVersion == 3) + isSaplingV4 = (self.fOverwintered and + self.nVersionGroupId == SAPLING_VERSION_GROUP_ID and + self.nVersion == 4) + isNu5V5 = (self.fOverwintered and + self.nVersionGroupId == ZIP225_VERSION_GROUP_ID and + self.nVersion == 5) + + if isNu5V5: + r = b"" + + # Common transaction fields + r += struct.pack("= 2: + r += ser_vector(self.vJoinSplit) + if len(self.vJoinSplit) > 0: + r += ser_uint256(self.joinSplitPubKey) + r += self.joinSplitSig + if isSaplingV4 and not (len(self.shieldedSpends) == 0 and len(self.shieldedOutputs) == 0): + r += self.bindingSig.serialize() + return r + + def rehash(self): + self.sha256 = None + self.calc_sha256() + + def calc_sha256(self): + if self.nVersion >= 5: + from . import zip244 + txid = zip244.txid_digest(self) + self.auth_digest = zip244.auth_digest(self) + else: + txid = hash256(self.serialize()) + self.auth_digest = b'\xFF'*32 + if self.sha256 is None: + self.sha256 = uint256_from_str(txid) + self.hash = encode(txid[::-1], 'hex_codec').decode('ascii') + self.auth_digest_hex = encode(self.auth_digest[::-1], 'hex_codec').decode('ascii') + + def is_valid(self): + self.calc_sha256() + for tout in self.vout: + if tout.nValue < 0 or tout.nValue > 21000000 * 100000000: + return False + return True + + def __repr__(self): + r = ("CTransaction(fOverwintered=%r nVersion=%i nVersionGroupId=0x%08x " + "vin=%r vout=%r nLockTime=%i nExpiryHeight=%i " + "valueBalance=%i shieldedSpends=%r shieldedOutputs=%r" + % (self.fOverwintered, self.nVersion, self.nVersionGroupId, + self.vin, self.vout, self.nLockTime, self.nExpiryHeight, + self.valueBalance, self.shieldedSpends, self.shieldedOutputs)) + if self.nVersion >= 2: + r += " vJoinSplit=%r" % (self.vJoinSplit,) + if len(self.vJoinSplit) > 0: + r += " joinSplitPubKey=%064x joinSplitSig=%s" \ + % (self.joinSplitPubKey, bytes_to_hex_str(self.joinSplitSig)) + if len(self.shieldedSpends) > 0 or len(self.shieldedOutputs) > 0: + r += " bindingSig=%r" % self.bindingSig + r += ")" + return r + + +class CBlockHeader(object): + def __init__(self, header=None): + if header is None: + self.set_null() + else: + self.nVersion = header.nVersion + self.hashPrevBlock = header.hashPrevBlock + self.hashMerkleRoot = header.hashMerkleRoot + self.hashBlockCommitments = header.hashBlockCommitments + self.nTime = header.nTime + self.nBits = header.nBits + self.nNonce = header.nNonce + self.nSolution = header.nSolution + self.sha256 = header.sha256 + self.hash = header.hash + self.calc_sha256() + + def set_null(self): + self.nVersion = 4 + self.hashPrevBlock = 0 + self.hashMerkleRoot = 0 + self.hashBlockCommitments = 0 + self.nTime = 0 + self.nBits = 0 + self.nNonce = 0 + self.nSolution = [] + self.sha256 = None + self.hash = None + + def deserialize(self, f): + self.nVersion = struct.unpack(" 1: + newhashes = [] + for i in range(0, len(hashes), 2): + i2 = min(i+1, len(hashes)-1) + newhashes.append(hash256(hashes[i] + hashes[i2])) + hashes = newhashes + return uint256_from_str(hashes[0]) + + def calc_auth_data_root(self): + hashes = [] + nleaves = 0 + for tx in self.vtx: + tx.calc_sha256() + hashes.append(tx.auth_digest) + nleaves += 1 + # Continue adding leaves (of zeros) until reaching a power of 2 + while nleaves & (nleaves-1) > 0: + hashes.append(b'\x00'*32) + nleaves += 1 + while len(hashes) > 1: + newhashes = [] + for i in range(0, len(hashes), 2): + digest = blake2b(digest_size=32, person=b'ZcashAuthDatHash') + digest.update(hashes[i]) + digest.update(hashes[i+1]) + newhashes.append(digest.digest()) + hashes = newhashes + return uint256_from_str(hashes[0]) + + def is_valid(self, n=48, k=5): + # H(I||... + digest = blake2b(digest_size=(512//n)*n//8, person=zcash_person(n, k)) + digest.update(super(CBlock, self).serialize()[:108]) + hash_nonce(digest, self.nNonce) + if not gbp_validate(self.nSolution, digest, n, k): + return False + self.calc_sha256() + target = uint256_from_compact(self.nBits) + if self.sha256 > target: + return False + for tx in self.vtx: + if not tx.is_valid(): + return False + if self.calc_merkle_root() != self.hashMerkleRoot: + return False + return True + + def solve(self, n=48, k=5): + target = uint256_from_compact(self.nBits) + # H(I||... + digest = blake2b(digest_size=(512//n)*n//8, person=zcash_person(n, k)) + digest.update(super(CBlock, self).serialize()[:108]) + self.nNonce = 0 + while True: + # H(I||V||... + curr_digest = digest.copy() + hash_nonce(curr_digest, self.nNonce) + # (x_1, x_2, ...) = A(I, V, n, k) + solns = gbp_basic(curr_digest, n, k) + for soln in solns: + assert(gbp_validate(curr_digest, soln, n, k)) + self.nSolution = soln + self.rehash() + if self.sha256 <= target: + return + self.nNonce += 1 + + def __repr__(self): + return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x hashBlockCommitments=%064x nTime=%s nBits=%08x nNonce=%064x nSolution=%r vtx=%r)" \ + % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, + self.hashBlockCommitments, time.ctime(self.nTime), self.nBits, + self.nNonce, self.nSolution, self.vtx) + + +class CUnsignedAlert(object): + def __init__(self): + self.nVersion = 1 + self.nRelayUntil = 0 + self.nExpiration = 0 + self.nID = 0 + self.nCancel = 0 + self.setCancel = [] + self.nMinVer = 0 + self.nMaxVer = 0 + self.setSubVer = [] + self.nPriority = 0 + self.strComment = b"" + self.strStatusBar = b"" + self.strReserved = b"" + + def deserialize(self, f): + self.nVersion = struct.unpack("= 106: + self.addrFrom = CAddress() + self.addrFrom.deserialize(f) + self.nNonce = struct.unpack("= 209: + self.nStartingHeight = struct.unpack(" +class msg_headers(object): + command = b"headers" + + def __init__(self): + self.headers = [] + + def deserialize(self, f): + # comment in bitcoind indicates these should be deserialized as blocks + blocks = deser_vector(f, CBlock) + for x in blocks: + self.headers.append(CBlockHeader(x)) + + def serialize(self): + blocks = [CBlock(x) for x in self.headers] + return ser_vector(blocks) + + def __repr__(self): + return "msg_headers(headers=%s)" % repr(self.headers) + + +class msg_reject(object): + command = b"reject" + REJECT_MALFORMED = 1 + + def __init__(self): + self.message = b"" + self.code = 0 + self.reason = b"" + self.data = 0 + + def deserialize(self, f): + self.message = deser_string(f) + self.code = struct.unpack("= 209: + conn.send_message(msg_verack()) + conn.ver_send = min(SPROUT_PROTO_VERSION, message.nVersion) + if message.nVersion < 209: + conn.ver_recv = conn.ver_send + + def on_verack(self, conn, message): + conn.ver_recv = conn.ver_send + self.verack_received = True + + def on_inv(self, conn, message): + want = msg_getdata() + for i in message.inv: + if i.type != 0: + want.inv.append(i) + if len(want.inv): + conn.send_message(want) + + def on_addr(self, conn, message): pass + def on_alert(self, conn, message): pass + def on_getdata(self, conn, message): pass + def on_notfound(self, conn, message): pass + def on_getblocks(self, conn, message): pass + def on_tx(self, conn, message): pass + def on_block(self, conn, message): pass + def on_getaddr(self, conn, message): pass + def on_headers(self, conn, message): pass + def on_getheaders(self, conn, message): pass + def on_ping(self, conn, message): + if conn.ver_send > BIP0031_VERSION: + conn.send_message(msg_pong(message.nonce)) + def on_reject(self, conn, message): pass + def on_close(self, conn): pass + def on_mempool(self, conn): pass + def on_pong(self, conn, message): pass + + +# The actual NodeConn class +# This class provides an interface for a p2p connection to a specified node +class NodeConn(asyncore.dispatcher): + messagemap = { + b"version": msg_version, + b"verack": msg_verack, + b"addr": msg_addr, + b"alert": msg_alert, + b"inv": msg_inv, + b"getdata": msg_getdata, + b"notfound": msg_notfound, + b"getblocks": msg_getblocks, + b"tx": msg_tx, + b"block": msg_block, + b"getaddr": msg_getaddr, + b"ping": msg_ping, + b"pong": msg_pong, + b"headers": msg_headers, + b"getheaders": msg_getheaders, + b"reject": msg_reject, + b"mempool": msg_mempool + } + MAGIC_BYTES = { + "mainnet": b"\x24\xe9\x27\x64", # mainnet + "testnet3": b"\xfa\x1a\xf9\xbf", # testnet3 + "regtest": b"\xaa\xe8\x3f\x5f" # regtest + } + + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", protocol_version=SAPLING_PROTO_VERSION): + asyncore.dispatcher.__init__(self, map=mininode_socket_map) + self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) + self.dstaddr = dstaddr + self.dstport = dstport + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + self.sendbuf = b"" + self.recvbuf = b"" + self.ver_send = 209 + self.ver_recv = 209 + self.last_sent = 0 + self.state = "connecting" + self.network = net + self.cb = callback + self.disconnect = False + + # stuff version msg into sendbuf + vt = msg_version(protocol_version) + vt.addrTo.ip = self.dstaddr + vt.addrTo.port = self.dstport + vt.addrFrom.ip = "0.0.0.0" + vt.addrFrom.port = 0 + self.send_message(vt, True) + print('MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ + + str(dstport) + ' using version ' + str(protocol_version)) + + try: + self.connect((dstaddr, dstport)) + except: + self.handle_close() + self.rpc = rpc + + def show_debug_msg(self, msg): + self.log.debug(msg) + + def handle_connect(self): + self.show_debug_msg("MiniNode: Connected & Listening: \n") + self.state = b"connected" + + def handle_close(self): + self.show_debug_msg("MiniNode: Closing Connection to %s:%d... " + % (self.dstaddr, self.dstport)) + self.state = b"closed" + self.recvbuf = b"" + self.sendbuf = b"" + try: + self.close() + except: + pass + self.cb.on_close(self) + + def handle_read(self): + try: + t = self.recv(8192) + if len(t) > 0: + self.recvbuf += t + self.got_data() + except: + pass + + def readable(self): + return True + + def writable(self): + with mininode_lock: + length = len(self.sendbuf) + return (length > 0) + + def handle_write(self): + with mininode_lock: + try: + sent = self.send(self.sendbuf) + except: + self.handle_close() + return + self.sendbuf = self.sendbuf[sent:] + + def got_data(self): + try: + while True: + if len(self.recvbuf) < 4: + return + if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]: + raise ValueError("got garbage %r" % (self.recvbuf,)) + if self.ver_recv < 209: + if len(self.recvbuf) < 4 + 12 + 4: + return + command = self.recvbuf[4:4+12].split(b"\x00", 1)[0] + msglen = struct.unpack("= 209: + th = sha256(data) + h = sha256(th) + tmsg += h[:4] + tmsg += data + with mininode_lock: + self.sendbuf += tmsg + self.last_sent = time.time() + + def got_message(self, message): + if message.command == b"version": + if message.nVersion <= BIP0031_VERSION: + self.messagemap[b'ping'] = msg_ping_prebip31 + if self.last_sent + 30 * 60 < time.time(): + self.send_message(self.messagemap[b'ping']()) + self.show_debug_msg("Recv %s" % repr(message)) + self.cb.deliver(self, message) + + def disconnect_node(self): + self.disconnect = True + + +class NetworkThread(Thread): + def run(self): + while mininode_socket_map: + # We check for whether to disconnect outside of the asyncore + # loop to workaround the behavior of asyncore when using + # select + disconnected = [] + for fd, obj in mininode_socket_map.items(): + if obj.disconnect: + disconnected.append(obj) + [ obj.handle_close() for obj in disconnected ] + asyncore.loop(0.1, use_poll=True, map=mininode_socket_map, count=1) + + +# An exception we can raise if we detect a potential disconnect +# (p2p or rpc) before the test is complete +class EarlyDisconnectError(Exception): + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) diff --git a/zebra-rpc/qa/rpc-tests/test_framework/netutil.py b/zebra-rpc/qa/rpc-tests/test_framework/netutil.py new file mode 100644 index 00000000000..98f099c5558 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/netutil.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2019-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Linux network utilities + +import sys +import socket +import struct +import array +import os +from binascii import unhexlify, hexlify + +# Roughly based on https://web.archive.org/web/20190424172231/http://voorloopnul.com:80/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal +STATE_ESTABLISHED = '01' +STATE_SYN_SENT = '02' +STATE_SYN_RECV = '03' +STATE_FIN_WAIT1 = '04' +STATE_FIN_WAIT2 = '05' +STATE_TIME_WAIT = '06' +STATE_CLOSE = '07' +STATE_CLOSE_WAIT = '08' +STATE_LAST_ACK = '09' +STATE_LISTEN = '0A' +STATE_CLOSING = '0B' + +def get_socket_inodes(pid): + ''' + Get list of socket inodes for process pid. + ''' + base = '/proc/%i/fd' % pid + inodes = [] + for item in os.listdir(base): + target = os.readlink(os.path.join(base, item)) + if target.startswith('socket:'): + inodes.append(int(target[8:-1])) + return inodes + +def _remove_empty(array): + return [x for x in array if x !=''] + +def _convert_ip_port(array): + host,port = array.split(':') + # convert host from mangled-per-four-bytes form as used by kernel + host = unhexlify(host) + host_out = '' + for x in range(0, len(host) // 4): + (val,) = struct.unpack('=I', host[x*4:(x+1)*4]) + host_out += '%08x' % val + + return host_out,int(port,16) + +def netstat(typ='tcp'): + ''' + Function to return a list with status of tcp connections at linux systems + To get pid of all network process running on system, you must run this script + as superuser + ''' + with open('/proc/net/'+typ,'r',encoding='utf8') as f: + content = f.readlines() + content.pop(0) + result = [] + for line in content: + line_array = _remove_empty(line.split(' ')) # Split lines and remove empty spaces. + tcp_id = line_array[0] + l_addr = _convert_ip_port(line_array[1]) + r_addr = _convert_ip_port(line_array[2]) + state = line_array[3] + inode = int(line_array[9]) # Need the inode to match with process pid. + nline = [tcp_id, l_addr, r_addr, state, inode] + result.append(nline) + return result + +def get_bind_addrs(pid): + ''' + Get bind addresses as (host,port) tuples for process pid. + ''' + inodes = get_socket_inodes(pid) + bind_addrs = [] + for conn in netstat('tcp') + netstat('tcp6'): + if conn[3] == STATE_LISTEN and conn[4] in inodes: + bind_addrs.append(conn[1]) + return bind_addrs + +# from: https://code.activestate.com/recipes/439093/ +def all_interfaces(): + ''' + Return all interfaces that are up + ''' + import fcntl + + is_64bits = sys.maxsize > 2**32 + struct_size = 40 if is_64bits else 32 + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + max_possible = 8 # initial value + while True: + bytes = max_possible * struct_size + names = array.array('B', b'\0' * bytes) + outbytes = struct.unpack('iL', fcntl.ioctl( + s.fileno(), + 0x8912, # SIOCGIFCONF + struct.pack('iL', bytes, names.buffer_info()[0]) + ))[0] + if outbytes == bytes: + max_possible *= 2 + else: + break + namestr = names.tobytes() + return [(namestr[i:i+16].split(b'\0', 1)[0], + socket.inet_ntoa(namestr[i+20:i+24])) + for i in range(0, outbytes, struct_size)] + +def addr_to_hex(addr): + ''' + Convert string IPv4 or IPv6 address to binary address as returned by + get_bind_addrs. + Very naive implementation that certainly doesn't work for all IPv6 variants. + ''' + if '.' in addr: # IPv4 + addr = [int(x) for x in addr.split('.')] + elif ':' in addr: # IPv6 + sub = [[], []] # prefix, suffix + x = 0 + addr = addr.split(':') + for i,comp in enumerate(addr): + if comp == '': + if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end + continue + x += 1 # :: skips to suffix + assert(x < 2) + else: # two bytes per component + val = int(comp, 16) + sub[x].append(val >> 8) + sub[x].append(val & 0xff) + nullbytes = 16 - len(sub[0]) - len(sub[1]) + assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0)) + addr = sub[0] + ([0] * nullbytes) + sub[1] + else: + raise ValueError('Could not parse address %s' % addr) + return hexlify(bytearray(addr)).decode('ascii') + +def test_ipv6_local(): + ''' + Check for (local) IPv6 support. + ''' + import socket + # By using SOCK_DGRAM this will not actually make a connection, but it will + # fail if there is no route to IPv6 localhost. + have_ipv6 = True + try: + s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + s.connect(('::1', 0)) + except socket.error: + have_ipv6 = False + return have_ipv6 diff --git a/zebra-rpc/qa/rpc-tests/test_framework/proxy.py b/zebra-rpc/qa/rpc-tests/test_framework/proxy.py new file mode 100644 index 00000000000..d41c92d3c51 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/proxy.py @@ -0,0 +1,157 @@ +""" + Copyright 2024 Zcash Foundation + + ServiceProxy is just AuthServiceProxy without the auth part. + + Previous copyright, from authproxy.py: + + Copyright 2011 Jeff Garzik + + AuthServiceProxy has the following improvements over python-jsonrpc's + ServiceProxy class: + + - HTTP connections persist for the life of the AuthServiceProxy object + (if server supports HTTP/1.1) + - sends protocol 'version', per JSON-RPC 1.1 + - sends proper, incrementing 'id' + - sends Basic HTTP authentication headers + - parses all JSON numbers that look like floats as Decimal + - uses standard Python json lib + + Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: + + Copyright (c) 2007 Jan-Klaas Kollhof + + This file is part of jsonrpc. + + jsonrpc is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this software; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" + +import decimal +import json +import logging +from http.client import HTTPConnection, HTTPSConnection, BadStatusLine +from urllib.parse import urlparse + +USER_AGENT = "ServiceProxy/0.1" + +HTTP_TIMEOUT = 600 + +log = logging.getLogger("BitcoinRPC") + +class JSONRPCException(Exception): + def __init__(self, rpc_error): + Exception.__init__(self, rpc_error.get("message")) + self.error = rpc_error + +def EncodeDecimal(o): + if isinstance(o, decimal.Decimal): + return str(o) + raise TypeError(repr(o) + " is not JSON serializable") + + +class ServiceProxy(): + __id_count = 0 + + def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): + self.__service_url = service_url + self._service_name = service_name + self.__url = urlparse(service_url) + + self.timeout = timeout + self._set_conn(connection) + + def _set_conn(self, connection=None): + port = 80 if self.__url.port is None else self.__url.port + if connection: + self.__conn = connection + self.timeout = connection.timeout + elif self.__url.scheme == 'https': + self.__conn = HTTPSConnection(self.__url.hostname, port, timeout=self.timeout) + else: + self.__conn = HTTPConnection(self.__url.hostname, port, timeout=self.timeout) + + def __getattr__(self, name): + if name.startswith('__') and name.endswith('__'): + # Python internal stuff + raise AttributeError + if self._service_name is not None: + name = "%s.%s" % (self._service_name, name) + return ServiceProxy(self.__service_url, name, connection=self.__conn) + + def _request(self, method, path, postdata): + ''' + Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout). + This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5. + ''' + headers = {'Host': self.__url.hostname, + 'User-Agent': USER_AGENT, + 'Content-type': 'application/json'} + try: + self.__conn.request(method, path, postdata, headers) + return self._get_response() + except Exception as e: + # If connection was closed, try again. + # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. + # ConnectionResetError happens on FreeBSD with Python 3.4. + # This can be simplified now that we depend on Python 3 (previously, we could not + # refer to BrokenPipeError or ConnectionResetError which did not exist on Python 2) + if ((isinstance(e, BadStatusLine) and e.line == "''") + or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): + self.__conn.close() + self.__conn.request(method, path, postdata, headers) + return self._get_response() + else: + raise + + def __call__(self, *args): + ServiceProxy.__id_count += 1 + + log.debug("-%s-> %s %s"%(ServiceProxy.__id_count, self._service_name, + json.dumps(args, default=EncodeDecimal))) + postdata = json.dumps({'jsonrpc': '1.0', + 'method': self._service_name, + 'params': args, + 'id': ServiceProxy.__id_count}, default=EncodeDecimal) + response = self._request('POST', self.__url.path, postdata) + if 'result' not in response: + raise JSONRPCException({ + 'code': -343, 'message': 'missing JSON-RPC result'}) + else: + return response['result'] + + def _batch(self, rpc_call_list): + postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal) + log.debug("--> "+postdata) + return self._request('POST', self.__url.path, postdata) + + def _get_response(self): + http_response = self.__conn.getresponse() + if http_response is None: + raise JSONRPCException({ + 'code': -342, 'message': 'missing HTTP response from server'}) + + content_type = http_response.getheader('Content-Type') + if content_type != 'application/json; charset=utf-8': + raise JSONRPCException({ + 'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)}) + + responsedata = http_response.read().decode('utf8') + response = json.loads(responsedata, parse_float=decimal.Decimal) + if "error" in response and response["error"] is None: + log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) + else: + log.debug("<-- "+responsedata) + return response diff --git a/zebra-rpc/qa/rpc-tests/test_framework/script.py b/zebra-rpc/qa/rpc-tests/test_framework/script.py new file mode 100644 index 00000000000..c39d249b0f5 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/script.py @@ -0,0 +1,979 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2017-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# script.py +# +# This file is modified from python-bitcoinlib. +# + +"""Scripts + +Functionality to build scripts, as well as SignatureHash(). +""" + +import sys +bchr = chr +bord = ord +if sys.version > '3': + long = int + bchr = lambda x: bytes([x]) + bord = lambda x: x + +from hashlib import blake2b + +from binascii import hexlify +import struct + +from test_framework.bignum import bn2vch +from test_framework.mininode import (CTransaction, CTxOut, hash256, ser_string, ser_uint256) + +MAX_SCRIPT_SIZE = 10000 +MAX_SCRIPT_ELEMENT_SIZE = 520 +MAX_SCRIPT_OPCODES = 201 + +OPCODE_NAMES = {} + +_opcode_instances = [] +class CScriptOp(int): + """A single script opcode""" + __slots__ = [] + + @staticmethod + def encode_op_pushdata(d): + """Encode a PUSHDATA op, returning bytes""" + if len(d) < 0x4c: + return b'' + struct.pack('B', len(d)) + d # OP_PUSHDATA + elif len(d) <= 0xff: + return b'\x4c' + struct.pack('B', len(d)) + d # OP_PUSHDATA1 + elif len(d) <= 0xffff: + return b'\x4d' + struct.pack(b'>= 8 + if r[-1] & 0x80: + r.append(0x80 if neg else 0) + elif neg: + r[-1] |= 0x80 + return struct.pack("B", len(r)) + r + + +class CScript(bytes): + """Serialized script + + A bytes subclass, so you can use this directly whenever bytes are accepted. + Note that this means that indexing does *not* work - you'll get an index by + byte rather than opcode. This format was chosen for efficiency so that the + general case would not require creating a lot of little CScriptOP objects. + + iter(script) however does iterate by opcode. + """ + @classmethod + def __coerce_instance(cls, other): + # Coerce other into bytes + if isinstance(other, CScriptOp): + other = bytes([other]) + elif isinstance(other, CScriptNum): + if (other.value == 0): + other = bytes([CScriptOp(OP_0)]) + else: + other = CScriptNum.encode(other) + elif isinstance(other, int): + if 0 <= other <= 16: + other = bytes([CScriptOp.encode_op_n(other)]) + elif other == -1: + other = bytes([OP_1NEGATE]) + else: + other = CScriptOp.encode_op_pushdata(bn2vch(other)) + elif isinstance(other, (bytes, bytearray)): + other = bytes(CScriptOp.encode_op_pushdata(other)) + return other + + def __add__(self, other): + # Do the coercion outside of the try block so that errors in it are + # noticed. + other = self.__coerce_instance(other) + + try: + # bytes.__add__ always returns bytes instances unfortunately + return CScript(super(CScript, self).__add__(other)) + except TypeError: + raise TypeError('Can not add a %r instance to a CScript' % other.__class__) + + def join(self, iterable): + # join makes no sense for a CScript() + raise NotImplementedError + + def __new__(cls, value=b''): + if isinstance(value, bytes) or isinstance(value, bytearray): + return super(CScript, cls).__new__(cls, value) + else: + def coerce_iterable(iterable): + for instance in iterable: + yield cls.__coerce_instance(instance) + # Annoyingly on both python2 and python3 bytes.join() always + # returns a bytes instance even when subclassed. + return super(CScript, cls).__new__(cls, b''.join(coerce_iterable(value))) + + def raw_iter(self): + """Raw iteration + + Yields tuples of (opcode, data, sop_idx) so that the different possible + PUSHDATA encodings can be accurately distinguished, as well as + determining the exact opcode byte indexes. (sop_idx) + """ + i = 0 + while i < len(self): + sop_idx = i + opcode = bord(self[i]) + i += 1 + + if opcode > OP_PUSHDATA4: + yield (opcode, None, sop_idx) + else: + datasize = None + pushdata_type = None + if opcode < OP_PUSHDATA1: + pushdata_type = 'PUSHDATA(%d)' % opcode + datasize = opcode + + elif opcode == OP_PUSHDATA1: + pushdata_type = 'PUSHDATA1' + if i >= len(self): + raise CScriptInvalidError('PUSHDATA1: missing data length') + datasize = bord(self[i]) + i += 1 + + elif opcode == OP_PUSHDATA2: + pushdata_type = 'PUSHDATA2' + if i + 1 >= len(self): + raise CScriptInvalidError('PUSHDATA2: missing data length') + datasize = bord(self[i]) + (bord(self[i+1]) << 8) + i += 2 + + elif opcode == OP_PUSHDATA4: + pushdata_type = 'PUSHDATA4' + if i + 3 >= len(self): + raise CScriptInvalidError('PUSHDATA4: missing data length') + datasize = bord(self[i]) + (bord(self[i+1]) << 8) + (bord(self[i+2]) << 16) + (bord(self[i+3]) << 24) + i += 4 + + else: + assert False # shouldn't happen + + + data = bytes(self[i:i+datasize]) + + # Check for truncation + if len(data) < datasize: + raise CScriptTruncatedPushDataError('%s: truncated data' % pushdata_type, data) + + i += datasize + + yield (opcode, data, sop_idx) + + def __iter__(self): + """'Cooked' iteration + + Returns either a CScriptOP instance, an integer, or bytes, as + appropriate. + + See raw_iter() if you need to distinguish the different possible + PUSHDATA encodings. + """ + for (opcode, data, sop_idx) in self.raw_iter(): + if data is not None: + yield data + else: + opcode = CScriptOp(opcode) + + if opcode.is_small_int(): + yield opcode.decode_op_n() + else: + yield CScriptOp(opcode) + + def __repr__(self): + # For Python3 compatibility add b before strings so testcases don't + # need to change + def _repr(o): + if isinstance(o, bytes): + return b"x('%s')" % hexlify(o).decode('ascii') + else: + return repr(o) + + ops = [] + i = iter(self) + while True: + op = None + try: + op = _repr(next(i)) + except CScriptTruncatedPushDataError as err: + op = '%s...' % (_repr(err.data), err) + break + except CScriptInvalidError as err: + op = '' % err + break + except StopIteration: + break + finally: + if op is not None: + ops.append(op) + + return "CScript([%s])" % ', '.join(ops) + + def GetSigOpCount(self, fAccurate): + """Get the SigOp count. + + fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details. + + Note that this is consensus-critical. + """ + n = 0 + lastOpcode = OP_INVALIDOPCODE + for (opcode, data, sop_idx) in self.raw_iter(): + if opcode in (OP_CHECKSIG, OP_CHECKSIGVERIFY): + n += 1 + elif opcode in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY): + if fAccurate and (OP_1 <= lastOpcode <= OP_16): + n += opcode.decode_op_n() + else: + n += 20 + lastOpcode = opcode + return n + + +SIGHASH_ALL = 1 +SIGHASH_NONE = 2 +SIGHASH_SINGLE = 3 +SIGHASH_ANYONECANPAY = 0x80 + +def getHashPrevouts(tx, person=b'ZcashPrevoutHash'): + digest = blake2b(digest_size=32, person=person) + for x in tx.vin: + digest.update(x.prevout.serialize()) + return digest.digest() + +def getHashSequence(tx, person=b'ZcashSequencHash'): + digest = blake2b(digest_size=32, person=person) + for x in tx.vin: + digest.update(struct.pack('= len(txTo.vin): + raise ValueError("inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) + + if consensusBranchId != 0: + # ZIP 243 + hashPrevouts = b'\x00'*32 + hashSequence = b'\x00'*32 + hashOutputs = b'\x00'*32 + hashJoinSplits = b'\x00'*32 + hashShieldedSpends = b'\x00'*32 + hashShieldedOutputs = b'\x00'*32 + + if not (hashtype & SIGHASH_ANYONECANPAY): + hashPrevouts = getHashPrevouts(txTo) + + if (not (hashtype & SIGHASH_ANYONECANPAY)) and \ + (hashtype & 0x1f) != SIGHASH_SINGLE and \ + (hashtype & 0x1f) != SIGHASH_NONE: + hashSequence = getHashSequence(txTo) + + if (hashtype & 0x1f) != SIGHASH_SINGLE and \ + (hashtype & 0x1f) != SIGHASH_NONE: + hashOutputs = getHashOutputs(txTo) + elif (hashtype & 0x1f) == SIGHASH_SINGLE and \ + 0 <= inIdx and inIdx < len(txTo.vout): + digest = blake2b(digest_size=32, person=b'ZcashOutputsHash') + digest.update(txTo.vout[inIdx].serialize()) + hashOutputs = digest.digest() + + if len(txTo.vJoinSplit) > 0: + hashJoinSplits = getHashJoinSplits(txTo) + + if len(txTo.shieldedSpends) > 0: + hashShieldedSpends = getHashShieldedSpends(txTo) + + if len(txTo.shieldedOutputs) > 0: + hashShieldedOutputs = getHashShieldedOutputs(txTo) + + digest = blake2b( + digest_size=32, + person=b'ZcashSigHash' + struct.pack('= len(txtmp.vout): + raise ValueError("outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) + + tmp = txtmp.vout[outIdx] + txtmp.vout = [] + for i in range(outIdx): + txtmp.vout.append(CTxOut()) + txtmp.vout.append(tmp) + + for i in range(len(txtmp.vin)): + if i != inIdx: + txtmp.vin[i].nSequence = 0 + + if hashtype & SIGHASH_ANYONECANPAY: + tmp = txtmp.vin[inIdx] + txtmp.vin = [] + txtmp.vin.append(tmp) + + s = txtmp.serialize() + s += struct.pack(b" 0: + d = s.recv(n) + if not d: + raise IOError('Unexpected end of stream') + rv.extend(d) + n -= len(d) + return rv + +### Implementation classes +class Socks5Configuration(object): + '''Proxy configuration''' + def __init__(self): + self.addr = None # Bind address (must be set) + self.af = socket.AF_INET # Bind address family + self.unauth = False # Support unauthenticated + self.auth = False # Support authentication + +class Socks5Command(object): + '''Information about an incoming socks5 command''' + def __init__(self, cmd, atyp, addr, port, username, password): + self.cmd = cmd # Command (one of Command.*) + self.atyp = atyp # Address type (one of AddressType.*) + self.addr = addr # Address + self.port = port # Port to connect to + self.username = username + self.password = password + def __repr__(self): + return 'Socks5Command(%s,%s,%s,%s,%s,%s)' % (self.cmd, self.atyp, self.addr, self.port, self.username, self.password) + +class Socks5Connection(object): + def __init__(self, serv, conn, peer): + self.serv = serv + self.conn = conn + self.peer = peer + + def handle(self): + ''' + Handle socks5 request according to RFC1928 + ''' + try: + # Verify socks version + ver = recvall(self.conn, 1)[0] + if ver != 0x05: + raise IOError('Invalid socks version %i' % ver) + # Choose authentication method + nmethods = recvall(self.conn, 1)[0] + methods = bytearray(recvall(self.conn, nmethods)) + method = None + if 0x02 in methods and self.serv.conf.auth: + method = 0x02 # username/password + elif 0x00 in methods and self.serv.conf.unauth: + method = 0x00 # unauthenticated + if method is None: + raise IOError('No supported authentication method was offered') + # Send response + self.conn.sendall(bytearray([0x05, method])) + # Read authentication (optional) + username = None + password = None + if method == 0x02: + ver = recvall(self.conn, 1)[0] + if ver != 0x01: + raise IOError('Invalid auth packet version %i' % ver) + ulen = recvall(self.conn, 1)[0] + username = str(recvall(self.conn, ulen)) + plen = recvall(self.conn, 1)[0] + password = str(recvall(self.conn, plen)) + # Send authentication response + self.conn.sendall(bytearray([0x01, 0x00])) + + # Read connect request + (ver,cmd,rsv,atyp) = recvall(self.conn, 4) + if ver != 0x05: + raise IOError('Invalid socks version %i in connect request' % ver) + if cmd != Command.CONNECT: + raise IOError('Unhandled command %i in connect request' % cmd) + + if atyp == AddressType.IPV4: + addr = recvall(self.conn, 4) + elif atyp == AddressType.DOMAINNAME: + n = recvall(self.conn, 1)[0] + addr = recvall(self.conn, n) + elif atyp == AddressType.IPV6: + addr = recvall(self.conn, 16) + else: + raise IOError('Unknown address type %i' % atyp) + port_hi,port_lo = recvall(self.conn, 2) + port = (port_hi << 8) | port_lo + + # Send dummy response + self.conn.sendall(bytearray([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) + + cmdin = Socks5Command(cmd, atyp, addr, port, username, password) + self.serv.queue.put(cmdin) + print('Proxy: ', cmdin) + # Fall through to disconnect + except Exception as e: + traceback.print_exc(file=sys.stderr) + self.serv.queue.put(e) + finally: + self.conn.close() + +class Socks5Server(object): + def __init__(self, conf): + self.conf = conf + self.s = socket.socket(conf.af) + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.s.bind(conf.addr) + self.s.listen(5) + self.running = False + self.thread = None + self.queue = queue.Queue() # report connections and exceptions to client + + def run(self): + while self.running: + (sockconn, peer) = self.s.accept() + if self.running: + conn = Socks5Connection(self, sockconn, peer) + thread = threading.Thread(None, conn.handle) + thread.daemon = True + thread.start() + + def start(self): + assert(not self.running) + self.running = True + self.thread = threading.Thread(None, self.run) + self.thread.daemon = True + self.thread.start() + + def stop(self): + self.running = False + # connect to self to end run loop + s = socket.socket(self.conf.af) + s.connect(self.conf.addr) + s.close() + self.thread.join() + diff --git a/zebra-rpc/qa/rpc-tests/test_framework/test_framework.py b/zebra-rpc/qa/rpc-tests/test_framework/test_framework.py new file mode 100755 index 00000000000..a4290647654 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/test_framework.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2016-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Base class for RPC testing + +import logging +import optparse +import os +import sys +import shutil +import tempfile +import traceback + +from .proxy import JSONRPCException +from .util import ( + zcashd_binary, + initialize_chain, + start_nodes, + connect_nodes_bi, + sync_blocks, + sync_mempools, + stop_nodes, + wait_bitcoinds, + enable_coverage, + check_json_precision, + PortSeed, +) + + +class BitcoinTestFramework(object): + + def __init__(self): + self.num_nodes = 4 + self.cache_behavior = 'current' + self.nodes = None + + def run_test(self): + raise NotImplementedError + + def add_options(self, parser): + pass + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir, self.cache_behavior) + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir) + + def setup_network(self, split = False, do_mempool_sync = True): + self.nodes = self.setup_nodes() + + # Connect the nodes as a "chain". This allows us + # to split the network between nodes 1 and 2 to get + # two halves that can work on competing chains. + connect_nodes_bi(self.nodes, 0, 1) + + # If we joined network halves, connect the nodes from the joint + # on outward. This ensures that chains are properly reorganised. + if len(self.nodes) >= 4: + connect_nodes_bi(self.nodes, 2, 3) + if not split: + connect_nodes_bi(self.nodes, 1, 2) + sync_blocks(self.nodes[1:3]) + if do_mempool_sync: + sync_mempools(self.nodes[1:3]) + + self.is_network_split = split + self.sync_all(do_mempool_sync) + + def split_network(self): + """ + Split the network of four nodes into nodes 0/1 and 2/3. + """ + assert not self.is_network_split + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network(True) + + def sync_all(self, do_mempool_sync = True): + if self.is_network_split: + sync_blocks(self.nodes[:2]) + sync_blocks(self.nodes[2:]) + if do_mempool_sync: + sync_mempools(self.nodes[:2]) + sync_mempools(self.nodes[2:]) + else: + sync_blocks(self.nodes) + if do_mempool_sync: + sync_mempools(self.nodes) + + def join_network(self): + """ + Join the (previously split) network halves together. + """ + assert self.is_network_split + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network(False, False) + + def main(self): + + parser = optparse.OptionParser(usage="%prog [options]") + parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", + help="Leave bitcoinds and test.* datadir on exit or error") + parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true", + help="Don't stop bitcoinds after the test execution") + parser.add_option("--srcdir", dest="srcdir", default="../../src", + help="Source directory containing bitcoind/bitcoin-cli (default: %default)") + parser.add_option("--cachedir", dest="cachedir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__))+"/../../cache"), + help="Directory for caching pregenerated datadirs") + parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), + help="Root directory for datadirs") + parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true", + help="Print out all RPC calls as they are made") + parser.add_option("--portseed", dest="port_seed", default=os.getpid(), type='int', + help="The seed to use for assigning port numbers (default: current process id)") + parser.add_option("--coveragedir", dest="coveragedir", + help="Write tested RPC commands into this directory") + self.add_options(parser) + (self.options, self.args) = parser.parse_args() + + self.options.tmpdir += '/' + str(self.options.port_seed) + + if self.options.trace_rpc: + logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) + + if self.options.coveragedir: + enable_coverage(self.options.coveragedir) + + PortSeed.n = self.options.port_seed + + os.environ['PATH'] = self.options.srcdir+":"+os.environ['PATH'] + + check_json_precision() + + success = False + try: + os.makedirs(self.options.tmpdir, exist_ok=False) + self.setup_chain() + self.setup_network() + self.run_test() + success = True + except JSONRPCException as e: + print("JSONRPC error: "+e.error['message']) + traceback.print_tb(sys.exc_info()[2]) + except AssertionError as e: + print("Assertion failed: " + str(e)) + traceback.print_tb(sys.exc_info()[2]) + except KeyError as e: + print("key not found: "+ str(e)) + traceback.print_tb(sys.exc_info()[2]) + except Exception as e: + print("Unexpected exception caught during testing: "+str(e)) + traceback.print_tb(sys.exc_info()[2]) + except KeyboardInterrupt as e: + print("Exiting after " + repr(e)) + + if not self.options.noshutdown: + print("Stopping nodes") + stop_nodes(self.nodes) + wait_bitcoinds() + else: + print("Note: bitcoinds were not stopped and may still be running") + + if not self.options.nocleanup and not self.options.noshutdown: + print("Cleaning up") + shutil.rmtree(self.options.tmpdir) + + if success: + print("Tests successful") + sys.exit(0) + else: + print("Failed") + sys.exit(1) + + +# Test framework for doing p2p comparison testing, which sets up some bitcoind +# binaries: +# 1 binary: test binary +# 2 binaries: 1 test binary, 1 ref binary +# n>2 binaries: 1 test binary, n-1 ref binaries + +class ComparisonTestFramework(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.cache_behavior = 'clean' + self.additional_args = [] + + def add_options(self, parser): + parser.add_option("--testbinary", dest="testbinary", + default=os.getenv("CARGO_BIN_EXE_zebrad", zcashd_binary()), + help="zebrad binary to test") + parser.add_option("--refbinary", dest="refbinary", + default=os.getenv("CARGO_BIN_EXE_zebrad", zcashd_binary()), + help="zebrad binary to use for reference nodes (if any)") + + def setup_network(self): + self.nodes = start_nodes( + self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1'] + self.additional_args] * self.num_nodes, + binary=[self.options.testbinary] + + [self.options.refbinary]*(self.num_nodes-1)) + + def get_tests(self): + raise NotImplementedError diff --git a/zebra-rpc/qa/rpc-tests/test_framework/util.py b/zebra-rpc/qa/rpc-tests/test_framework/util.py new file mode 100644 index 00000000000..c50e730307c --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/util.py @@ -0,0 +1,802 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2016-2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + + +# +# Helpful routines for regression testing +# + +import os +import sys + +from binascii import hexlify, unhexlify +from base64 import b64encode +from decimal import Decimal, ROUND_DOWN +import json +import http.client +import random +import shutil +import subprocess +import tarfile +import tempfile +import time +import re +import errno + +from . import coverage +from .proxy import ServiceProxy, JSONRPCException + +LEGACY_DEFAULT_FEE = Decimal('0.00001') + +COVERAGE_DIR = None +PRE_BLOSSOM_BLOCK_TARGET_SPACING = 150 +POST_BLOSSOM_BLOCK_TARGET_SPACING = 75 + +SPROUT_BRANCH_ID = 0x00000000 +OVERWINTER_BRANCH_ID = 0x5BA81B19 +SAPLING_BRANCH_ID = 0x76B809BB +BLOSSOM_BRANCH_ID = 0x2BB40E60 +HEARTWOOD_BRANCH_ID = 0xF5B9230B +CANOPY_BRANCH_ID = 0xE9FF75A6 +NU5_BRANCH_ID = 0xC2D6D0B4 +NU6_BRANCH_ID = 0xC8E71055 + +# The maximum number of nodes a single test can spawn +MAX_NODES = 8 +# Don't assign rpc or p2p ports lower than this +PORT_MIN = 11000 +# The number of ports to "reserve" for p2p and rpc, each +PORT_RANGE = 5000 + +def zcashd_binary(): + return os.getenv("CARGO_BIN_EXE_zebrad", os.path.join("..", "target", "debug", "zebrad")) + +def zebrad_config(datadir): + base_location = os.path.join('qa', 'base_config.toml') + new_location = os.path.join(datadir, "config.toml") + shutil.copyfile(base_location, new_location) + return new_location + +class PortSeed: + # Must be initialized with a unique integer for each process + n = None + +def enable_coverage(dirname): + """Maintain a log of which RPC calls are made during testing.""" + global COVERAGE_DIR + COVERAGE_DIR = dirname + + +def get_rpc_proxy(url, node_number, timeout=None): + """ + Args: + url (str): URL of the RPC server to call + node_number (int): the node number (or id) that this calls to + + Kwargs: + timeout (int): HTTP timeout in seconds + + Returns: + AuthServiceProxy. convenience object for making RPC calls. + + """ + proxy_kwargs = {} + if timeout is not None: + proxy_kwargs['timeout'] = timeout + + proxy = ServiceProxy(url, **proxy_kwargs) + proxy.url = url # store URL on proxy for info + + coverage_logfile = coverage.get_filename( + COVERAGE_DIR, node_number) if COVERAGE_DIR else None + + return coverage.AuthServiceProxyWrapper(proxy, coverage_logfile) + + +def p2p_port(n): + assert(n <= MAX_NODES) + return PORT_MIN + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) + +def rpc_port(n): + return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) + +def check_json_precision(): + """Make sure json library being used does not lose precision converting ZEC values""" + n = Decimal("20000000.00000003") + zatoshis = int(json.loads(json.dumps(float(n)))*1.0e8) + if zatoshis != 2000000000000003: + raise RuntimeError("JSON encode/decode loses precision") + +def bytes_to_hex_str(byte_str): + return hexlify(byte_str).decode('ascii') + +def hex_str_to_bytes(hex_str): + return unhexlify(hex_str.encode('ascii')) + +def str_to_b64str(string): + return b64encode(string.encode('utf-8')).decode('ascii') + +def sync_blocks(rpc_connections, wait=0.125, timeout=60, allow_different_tips=False): + """ + Wait until everybody has the same tip, and has notified + all internal listeners of them. + + If allow_different_tips is True, waits until everyone has + the same block count. + """ + while timeout > 0: + if allow_different_tips: + tips = [ x.getblockcount() for x in rpc_connections ] + else: + tips = [ x.getbestblockhash() for x in rpc_connections ] + if tips == [ tips[0] ]*len(tips): + break + time.sleep(wait) + timeout -= wait + + """ Zebra does not support the `fullyNotified` field in the `blockchaininfo` RPC + # Now that the block counts are in sync, wait for the internal + # notifications to finish + while timeout > 0: + notified = [ x.getblockchaininfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + return True + time.sleep(wait) + timeout -= wait + + raise AssertionError("Block sync failed") + """ + return True + +def sync_mempools(rpc_connections, wait=0.5, timeout=60): + """ + Wait until everybody has the same transactions in their memory + pools, and has notified all internal listeners of them + """ + while timeout > 0: + pool = set(rpc_connections[0].getrawmempool()) + num_match = 1 + for i in range(1, len(rpc_connections)): + if set(rpc_connections[i].getrawmempool()) == pool: + num_match = num_match+1 + if num_match == len(rpc_connections): + break + time.sleep(wait) + timeout -= wait + + """ Zebra does not support the `fullyNotified` field in the `getmempoolinfo` RPC + # Now that the mempools are in sync, wait for the internal + # notifications to finish + while timeout > 0: + notified = [ x.getmempoolinfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + return True + time.sleep(wait) + timeout -= wait + + raise AssertionError("Mempool sync failed") + """ + return True + +bitcoind_processes = {} + +def initialize_datadir(dirname, n, clock_offset=0): + datadir = os.path.join(dirname, "node"+str(n)) + if not os.path.isdir(datadir): + os.makedirs(datadir) + rpc_u, rpc_p = rpc_auth_pair(n) + config_rpc_port = rpc_port(n) + config_p2p_port = p2p_port(n) + + with open(os.path.join(datadir, "zcash.conf"), 'w', encoding='utf8') as f: + f.write("regtest=1\n") + f.write("showmetrics=0\n") + f.write("rpcuser=" + rpc_u + "\n") + f.write("rpcpassword=" + rpc_p + "\n") + f.write("port="+str(config_p2p_port)+"\n") + f.write("rpcport="+str(config_rpc_port)+"\n") + f.write("listenonion=0\n") + if clock_offset != 0: + f.write('clockoffset='+str(clock_offset)+'\n') + + update_zebrad_conf(datadir, config_rpc_port, config_p2p_port) + + return datadir + +def update_zebrad_conf(datadir, rpc_port, p2p_port): + import toml + + config_path = zebrad_config(datadir) + + with open(config_path, 'r') as f: + config_file = toml.load(f) + + config_file['rpc']['listen_addr'] = '127.0.0.1:'+str(rpc_port) + config_file['network']['listen_addr'] = '127.0.0.1:'+str(p2p_port) + config_file['state']['cache_dir'] = datadir + + with open(config_path, 'w') as f: + toml.dump(config_file, f) + + return config_path + +def rpc_auth_pair(n): + return 'rpcuser💻' + str(n), 'rpcpass🔑' + str(n) + +def rpc_url(i, rpchost=None): + rpc_u, rpc_p = rpc_auth_pair(i) + host = '127.0.0.1' + port = rpc_port(i) + if rpchost: + parts = rpchost.split(':') + if len(parts) == 2: + host, port = parts + else: + host = rpchost + # For zebra, we just use a non-authenticated endpoint. + return "http://%s:%d" % (host, int(port)) + # We might want to get back to authenticated endpoints after #8864: + #return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, host, int(port)) + +def wait_for_bitcoind_start(process, url, i): + ''' + Wait for bitcoind to start. This means that RPC is accessible and fully initialized. + Raise an exception if bitcoind exits during initialization. + ''' + time.sleep(1) # give zebrad a moment to start + while True: + if process.poll() is not None: + raise Exception('%s node %d exited with status %i during initialization' % (zcashd_binary(), i, process.returncode)) + try: + rpc = get_rpc_proxy(url, i) + rpc.getblockcount() + break # break out of loop on success + except IOError as e: + if e.errno != errno.ECONNREFUSED: # Port not yet open? + raise # unknown IO error + except JSONRPCException as e: # Initialization phase + if e.error['code'] != -28: # RPC in warmup? + raise # unknown JSON RPC exception + time.sleep(0.25) + +def initialize_chain(test_dir, num_nodes, cachedir, cache_behavior='current'): + """ + Create a set of node datadirs in `test_dir`, based upon the specified + `cache_behavior` value. The following values are recognized for + `cache_behavior`: + + * 'current': create a 200-block-long chain (with wallet) for MAX_NODES + in `cachedir` if necessary. Afterward, create num_nodes copies in + `test_dir` from the cache. The resulting nodes will be configured to + use the -clockoffset config argument when starting to ensure that + the cached chain is not treated as being excessively out-of-date. + * 'sprout': use persisted chain data containing known amounts of Sprout + funds from the files in `qa/rpc-tests/cache/sprout`. This allows + testing of Sprout spends even though Sprout outputs can no longer + be created by zcashd software. The resulting nodes will be configured to + use the -clockoffset config argument when starting to ensure that + the cached chain is not treated as being excessively out-of-date. + * 'fresh': force re-creation of the cache, and then start as for `current`. + * 'clean': start the nodes without cached chain data, allowing the test + to take full control of chain setup. + """ + assert num_nodes <= MAX_NODES + + def rebuild_cache(): + #find and delete old cache directories if any exist + for i in range(MAX_NODES): + if os.path.isdir(os.path.join(cachedir,"node"+str(i))): + shutil.rmtree(os.path.join(cachedir,"node"+str(i))) + + # Create cache directories, run bitcoinds: + block_time = int(time.time()) - (200 * PRE_BLOSSOM_BLOCK_TARGET_SPACING) + for i in range(MAX_NODES): + datadir = initialize_datadir(cachedir, i) + + config = update_zebrad_conf(datadir, rpc_port(i), p2p_port(i)) + binary = zcashd_binary() + args = [ binary, "-c="+config, "start" ] + + bitcoind_processes[i] = subprocess.Popen(args) + if os.getenv("PYTHON_DEBUG", ""): + print("initialize_chain: %s started, waiting for RPC to come up" % (zcashd_binary(),)) + wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i) + if os.getenv("PYTHON_DEBUG", ""): + print("initialize_chain: RPC successfully started") + + rpcs = [] + for i in range(MAX_NODES): + try: + rpcs.append(get_rpc_proxy(rpc_url(i), i)) + except: + sys.stderr.write("Error connecting to "+rpc_url(i)+"\n") + sys.exit(1) + + # Create a 200-block-long chain; each of the 4 first nodes + # gets 25 mature blocks and 25 immature. + # Note: To preserve compatibility with older versions of + # initialize_chain, only 4 nodes will generate coins. + # + # Blocks are created with timestamps 2.5 minutes apart (matching the + # chain defaulting above to Sapling active), starting 200 * 2.5 minutes + # before the current time. + for i in range(2): + for peer in range(4): + for j in range(25): + # Removed because zebrad does not has this RPC method: + #set_node_times(rpcs, block_time) + rpcs[peer].generate(1) + block_time += PRE_BLOSSOM_BLOCK_TARGET_SPACING + # Must sync before next peer starts generating blocks + sync_blocks(rpcs) + # Check that local time isn't going backwards + assert_greater_than(time.time() + 1, block_time) + + # Shut them down, and clean up cache directories: + stop_nodes(rpcs) + wait_bitcoinds() + + for i in range(MAX_NODES): + # record the system time at which the cache was regenerated + with open(node_file(cachedir, i, 'cache_config.json'), "w", encoding="utf8") as cache_conf_file: + cache_config = { "cache_time": time.time() } + cache_conf_json = json.dumps(cache_config, indent=4) + cache_conf_file.write(cache_conf_json) + + # Removed as zebrad do not created these files: + #os.remove(node_file(cachedir, i, "debug.log")) + #os.remove(node_file(cachedir, i, "db.log")) + #os.remove(node_file(cachedir, i, "peers.dat")) + + + def init_from_cache(): + for i in range(num_nodes): + from_dir = os.path.join(cachedir, "node"+str(i)) + to_dir = os.path.join(test_dir, "node"+str(i)) + shutil.copytree(from_dir, to_dir) + with open(os.path.join(to_dir, 'cache_config.json'), "r", encoding="utf8") as cache_conf_file: + cache_conf = json.load(cache_conf_file) + # obtain the clock offset as a negative number of seconds + offset = round(cache_conf['cache_time']) - round(time.time()) + # overwrite port/rpcport and clock offset in zcash.conf + initialize_datadir(test_dir, i, clock_offset=offset) + + def init_persistent(cache_behavior): + assert num_nodes <= 4 # only 4 nodes with Sprout funds are supported + cache_path = persistent_cache_path(cache_behavior) + if not os.path.isdir(cache_path): + raise Exception('No cache available for cache behavior %s' % cache_behavior) + + chain_cache_filename = os.path.join(cache_path, "chain_cache.tar.gz") + if not os.path.exists(chain_cache_filename): + raise Exception('Chain cache missing for cache behavior %s' % cache_behavior) + + for i in range(num_nodes): + to_dir = os.path.join(test_dir, "node"+str(i), "regtest") + os.makedirs(to_dir) + + # Copy the same chain data to all nodes + with tarfile.open(chain_cache_filename, "r:gz") as chain_cache_file: + tarfile_extractall(chain_cache_file, to_dir) + + # Copy in per-node wallet data + wallet_tgz_filename = os.path.join(cache_path, "node"+str(i)+"_wallet.tar.gz") + if not os.path.exists(wallet_tgz_filename): + raise Exception('Wallet cache missing for cache behavior %s, node %d' % (cache_behavior, i)) + with tarfile.open(wallet_tgz_filename, "r:gz") as wallet_tgz_file: + tarfile_extractall(wallet_tgz_file, os.path.join(to_dir, "wallet.dat")) + + # Copy in per-node wallet config and update zcash.conf to set the + # clock offsets correctly. + cache_conf_filename = os.path.join(to_dir, 'cache_config.json') + if not os.path.exists(cache_conf_filename): + raise Exception('Cache config missing for cache behavior %s, node %d' % (cache_behavior, i)) + with open(cache_conf_filename, "r", encoding="utf8") as cache_conf_file: + cache_conf = json.load(cache_conf_file) + # obtain the clock offset as a negative number of seconds + offset = round(cache_conf['cache_time']) - round(time.time()) + # overwrite port/rpcport and clock offset in zcash.conf + initialize_datadir(test_dir, i, clock_offset=offset) + + def cache_rebuild_required(): + for i in range(MAX_NODES): + node_path = os.path.join(cachedir, 'node'+str(i)) + if os.path.isdir(node_path): + if not os.path.isfile(node_file(cachedir, i, 'cache_config.json')): + return True + else: + return True + return False + + if cache_behavior == 'current': + if cache_rebuild_required(): rebuild_cache() + init_from_cache() + elif cache_behavior == 'fresh': + rebuild_cache() + init_from_cache() + elif cache_behavior == 'clean': + initialize_chain_clean(test_dir, num_nodes) + else: + init_persistent(cache_behavior) + +def initialize_chain_clean(test_dir, num_nodes): + """ + Create an empty blockchain and num_nodes wallets. + Useful if a test case wants complete control over initialization. + """ + for i in range(num_nodes): + initialize_datadir(test_dir, i) + +def persistent_cache_path(cache_behavior): + return os.path.join( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))), + 'cache', + cache_behavior + ) + +def persistent_cache_exists(cache_behavior): + cache_path = persistent_cache_path(cache_behavior) + return os.path.isdir(cache_path) + +# Clean up, zip, and persist the generated datadirs. Record the generation +# time so that we can correctly set the system clock offset in tests that +# restore their node states using the resulting files. +def persist_node_caches(tmpdir, cache_behavior, num_nodes): + cache_path = persistent_cache_path(cache_behavior) + if os.path.exists(cache_path): + raise Exception('Cache already exists for cache behavior %s' % cache_behavior) + os.mkdir(cache_path) + + for i in range(num_nodes): + node_path = os.path.join(tmpdir, 'node' + str(i)) + + # Clean up the files that we don't want to persist + os.remove(os.path.join(node_path, 'debug.log')) + os.remove(os.path.join(node_path, 'db.log')) + os.remove(os.path.join(node_path, 'peers.dat')) + + # Persist the wallet file for the node to the cache + wallet_tgz_filename = os.path.join(cache_path, 'node' + str(i) + '_wallet.tar.gz') + with tarfile.open(wallet_tgz_filename, "w:gz") as wallet_tgz_file: + wallet_tgz_file.add(os.path.join(node_path, 'wallet.dat'), arcname="") + + # Persist the chain data and cache config just once; it will be reused + # for all of the nodes when loading from the cache. + if i == 0: + # Move the wallet.dat file out of the way so that it doesn't + # pollute the chain cache tarfile + shutil.move( + os.path.join(node_path, 'wallet.dat'), + os.path.join(tmpdir, 'wallet.dat.0')) + + # Store the current time so that we can correctly set the clock + # offset when restoring from the cache. + cache_config = { "cache_time": time.time() } + cache_conf_filename = os.path.join(cache_path, 'cache_config.json') + with open(cache_conf_filename, "w", encoding="utf8") as cache_conf_file: + cache_conf_json = json.dumps(cache_config, indent=4) + cache_conf_file.write(cache_conf_json) + + # Persist the chain data. + chain_cache_filename = os.path.join(cache_path, 'chain_cache.tar.gz') + with tarfile.open(chain_cache_filename, "w:gz") as chain_cache_file: + chain_cache_file.add(node_path, arcname="") + + # Move the wallet file back into place + shutil.move( + os.path.join(tmpdir, 'wallet.dat.0'), + os.path.join(node_path, 'wallet.dat')) + + +def _rpchost_to_args(rpchost): + '''Convert optional IP:port spec to rpcconnect/rpcport args''' + if rpchost is None: + return [] + + match = re.match(r'(\[[0-9a-fA-f:]+\]|[^:]+)(?::([0-9]+))?$', rpchost) + if not match: + raise ValueError('Invalid RPC host spec ' + rpchost) + + rpcconnect = match.group(1) + rpcport = match.group(2) + + if rpcconnect.startswith('['): # remove IPv6 [...] wrapping + rpcconnect = rpcconnect[1:-1] + + rv = ['-rpcconnect=' + rpcconnect] + if rpcport: + rv += ['-rpcport=' + rpcport] + return rv + +def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): + """ + Start a bitcoind and return RPC connection to it + """ + + datadir = os.path.join(dirname, "node"+str(i)) + if binary is None: + binary = zcashd_binary() + + config = update_zebrad_conf(datadir, rpc_port(i), p2p_port(i)) + args = [ binary, "-c="+config, "start" ] + + if extra_args is not None: args.extend(extra_args) + bitcoind_processes[i] = subprocess.Popen(args, stderr=stderr) + if os.getenv("PYTHON_DEBUG", ""): + print("start_node: bitcoind started, waiting for RPC to come up") + url = rpc_url(i, rpchost) + wait_for_bitcoind_start(bitcoind_processes[i], url, i) + if os.getenv("PYTHON_DEBUG", ""): + print("start_node: RPC successfully started for node {} with pid {}".format(i, bitcoind_processes[i].pid)) + proxy = get_rpc_proxy(url, i, timeout=timewait) + + if COVERAGE_DIR: + coverage.write_all_rpc_commands(COVERAGE_DIR, proxy) + + return proxy + +def assert_start_raises_init_error(i, dirname, extra_args=None, expected_msg=None): + with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: + try: + node = start_node(i, dirname, extra_args, stderr=log_stderr) + stop_node(node, i) + except Exception as e: + assert ("%s node %d exited" % (zcashd_binary(), i)) in str(e) # node must have shutdown + if expected_msg is not None: + log_stderr.seek(0) + stderr = log_stderr.read().decode('utf-8') + if expected_msg not in stderr: + raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + stderr) + else: + if expected_msg is None: + assert_msg = "%s should have exited with an error" % (zcashd_binary(),) + else: + assert_msg = "%s should have exited with expected error %r" % (zcashd_binary(), expected_msg) + raise AssertionError(assert_msg) + +def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): + """ + Start multiple bitcoinds, return RPC connections to them + """ + if extra_args is None: extra_args = [ None for _ in range(num_nodes) ] + if binary is None: binary = [ None for _ in range(num_nodes) ] + rpcs = [] + try: + for i in range(num_nodes): + rpcs.append(start_node(i, dirname, extra_args[i], rpchost, binary=binary[i])) + except: # If one node failed to start, stop the others + stop_nodes(rpcs) + raise + return rpcs + +def node_file(dirname, n_node, filename): + return os.path.join(dirname, "node"+str(n_node), filename) + +def check_node(i): + bitcoind_processes[i].poll() + return bitcoind_processes[i].returncode + +def stop_node(node, i): + try: + node.stop() + except http.client.CannotSendRequest as e: + print("WARN: Unable to stop node: " + repr(e)) + bitcoind_processes[i].wait() + del bitcoind_processes[i] + +def stop_nodes(nodes): + for node in nodes: + try: + node.stop() + except http.client.CannotSendRequest as e: + print("WARN: Unable to stop node: " + repr(e)) + del nodes[:] # Emptying array closes connections as a side effect + +def set_node_times(nodes, t): + for node in nodes: + node.setmocktime(t) + +def wait_bitcoinds(): + # Wait for all bitcoinds to cleanly exit + for bitcoind in list(bitcoind_processes.values()): + bitcoind.wait() + bitcoind_processes.clear() + +def connect_nodes(from_connection, node_num): + ip_port = "127.0.0.1:"+str(p2p_port(node_num)) + from_connection.addnode(ip_port, "onetry") + # poll until version handshake complete to avoid race conditions + # with transaction relaying + while any(peer['version'] == 0 for peer in from_connection.getpeerinfo()): + time.sleep(0.1) + +def connect_nodes_bi(nodes, a, b): + connect_nodes(nodes[a], b) + connect_nodes(nodes[b], a) + +def find_output(node, txid, amount): + """ + Return index to output of txid with value amount + Raises exception if there is none. + """ + txdata = node.getrawtransaction(txid, 1) + for i in range(len(txdata["vout"])): + if txdata["vout"][i]["value"] == amount: + return i + raise RuntimeError("find_output txid %s : %s not found"%(txid,str(amount))) + + +def gather_inputs(from_node, amount_needed, confirmations_required=1): + """ + Return a random set of unspent txouts that are enough to pay amount_needed + """ + assert(confirmations_required >=0) + utxo = from_node.listunspent(confirmations_required) + random.shuffle(utxo) + inputs = [] + total_in = Decimal("0.00000000") + while total_in < amount_needed and len(utxo) > 0: + t = utxo.pop() + total_in += t["amount"] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"], "address" : t["address"] } ) + if total_in < amount_needed: + raise RuntimeError("Insufficient funds: need %d, have %d"%(amount_needed, total_in)) + return (total_in, inputs) + +def make_change(from_node, amount_in, amount_out, fee): + """ + Create change output(s), return them + """ + outputs = {} + amount = amount_out+fee + change = amount_in - amount + if change > amount*2: + # Create an extra change output to break up big inputs + change_address = from_node.getnewaddress() + # Split change in two, being careful of rounding: + outputs[change_address] = Decimal(change/2).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + change = amount_in - amount - outputs[change_address] + if change > 0: + outputs[from_node.getnewaddress()] = change + return outputs + +def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants): + """ + Create a random transaction. + Returns (txid, hex-encoded-transaction-data, fee) + """ + from_node = random.choice(nodes) + to_node = random.choice(nodes) + fee = min_fee + fee_increment*random.randint(0,fee_variants) + + (total_in, inputs) = gather_inputs(from_node, amount+fee) + outputs = make_change(from_node, total_in, amount, fee) + outputs[to_node.getnewaddress()] = float(amount) + + rawtx = from_node.createrawtransaction(inputs, outputs) + signresult = from_node.signrawtransaction(rawtx) + txid = from_node.sendrawtransaction(signresult["hex"], True) + + return (txid, signresult["hex"], fee) + +def assert_equal(expected, actual, message=""): + if expected != actual: + if message: + message = "; %s" % message + raise AssertionError("(left == right)%s\n left: <%s>\n right: <%s>" % (message, str(expected), str(actual))) + +def assert_true(condition, message = ""): + if not condition: + raise AssertionError(message) + +def assert_false(condition, message = ""): + assert_true(not condition, message) + +def assert_greater_than(thing1, thing2): + if thing1 <= thing2: + raise AssertionError("%s <= %s"%(str(thing1),str(thing2))) + +def assert_raises(exc, fun, *args, **kwds): + assert_raises_message(exc, None, fun, *args, **kwds) + +def assert_raises_message(ExceptionType, errstr, func, *args, **kwargs): + """ + Asserts that func throws and that the exception contains 'errstr' + in its message. + """ + try: + func(*args, **kwargs) + except ExceptionType as e: + if errstr is not None and errstr not in str(e): + raise AssertionError("Invalid exception string: Couldn't find %r in %r" % ( + errstr, str(e))) + except Exception as e: + raise AssertionError("Unexpected exception raised: " + type(e).__name__) + else: + raise AssertionError("No exception raised") + +def fail(message=""): + raise AssertionError(message) + + +# Returns an async operation result +def wait_and_assert_operationid_status_result(node, myopid, in_status='success', in_errormsg=None, timeout=300): + print('waiting for async operation {}'.format(myopid)) + result = None + for _ in range(1, timeout): + results = node.z_getoperationresult([myopid]) + if len(results) > 0: + result = results[0] + break + time.sleep(1) + + assert_true(result is not None, "timeout occurred") + status = result['status'] + + debug = os.getenv("PYTHON_DEBUG", "") + if debug: + print('...returned status: {}'.format(status)) + + errormsg = None + if status == "failed": + errormsg = result['error']['message'] + if debug: + print('...returned error: {}'.format(errormsg)) + assert_equal(in_errormsg, errormsg) + + assert_equal(in_status, status, "Operation returned mismatched status. Error Message: {}".format(errormsg)) + + return result + + +# Returns txid if operation was a success or None +def wait_and_assert_operationid_status(node, myopid, in_status='success', in_errormsg=None, timeout=300): + result = wait_and_assert_operationid_status_result(node, myopid, in_status, in_errormsg, timeout) + if result['status'] == "success": + return result['result']['txid'] + else: + return None + +# Find a coinbase address on the node, filtering by the number of UTXOs it has. +# If no filter is provided, returns the coinbase address on the node containing +# the greatest number of spendable UTXOs. +# The default cached chain has one address per coinbase output. +def get_coinbase_address(node, expected_utxos=None): + addrs = [utxo['address'] for utxo in node.listunspent() if utxo['generated']] + assert(len(set(addrs)) > 0) + + if expected_utxos is None: + addrs = [(addrs.count(a), a) for a in set(addrs)] + return sorted(addrs, reverse=True)[0][1] + + addrs = [a for a in set(addrs) if addrs.count(a) == expected_utxos] + assert(len(addrs) > 0) + return addrs[0] + +def check_node_log(self, node_number, line_to_check, stop_node = True): + print("Checking node " + str(node_number) + " logs") + if stop_node: + self.nodes[node_number].stop() + bitcoind_processes[node_number].wait() + logpath = self.options.tmpdir + "/node" + str(node_number) + "/regtest/debug.log" + with open(logpath, "r", encoding="utf8") as myfile: + logdata = myfile.readlines() + for (n, logline) in enumerate(logdata): + if line_to_check in logline: + return n + raise AssertionError(repr(line_to_check) + " not found") + +def nustr(branch_id): + return '%08x' % branch_id + +def nuparams(branch_id, height): + return '-nuparams=%s:%d' % (nustr(branch_id), height) + +def tarfile_extractall(tarfile, path): + if sys.version_info >= (3, 11, 4): + tarfile.extractall(path=path, filter='data') + else: + tarfile.extractall(path=path) diff --git a/zebra-rpc/qa/rpc-tests/test_framework/zip244.py b/zebra-rpc/qa/rpc-tests/test_framework/zip244.py new file mode 100644 index 00000000000..b0f28817a6a --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/test_framework/zip244.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# zip244.py +# +# Functionality to create txids, auth digests, and signature digests. +# +# This file is modified from zcash/zcash-test-vectors. +# + +import struct + +from hashlib import blake2b + +from .mininode import ser_string, ser_uint256 +from .script import ( + SIGHASH_ANYONECANPAY, + SIGHASH_NONE, + SIGHASH_SINGLE, + getHashOutputs, + getHashPrevouts, + getHashSequence, +) + + +# Transparent + +def transparent_digest(tx): + digest = blake2b(digest_size=32, person=b'ZTxIdTranspaHash') + + if len(tx.vin) + len(tx.vout) > 0: + digest.update(getHashPrevouts(tx, b'ZTxIdPrevoutHash')) + digest.update(getHashSequence(tx, b'ZTxIdSequencHash')) + digest.update(getHashOutputs(tx, b'ZTxIdOutputsHash')) + + return digest.digest() + +def transparent_scripts_digest(tx): + digest = blake2b(digest_size=32, person=b'ZTxAuthTransHash') + for x in tx.vin: + digest.update(ser_string(x.scriptSig)) + return digest.digest() + +# Sapling + +def sapling_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSaplingHash') + + if len(saplingBundle.spends) + len(saplingBundle.outputs) > 0: + digest.update(sapling_spends_digest(saplingBundle)) + digest.update(sapling_outputs_digest(saplingBundle)) + digest.update(struct.pack(' 0: + for desc in saplingBundle.spends: + digest.update(desc.zkproof.serialize()) + for desc in saplingBundle.spends: + digest.update(desc.spendAuthSig.serialize()) + for desc in saplingBundle.outputs: + digest.update(desc.zkproof.serialize()) + digest.update(saplingBundle.bindingSig.serialize()) + + return digest.digest() + +# - Spends + +def sapling_spends_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSSpendsHash') + + if len(saplingBundle.spends) > 0: + digest.update(sapling_spends_compact_digest(saplingBundle)) + digest.update(sapling_spends_noncompact_digest(saplingBundle)) + + return digest.digest() + +def sapling_spends_compact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSSpendCHash') + for desc in saplingBundle.spends: + digest.update(ser_uint256(desc.nullifier)) + return digest.digest() + +def sapling_spends_noncompact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSSpendNHash') + for desc in saplingBundle.spends: + digest.update(ser_uint256(desc.cv)) + digest.update(ser_uint256(saplingBundle.anchor)) + digest.update(ser_uint256(desc.rk)) + return digest.digest() + +# - Outputs + +def sapling_outputs_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutputHash') + + if len(saplingBundle.outputs) > 0: + digest.update(sapling_outputs_compact_digest(saplingBundle)) + digest.update(sapling_outputs_memos_digest(saplingBundle)) + digest.update(sapling_outputs_noncompact_digest(saplingBundle)) + + return digest.digest() + +def sapling_outputs_compact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutC__Hash') + for desc in saplingBundle.outputs: + digest.update(ser_uint256(desc.cmu)) + digest.update(ser_uint256(desc.ephemeralKey)) + digest.update(desc.encCiphertext[:52]) + return digest.digest() + +def sapling_outputs_memos_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutM__Hash') + for desc in saplingBundle.outputs: + digest.update(desc.encCiphertext[52:564]) + return digest.digest() + +def sapling_outputs_noncompact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutN__Hash') + for desc in saplingBundle.outputs: + digest.update(ser_uint256(desc.cv)) + digest.update(desc.encCiphertext[564:]) + digest.update(desc.outCiphertext) + return digest.digest() + +# Orchard + +def orchard_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrchardHash') + + if len(orchardBundle.actions) > 0: + digest.update(orchard_actions_compact_digest(orchardBundle)) + digest.update(orchard_actions_memos_digest(orchardBundle)) + digest.update(orchard_actions_noncompact_digest(orchardBundle)) + digest.update(struct.pack('B', orchardBundle.flags())) + digest.update(struct.pack(' 0: + digest.update(bytes(orchardBundle.proofs)) + for desc in orchardBundle.actions: + digest.update(desc.spendAuthSig.serialize()) + digest.update(orchardBundle.bindingSig.serialize()) + + return digest.digest() + +# - Actions + +def orchard_actions_compact_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrcActCHash') + for desc in orchardBundle.actions: + digest.update(ser_uint256(desc.nullifier)) + digest.update(ser_uint256(desc.cmx)) + digest.update(ser_uint256(desc.ephemeralKey)) + digest.update(desc.encCiphertext[:52]) + return digest.digest() + +def orchard_actions_memos_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrcActMHash') + for desc in orchardBundle.actions: + digest.update(desc.encCiphertext[52:564]) + return digest.digest() + +def orchard_actions_noncompact_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrcActNHash') + for desc in orchardBundle.actions: + digest.update(ser_uint256(desc.cv)) + digest.update(ser_uint256(desc.rk)) + digest.update(desc.encCiphertext[564:]) + digest.update(desc.outCiphertext) + return digest.digest() + +# Transaction + +def header_digest(tx): + digest = blake2b(digest_size=32, person=b'ZTxIdHeadersHash') + + digest.update(struct.pack(' Date: Mon, 23 Sep 2024 09:22:14 -0400 Subject: [PATCH 32/46] Returns an error instead of panicking when the relevant chain is empty (#8883) --- zebra-state/src/service/check.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/zebra-state/src/service/check.rs b/zebra-state/src/service/check.rs index b20ca0fd4c5..ced63bfea16 100644 --- a/zebra-state/src/service/check.rs +++ b/zebra-state/src/service/check.rs @@ -67,9 +67,16 @@ where .take(POW_ADJUSTMENT_BLOCK_SPAN) .collect(); - let parent_block = relevant_chain - .first() - .expect("state must contain parent block to do contextual validation"); + let Some(parent_block) = relevant_chain.first() else { + warn!( + ?semantically_verified, + ?finalized_tip_height, + "state must contain parent block to do contextual validation" + ); + + return Err(ValidateContextError::NotReadyToBeCommitted); + }; + let parent_block = parent_block.borrow(); let parent_height = parent_block .coinbase_height() From ac1242a189e6f22bb132a01bc1ab3b89daedc041 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Tue, 24 Sep 2024 12:52:04 +0100 Subject: [PATCH 33/46] feat(ci): add Docker Scout vulnerabilities scanning (#8871) * feat(ci): add Docker Scout vulnerabilities scanning * fix(scout): add missing `environment` command Co-authored-by: Marek --------- Co-authored-by: Marek --- .github/workflows/sub-build-docker-image.yml | 33 +++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sub-build-docker-image.yml b/.github/workflows/sub-build-docker-image.yml index 83af03ad6e1..78b34199c1b 100644 --- a/.github/workflows/sub-build-docker-image.yml +++ b/.github/workflows/sub-build-docker-image.yml @@ -4,6 +4,7 @@ # - Uses Docker Buildx for improved build performance and caching. # - Builds the Docker image and pushes it to both Google Artifact Registry and potentially DockerHub, depending on release type. # - Manages caching strategies to optimize build times across different branches. +# - Uses Docker Scout to display vulnerabilities and recommendations for the latest built image. name: Build docker image on: @@ -75,6 +76,7 @@ jobs: permissions: contents: 'read' id-token: 'write' + pull-requests: write # for `docker-scout` to be able to write the comment env: DOCKER_BUILD_SUMMARY: ${{ vars.DOCKER_BUILD_SUMMARY }} steps: @@ -150,7 +152,7 @@ jobs: # Setup Docker Buildx to use Docker Build Cloud - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v3.6.1 with: version: "lab:latest" driver: cloud @@ -179,3 +181,32 @@ jobs: # Don't read from the cache if the caller disabled it. # https://docs.docker.com/engine/reference/commandline/buildx_build/#options no-cache: ${{ inputs.no_cache }} + + # For the latest built image, display: + # - the vulnerabilities (ignoring the base image, and only displaying vulnerabilities with a critical or high security severity) + # - the available recommendations + # - compare it to the latest image indexed in Docker Hub (only displaying changed packages and vulnerabilities that already have a fix) + # + # Record the image to Scout environment based on the event type, for example: + # - `prod` for a release event + # - `stage` for a push event to the main branch + # - `dev` for a pull request event + - name: Docker Scout + id: docker-scout + uses: docker/scout-action@v1.13.0 + # We only run Docker Scout on the `runtime` target, as the other targets are not meant to be released + # and are commonly used for testing, and thus are ephemeral. + # TODO: Remove the `contains` check once we have a better way to determine if just new vulnerabilities are present. + # See: https://github.com/docker/scout-action/issues/56 + if: ${{ inputs.dockerfile_target == 'runtime' && contains(github.event.pull_request.title, 'Release v') }} + with: + command: cves,recommendations,compare,environment + image: us-docker.pkg.dev/${{ vars.GCP_PROJECT }}/zebra/${{ inputs.image_name }}:${{ steps.meta.outputs.version }} + to: zfnd/zebra:latest + ignore-base: true + ignore-unchanged: true + only-fixed: true + only-severities: critical,high + environment: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'prod') || (github.event_name == 'push' && github.ref_name == 'main' && 'stage') || (github.event_name == 'pull_request' && 'dev') }} + organization: zfnd + github-token: ${{ secrets.GITHUB_TOKEN }} # to be able to write the comment From 689a77637b46d21d27fbff5bf999f2b44aebe1e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:55:29 +0000 Subject: [PATCH 34/46] build(deps): bump docker/scout-action in the devops group (#8890) Bumps the devops group with 1 update: [docker/scout-action](https://github.com/docker/scout-action). Updates `docker/scout-action` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/docker/scout-action/releases) - [Commits](https://github.com/docker/scout-action/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: docker/scout-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: devops ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/sub-build-docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sub-build-docker-image.yml b/.github/workflows/sub-build-docker-image.yml index 78b34199c1b..946241a4bae 100644 --- a/.github/workflows/sub-build-docker-image.yml +++ b/.github/workflows/sub-build-docker-image.yml @@ -193,7 +193,7 @@ jobs: # - `dev` for a pull request event - name: Docker Scout id: docker-scout - uses: docker/scout-action@v1.13.0 + uses: docker/scout-action@v1.14.0 # We only run Docker Scout on the `runtime` target, as the other targets are not meant to be released # and are commonly used for testing, and thus are ephemeral. # TODO: Remove the `contains` check once we have a better way to determine if just new vulnerabilities are present. From 3bf4bc82d64a591f1be357fa8f2a572a6c0bf4c4 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Fri, 4 Oct 2024 14:51:13 +0100 Subject: [PATCH 35/46] fix(actions): disk regeneration does not required a cached state (#8910) --- .github/workflows/sub-deploy-integration-tests-gcp.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sub-deploy-integration-tests-gcp.yml b/.github/workflows/sub-deploy-integration-tests-gcp.yml index 4d1d346ff1d..82b5573c25d 100644 --- a/.github/workflows/sub-deploy-integration-tests-gcp.yml +++ b/.github/workflows/sub-deploy-integration-tests-gcp.yml @@ -113,6 +113,7 @@ jobs: get-disk-name: name: Get disk name uses: ./.github/workflows/sub-find-cached-disks.yml + if: ${{ inputs.needs_zebra_state || inputs.needs_lwd_state }} with: network: ${{ inputs.network || vars.ZCASH_NETWORK }} disk_prefix: ${{ inputs.needs_lwd_state && 'lwd-cache' || inputs.needs_zebra_state && 'zebrad-cache' }} From abfb9ce29c5f556f03f7551bd50959b715438d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:01:02 +0000 Subject: [PATCH 36/46] build(deps): bump the devops group with 4 updates (#8905) Bumps the devops group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [google-github-actions/auth](https://github.com/google-github-actions/auth), [codecov/codecov-action](https://github.com/codecov/codecov-action) and [docker/build-push-action](https://github.com/docker/build-push-action). Updates `actions/checkout` from 4.1.7 to 4.2.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.7...v4.2.0) Updates `google-github-actions/auth` from 2.1.5 to 2.1.6 - [Release notes](https://github.com/google-github-actions/auth/releases) - [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md) - [Commits](https://github.com/google-github-actions/auth/compare/v2.1.5...v2.1.6) Updates `codecov/codecov-action` from 4.5.0 to 4.6.0 - [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/v4.5.0...v4.6.0) Updates `docker/build-push-action` from 6.7.0 to 6.9.0 - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.7.0...v6.9.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor dependency-group: devops - dependency-name: google-github-actions/auth dependency-type: direct:production update-type: version-update:semver-patch dependency-group: devops - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: devops - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: devops ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cd-deploy-nodes-gcp.yml | 8 ++++---- .github/workflows/chore-delete-gcp-resources.yml | 8 ++++---- .github/workflows/ci-build-crates.patch.yml | 2 +- .github/workflows/ci-build-crates.yml | 4 ++-- .github/workflows/ci-coverage.yml | 4 ++-- .github/workflows/ci-lint.yml | 10 +++++----- .github/workflows/ci-unit-tests-os.yml | 10 +++++----- .github/workflows/docs-deploy-firebase.yml | 8 ++++---- .github/workflows/docs-dockerhub-description.yml | 2 +- .github/workflows/manual-zcashd-deploy.yml | 4 ++-- .github/workflows/release-crates-io.yml | 2 +- .github/workflows/sub-build-docker-image.yml | 6 +++--- .../workflows/sub-deploy-integration-tests-gcp.yml | 12 ++++++------ .github/workflows/sub-find-cached-disks.yml | 4 ++-- .github/workflows/sub-test-zebra-config.yml | 2 +- 15 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.github/workflows/cd-deploy-nodes-gcp.yml b/.github/workflows/cd-deploy-nodes-gcp.yml index fcd14715e8a..9b403b53025 100644 --- a/.github/workflows/cd-deploy-nodes-gcp.yml +++ b/.github/workflows/cd-deploy-nodes-gcp.yml @@ -219,7 +219,7 @@ jobs: if: ${{ !cancelled() && !failure() && ((github.event_name == 'push' && github.ref_name == 'main') || github.event_name == 'release') }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -242,7 +242,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' @@ -329,7 +329,7 @@ jobs: if: github.event_name == 'workflow_dispatch' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -352,7 +352,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' diff --git a/.github/workflows/chore-delete-gcp-resources.yml b/.github/workflows/chore-delete-gcp-resources.yml index 50848347834..614ae82431e 100644 --- a/.github/workflows/chore-delete-gcp-resources.yml +++ b/.github/workflows/chore-delete-gcp-resources.yml @@ -39,14 +39,14 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' @@ -106,14 +106,14 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' diff --git a/.github/workflows/ci-build-crates.patch.yml b/.github/workflows/ci-build-crates.patch.yml index 3e6de342080..3e35849ea0e 100644 --- a/.github/workflows/ci-build-crates.patch.yml +++ b/.github/workflows/ci-build-crates.patch.yml @@ -23,7 +23,7 @@ jobs: outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 # Setup Rust with stable toolchain and minimal profile - name: Setup Rust diff --git a/.github/workflows/ci-build-crates.yml b/.github/workflows/ci-build-crates.yml index e8784b886b5..fe764136144 100644 --- a/.github/workflows/ci-build-crates.yml +++ b/.github/workflows/ci-build-crates.yml @@ -60,7 +60,7 @@ jobs: outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 - uses: r7kamura/rust-problem-matchers@v1.5.0 # Setup Rust with stable toolchain and minimal profile @@ -122,7 +122,7 @@ jobs: matrix: ${{ fromJson(needs.matrix.outputs.matrix) }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index b47904c1243..50d9d911a4b 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -69,7 +69,7 @@ jobs: runs-on: ubuntu-latest-xl steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -103,4 +103,4 @@ jobs: run: cargo llvm-cov --lcov --no-run --output-path lcov.info - name: Upload coverage report to Codecov - uses: codecov/codecov-action@v4.5.0 + uses: codecov/codecov-action@v4.6.0 diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index a2ea13523b8..4c354ebaaeb 100644 --- a/.github/workflows/ci-lint.yml +++ b/.github/workflows/ci-lint.yml @@ -37,7 +37,7 @@ jobs: rust: ${{ steps.changed-files-rust.outputs.any_changed == 'true' }} workflows: ${{ steps.changed-files-workflows.outputs.any_changed == 'true' }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false fetch-depth: 0 @@ -69,7 +69,7 @@ jobs: if: ${{ needs.changed-files.outputs.rust == 'true' }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -119,7 +119,7 @@ jobs: if: ${{ needs.changed-files.outputs.rust == 'true' }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -149,7 +149,7 @@ jobs: needs: changed-files if: ${{ needs.changed-files.outputs.workflows == 'true' }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 - name: actionlint uses: reviewdog/action-actionlint@v1.48.0 with: @@ -166,7 +166,7 @@ jobs: runs-on: ubuntu-latest needs: changed-files steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 - uses: codespell-project/actions-codespell@v2.1 with: only_warn: 1 diff --git a/.github/workflows/ci-unit-tests-os.yml b/.github/workflows/ci-unit-tests-os.yml index 34bb57da2cd..036be178d34 100644 --- a/.github/workflows/ci-unit-tests-os.yml +++ b/.github/workflows/ci-unit-tests-os.yml @@ -94,7 +94,7 @@ jobs: rust: beta steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -183,7 +183,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -205,7 +205,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -248,7 +248,7 @@ jobs: continue-on-error: ${{ matrix.checks == 'advisories' }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -269,7 +269,7 @@ jobs: steps: - name: Checkout git repository - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 diff --git a/.github/workflows/docs-deploy-firebase.yml b/.github/workflows/docs-deploy-firebase.yml index 6f0fad37f89..e9431693fd7 100644 --- a/.github/workflows/docs-deploy-firebase.yml +++ b/.github/workflows/docs-deploy-firebase.yml @@ -85,7 +85,7 @@ jobs: pull-requests: write steps: - name: Checkout the source code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -106,7 +106,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_FIREBASE_SA }}' @@ -138,7 +138,7 @@ jobs: pull-requests: write steps: - name: Checkout the source code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -164,7 +164,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_FIREBASE_SA }}' diff --git a/.github/workflows/docs-dockerhub-description.yml b/.github/workflows/docs-dockerhub-description.yml index 5448b32a68a..e232c55fb5d 100644 --- a/.github/workflows/docs-dockerhub-description.yml +++ b/.github/workflows/docs-dockerhub-description.yml @@ -17,7 +17,7 @@ jobs: dockerHubDescription: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false diff --git a/.github/workflows/manual-zcashd-deploy.yml b/.github/workflows/manual-zcashd-deploy.yml index 3f50e17048d..b805289aa30 100644 --- a/.github/workflows/manual-zcashd-deploy.yml +++ b/.github/workflows/manual-zcashd-deploy.yml @@ -29,7 +29,7 @@ jobs: id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false @@ -52,7 +52,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' diff --git a/.github/workflows/release-crates-io.yml b/.github/workflows/release-crates-io.yml index feaf1a9e508..5270af8ac27 100644 --- a/.github/workflows/release-crates-io.yml +++ b/.github/workflows/release-crates-io.yml @@ -70,7 +70,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@v1.5.0 - name: Checkout git repository - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.0 with: persist-credentials: false diff --git a/.github/workflows/sub-build-docker-image.yml b/.github/workflows/sub-build-docker-image.yml index 946241a4bae..aea227d1e46 100644 --- a/.github/workflows/sub-build-docker-image.yml +++ b/.github/workflows/sub-build-docker-image.yml @@ -80,7 +80,7 @@ jobs: env: DOCKER_BUILD_SUMMARY: ${{ vars.DOCKER_BUILD_SUMMARY }} steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -126,7 +126,7 @@ jobs: - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_ARTIFACTS_SA }}' @@ -161,7 +161,7 @@ jobs: # Build and push image to Google Artifact Registry, and possibly DockerHub - name: Build & push id: docker_build - uses: docker/build-push-action@v6.7.0 + uses: docker/build-push-action@v6.9.0 with: target: ${{ inputs.dockerfile_target }} context: . diff --git a/.github/workflows/sub-deploy-integration-tests-gcp.yml b/.github/workflows/sub-deploy-integration-tests-gcp.yml index 82b5573c25d..1145a1d6740 100644 --- a/.github/workflows/sub-deploy-integration-tests-gcp.yml +++ b/.github/workflows/sub-deploy-integration-tests-gcp.yml @@ -140,7 +140,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false fetch-depth: '2' @@ -172,7 +172,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' @@ -390,7 +390,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false fetch-depth: '2' @@ -434,7 +434,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' @@ -686,7 +686,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false fetch-depth: '2' @@ -700,7 +700,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' diff --git a/.github/workflows/sub-find-cached-disks.yml b/.github/workflows/sub-find-cached-disks.yml index 00254c14be5..e52ef86327e 100644 --- a/.github/workflows/sub-find-cached-disks.yml +++ b/.github/workflows/sub-find-cached-disks.yml @@ -58,7 +58,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false fetch-depth: 0 @@ -66,7 +66,7 @@ jobs: # Setup gcloud CLI - name: Authenticate to Google Cloud id: auth - uses: google-github-actions/auth@v2.1.5 + uses: google-github-actions/auth@v2.1.6 with: workload_identity_provider: '${{ vars.GCP_WIF }}' service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}' diff --git a/.github/workflows/sub-test-zebra-config.yml b/.github/workflows/sub-test-zebra-config.yml index 7dbee6ba357..92791f31d54 100644 --- a/.github/workflows/sub-test-zebra-config.yml +++ b/.github/workflows/sub-test-zebra-config.yml @@ -38,7 +38,7 @@ jobs: timeout-minutes: 30 runs-on: ubuntu-latest-m steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: persist-credentials: false From 841047aa37378517968976caea2ab025cf369cb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:11:13 +0000 Subject: [PATCH 37/46] build(deps): bump the prod group across 1 directory with 24 updates (#8899) * build(deps): bump the prod group across 1 directory with 24 updates Bumps the prod group with 24 updates in the / directory: | Package | From | To | | --- | --- | --- | | [clap](https://github.com/clap-rs/clap) | `4.5.13` | `4.5.18` | | [indexmap](https://github.com/indexmap-rs/indexmap) | `2.3.0` | `2.5.0` | | [serde](https://github.com/serde-rs/serde) | `1.0.204` | `1.0.210` | | [tokio](https://github.com/tokio-rs/tokio) | `1.39.2` | `1.40.0` | | [tokio-stream](https://github.com/tokio-rs/tokio) | `0.1.15` | `0.1.16` | | [tower](https://github.com/tower-rs/tower) | `0.4.13` | `0.5.0` | | [thiserror](https://github.com/dtolnay/thiserror) | `1.0.63` | `1.0.64` | | [hyper-util](https://github.com/hyperium/hyper-util) | `0.1.6` | `0.1.9` | | [bytes](https://github.com/tokio-rs/bytes) | `1.7.1` | `1.7.2` | | [regex](https://github.com/rust-lang/regex) | `1.10.6` | `1.11.0` | | [insta](https://github.com/mitsuhiko/insta) | `1.39.0` | `1.40.0` | | [serde_json](https://github.com/serde-rs/json) | `1.0.122` | `1.0.128` | | [tempfile](https://github.com/Stebalien/tempfile) | `3.11.0` | `3.13.0` | | [prost](https://github.com/tokio-rs/prost) | `0.13.1` | `0.13.3` | | [tonic](https://github.com/hyperium/tonic) | `0.12.1` | `0.12.3` | | [tonic-build](https://github.com/hyperium/tonic) | `0.12.1` | `0.12.3` | | [primitive-types](https://github.com/paritytech/parity-common) | `0.12.2` | `0.13.1` | | [uint](https://github.com/paritytech/parity-common) | `0.9.5` | `0.10.0` | | [tokio-util](https://github.com/tokio-rs/tokio) | `0.7.11` | `0.7.12` | | [rlimit](https://github.com/Nugine/rlimit) | `0.10.1` | `0.10.2` | | [tonic-reflection](https://github.com/hyperium/tonic) | `0.12.1` | `0.12.3` | | [owo-colors](https://github.com/jam1garner/owo-colors) | `4.0.0` | `4.1.0` | | [syn](https://github.com/dtolnay/syn) | `2.0.72` | `2.0.79` | | [quote](https://github.com/dtolnay/quote) | `1.0.36` | `1.0.37` | Updates `clap` from 4.5.13 to 4.5.18 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.13...clap_complete-v4.5.18) Updates `indexmap` from 2.3.0 to 2.5.0 - [Changelog](https://github.com/indexmap-rs/indexmap/blob/master/RELEASES.md) - [Commits](https://github.com/indexmap-rs/indexmap/compare/2.3.0...2.5.0) Updates `serde` from 1.0.204 to 1.0.210 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.204...v1.0.210) Updates `tokio` from 1.39.2 to 1.40.0 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.39.2...tokio-1.40.0) Updates `tokio-stream` from 0.1.15 to 0.1.16 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-stream-0.1.15...tokio-stream-0.1.16) Updates `tower` from 0.4.13 to 0.5.0 - [Release notes](https://github.com/tower-rs/tower/releases) - [Commits](https://github.com/tower-rs/tower/compare/tower-0.4.13...tower-0.5.0) Updates `thiserror` from 1.0.63 to 1.0.64 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.63...1.0.64) Updates `hyper-util` from 0.1.6 to 0.1.9 - [Release notes](https://github.com/hyperium/hyper-util/releases) - [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.6...v0.1.9) Updates `bytes` from 1.7.1 to 1.7.2 - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.7.1...v1.7.2) Updates `regex` from 1.10.6 to 1.11.0 - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.10.6...1.11.0) Updates `insta` from 1.39.0 to 1.40.0 - [Release notes](https://github.com/mitsuhiko/insta/releases) - [Changelog](https://github.com/mitsuhiko/insta/blob/master/CHANGELOG.md) - [Commits](https://github.com/mitsuhiko/insta/compare/1.39.0...1.40.0) Updates `serde_json` from 1.0.122 to 1.0.128 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.122...1.0.128) Updates `tempfile` from 3.11.0 to 3.13.0 - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.11.0...v3.13.0) Updates `prost` from 0.13.1 to 0.13.3 - [Release notes](https://github.com/tokio-rs/prost/releases) - [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/prost/compare/v0.13.1...v0.13.3) Updates `tonic` from 0.12.1 to 0.12.3 - [Release notes](https://github.com/hyperium/tonic/releases) - [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/tonic/compare/v0.12.1...v0.12.3) Updates `tonic-build` from 0.12.1 to 0.12.3 - [Release notes](https://github.com/hyperium/tonic/releases) - [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/tonic/compare/v0.12.1...v0.12.3) Updates `primitive-types` from 0.12.2 to 0.13.1 - [Commits](https://github.com/paritytech/parity-common/commits/primitive-types-v0.13.1) Updates `uint` from 0.9.5 to 0.10.0 - [Commits](https://github.com/paritytech/parity-common/compare/uint-v0.9.5...uint-v0.10.0) Updates `tokio-util` from 0.7.11 to 0.7.12 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.11...tokio-util-0.7.12) Updates `rlimit` from 0.10.1 to 0.10.2 - [Changelog](https://github.com/Nugine/rlimit/blob/main/CHANGELOG.md) - [Commits](https://github.com/Nugine/rlimit/compare/v0.10.1...v0.10.2) Updates `tonic-reflection` from 0.12.1 to 0.12.3 - [Release notes](https://github.com/hyperium/tonic/releases) - [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/tonic/compare/v0.12.1...v0.12.3) Updates `owo-colors` from 4.0.0 to 4.1.0 - [Commits](https://github.com/jam1garner/owo-colors/compare/v4.0.0...v4.1.0) Updates `syn` from 2.0.72 to 2.0.79 - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/2.0.72...2.0.79) Updates `quote` from 1.0.36 to 1.0.37 - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.36...1.0.37) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: indexmap dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: tokio-stream dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: tower dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: hyper-util dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: insta dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: prost dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: tonic dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: tonic-build dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: primitive-types dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: uint dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: tokio-util dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: rlimit dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: tonic-reflection dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: owo-colors dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod ... Signed-off-by: dependabot[bot] * downgrade `primitive-types` and `tower` * fix docs and deprecated stuff * cargo vet updates --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alfredo Garcia --- Cargo.lock | 349 +++++++++++++------------ supply-chain/audits.toml | 384 ++++++++++++++++++++++++++++ supply-chain/config.toml | 96 +++---- supply-chain/imports.lock | 391 +++++++++++++++++++++++++---- tower-batch-control/Cargo.toml | 6 +- tower-fallback/Cargo.toml | 2 +- zebra-chain/Cargo.toml | 14 +- zebra-chain/src/work/difficulty.rs | 5 +- zebra-chain/src/work/u256.rs | 1 + zebra-consensus/Cargo.toml | 8 +- zebra-grpc/Cargo.toml | 16 +- zebra-grpc/build.rs | 2 +- zebra-grpc/src/server.rs | 2 +- zebra-network/Cargo.toml | 20 +- zebra-node-services/Cargo.toml | 10 +- zebra-rpc/Cargo.toml | 24 +- zebra-rpc/build.rs | 2 +- zebra-rpc/src/indexer/server.rs | 2 +- zebra-scan/Cargo.toml | 16 +- zebra-script/Cargo.toml | 2 +- zebra-state/Cargo.toml | 20 +- zebra-test/Cargo.toml | 14 +- zebra-utils/Cargo.toml | 16 +- zebrad/Cargo.toml | 34 +-- zebrad/build.rs | 2 +- 25 files changed, 1048 insertions(+), 390 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22f5d505038..72541a4a72c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ "arc-swap", "backtrace", "canonical-path", - "clap 4.5.13", + "clap 4.5.18", "color-eyre", "fs-err", "once_cell", @@ -152,9 +152,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -240,7 +240,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -251,7 +251,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -424,7 +424,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.72", + "syn 2.0.79", "which", ] @@ -592,9 +592,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bzip2-sys" @@ -732,7 +732,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -801,9 +801,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -811,9 +811,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -823,14 +823,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -980,7 +980,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.13", + "clap 4.5.18", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1082,7 +1082,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1130,7 +1130,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1152,7 +1152,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core 0.20.9", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1374,9 +1374,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "ff" @@ -1536,7 +1536,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1637,8 +1637,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -1665,10 +1665,10 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.3.0", + "indexmap 2.5.0", "slab", "tokio", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tracing", ] @@ -1684,10 +1684,10 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.3.0", + "indexmap 2.5.0", "slab", "tokio", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tracing", ] @@ -1716,7 +1716,7 @@ dependencies = [ "pasta_curves", "rand 0.8.5", "subtle", - "uint", + "uint 0.9.5", ] [[package]] @@ -2019,9 +2019,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -2032,7 +2032,6 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -2124,9 +2123,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -2174,9 +2173,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" dependencies = [ "console", "lazy_static", @@ -2383,9 +2382,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libgit2-sys" @@ -2406,7 +2405,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if 1.0.0", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2566,7 +2565,7 @@ dependencies = [ "http-body-util", "hyper 1.4.1", "hyper-util", - "indexmap 2.3.0", + "indexmap 2.5.0", "ipnet", "metrics", "metrics-util", @@ -2863,9 +2862,9 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "owo-colors" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "pairing" @@ -2947,7 +2946,7 @@ dependencies = [ "libc", "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -3002,7 +3001,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -3023,7 +3022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.3.0", + "indexmap 2.5.0", ] [[package]] @@ -3043,7 +3042,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -3138,7 +3137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -3149,7 +3148,7 @@ checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", - "uint", + "uint 0.9.5", ] [[package]] @@ -3217,7 +3216,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", @@ -3231,14 +3230,14 @@ checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "prost" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes", "prost-derive", @@ -3261,21 +3260,21 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.72", + "syn 2.0.79", "tempfile", ] [[package]] name = "prost-derive" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ "anyhow", "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -3342,9 +3341,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -3526,14 +3525,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -3547,13 +3546,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -3564,9 +3563,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -3601,7 +3600,7 @@ dependencies = [ "system-configuration", "tokio", "tokio-rustls", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tower-service", "url", "wasm-bindgen", @@ -3646,9 +3645,9 @@ dependencies = [ [[package]] name = "rlimit" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3560f70f30a0f16d11d01ed078a07740fe6b489667abc7c7b029155d9f21c3d8" +checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" dependencies = [ "libc", ] @@ -3712,9 +3711,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -3985,9 +3984,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -4003,22 +4002,22 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -4066,7 +4065,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.3.0", + "indexmap 2.5.0", "serde", "serde_derive", "serde_json", @@ -4095,7 +4094,7 @@ dependencies = [ "darling 0.20.9", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -4104,7 +4103,7 @@ version = "0.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.5.0", "itoa", "libyml", "memchr", @@ -4320,9 +4319,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -4382,15 +4381,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.11.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if 1.0.0", "fastrand", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4413,22 +4412,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -4515,9 +4514,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -4540,7 +4539,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -4555,14 +4554,14 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util 0.7.11", + "tokio-util 0.7.12", ] [[package]] @@ -4594,9 +4593,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -4641,7 +4640,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.5.0", "toml_datetime", "winnow 0.5.40", ] @@ -4652,7 +4651,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -4661,9 +4660,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38659f4a91aba8598d27821589f5db7dddd94601e7a01b1e485a50e5484c7401" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", @@ -4691,22 +4690,23 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568392c5a2bd0020723e3f387891176aabafe36fd9fcd074ad309dfa0c8eb964" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" dependencies = [ "prettyplease", "proc-macro2", "prost-build", + "prost-types", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "tonic-reflection" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b742c83ad673e9ab5b4ce0981f7b9e8932be9d60e8682cbf9120494764dbc173" +checksum = "878d81f52e7fcfd80026b7fdb6a9b578b3c3653ba987f87f0dce4b64043cba27" dependencies = [ "prost", "prost-types", @@ -4730,7 +4730,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tower-layer", "tower-service", "tracing", @@ -4750,7 +4750,7 @@ dependencies = [ "tinyvec", "tokio", "tokio-test", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tower", "tower-fallback", "tower-test", @@ -4773,15 +4773,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tower-test" @@ -4829,7 +4829,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -4942,7 +4942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -4975,6 +4975,18 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "uint" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "uname" version = "0.1.1" @@ -5144,7 +5156,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -5264,7 +5276,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -5298,7 +5310,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5375,7 +5387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5384,7 +5396,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5402,7 +5414,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "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]] @@ -5422,18 +5443,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5444,9 +5465,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5456,9 +5477,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5468,15 +5489,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5486,9 +5507,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5498,9 +5519,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5510,9 +5531,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5522,9 +5543,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -6026,7 +6047,7 @@ dependencies = [ "tinyvec", "tokio", "tracing", - "uint", + "uint 0.10.0", "x25519-dalek", "zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_client_backend 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6119,7 +6140,7 @@ dependencies = [ "hex", "howudoin", "humantime-serde", - "indexmap 2.3.0", + "indexmap 2.5.0", "itertools 0.13.0", "lazy_static", "metrics", @@ -6137,7 +6158,7 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "toml 0.8.19", "tower", "tracing", @@ -6167,7 +6188,7 @@ dependencies = [ "chrono", "futures", "hex", - "indexmap 2.3.0", + "indexmap 2.5.0", "insta", "jsonrpc-core", "jsonrpc-derive", @@ -6208,7 +6229,7 @@ dependencies = [ "futures", "group", "hex", - "indexmap 2.3.0", + "indexmap 2.5.0", "insta", "itertools 0.13.0", "jsonrpc", @@ -6271,7 +6292,7 @@ dependencies = [ "howudoin", "human_bytes", "humantime-serde", - "indexmap 2.3.0", + "indexmap 2.5.0", "insta", "itertools 0.13.0", "jubjub", @@ -6308,12 +6329,12 @@ dependencies = [ "futures", "hex", "humantime", - "indexmap 2.3.0", + "indexmap 2.5.0", "insta", "itertools 0.13.0", "lazy_static", "once_cell", - "owo-colors 4.0.0", + "owo-colors 4.1.0", "proptest", "rand 0.8.5", "regex", @@ -6334,7 +6355,7 @@ version = "1.0.0-beta.39" dependencies = [ "color-eyre", "hex", - "indexmap 2.3.0", + "indexmap 2.5.0", "itertools 0.13.0", "jsonrpc", "quote", @@ -6345,7 +6366,7 @@ dependencies = [ "serde_json", "serde_yml", "structopt", - "syn 2.0.72", + "syn 2.0.79", "thiserror", "tinyvec", "tokio", @@ -6367,7 +6388,7 @@ dependencies = [ "atty", "bytes", "chrono", - "clap 4.5.13", + "clap 4.5.18", "color-eyre", "console-subscriber", "dirs", @@ -6379,7 +6400,7 @@ dependencies = [ "humantime-serde", "hyper 1.4.1", "hyper-util", - "indexmap 2.3.0", + "indexmap 2.5.0", "indicatif", "inferno", "insta", @@ -6448,7 +6469,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -6468,7 +6489,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index fd2e76233c1..963d1771ca3 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1,6 +1,11 @@ # cargo-vet audits file +[[audits.anstyle]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.7 -> 1.0.8" + [[audits.axum]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -11,6 +16,21 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.3.4 -> 0.4.3" +[[audits.bip32]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.5.1 -> 0.5.2" + +[[audits.bridgetree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.5.0" + +[[audits.bytemuck]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.16.3 -> 1.16.1" + [[audits.bytes]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -21,6 +41,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.6.1 -> 1.7.1" +[[audits.cfg_aliases]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +version = "0.1.1" + [[audits.clap_derive]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -66,6 +91,18 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.3.0 -> 0.4.0" +[[audits.equihash]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.0 -> 0.2.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.f4jumble]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.1.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + [[audits.git2]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -81,11 +118,26 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.3.1 -> 1.4.1" +[[audits.hyper-util]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.6 -> 0.1.9" + +[[audits.incrementalmerkletree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.5.1 -> 0.6.0" + [[audits.indexmap]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "2.2.6 -> 2.3.0" +[[audits.indexmap]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "2.3.0 -> 2.5.0" + [[audits.inferno]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -96,11 +148,26 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.11.20 -> 0.11.21" +[[audits.insta]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.39.0 -> 1.40.0" + +[[audits.libc]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.155 -> 0.2.159" + [[audits.libgit2-sys]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.16.2+1.7.2 -> 0.17.0+1.8.1" +[[audits.libyml]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +version = "0.0.5" + [[audits.log]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -131,6 +198,21 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.8.11 -> 1.0.1" +[[audits.nix]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +version = "0.15.0" + +[[audits.orchard]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.8.0 -> 0.9.0" + +[[audits.owo-colors]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "4.0.0 -> 4.1.0" + [[audits.proptest-derive]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -141,6 +223,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.12.6 -> 0.13.1" +[[audits.prost]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.13.1 -> 0.13.3" + [[audits.prost-build]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -151,6 +238,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.12.6 -> 0.13.1" +[[audits.prost-derive]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.13.1 -> 0.13.3" + [[audits.prost-types]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -161,6 +253,36 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.10.5 -> 1.10.6" +[[audits.regex]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.10.6 -> 1.11.0" + +[[audits.regex-automata]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.4.7 -> 0.4.8" + +[[audits.regex-syntax]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.8.4 -> 0.8.5" + +[[audits.rlimit]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.10.1 -> 0.10.2" + +[[audits.rustix]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.38.34 -> 0.38.37" + +[[audits.sapling-crypto]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.3 -> 0.2.0" + [[audits.serde_spanned]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -186,21 +308,46 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "3.8.3 -> 3.9.0" +[[audits.serde_yml]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +version = "0.0.12" + +[[audits.shardtree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.1 -> 0.4.0" + [[audits.tempfile]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "3.10.1 -> 3.11.0" +[[audits.tempfile]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "3.11.0 -> 3.13.0" + [[audits.thiserror]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.0.61 -> 1.0.62" +[[audits.thiserror]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.63 -> 1.0.64" + [[audits.thiserror-impl]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "1.0.63 -> 1.0.62" +[[audits.thiserror-impl]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.63 -> 1.0.64" + [[audits.tokio]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -216,6 +363,16 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "2.3.0 -> 2.4.0" +[[audits.tokio-stream]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.15 -> 0.1.16" + +[[audits.tokio-util]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.7.11 -> 0.7.12" + [[audits.toml]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -261,6 +418,16 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.11.0 -> 0.12.0" +[[audits.tonic]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.12.1 -> 0.12.3" + +[[audits.tonic-build]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.12.1 -> 0.12.3" + [[audits.tonic-reflection]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -271,16 +438,233 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.12.0 -> 0.12.1" +[[audits.tonic-reflection]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.12.1 -> 0.12.3" + +[[audits.tower-batch-control]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.41-beta.14 -> 0.2.41-beta.15" + +[[audits.tower-fallback]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.41-beta.14 -> 0.2.41-beta.15" + +[[audits.tower-layer]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.2 -> 0.3.3" + +[[audits.tower-service]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.2 -> 0.3.3" + +[[audits.uint]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.9.5 -> 0.10.0" + [[audits.vergen]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "8.3.1 -> 8.3.2" +[[audits.version_check]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.9.4 -> 0.9.5" + +[[audits.windows-sys]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.0 -> 0.59.0" + +[[audits.windows-targets]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_aarch64_gnullvm]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_aarch64_msvc]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_i686_gnu]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_i686_gnullvm]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_i686_msvc]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_x86_64_gnu]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_x86_64_gnullvm]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + +[[audits.windows_x86_64_msvc]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.52.5 -> 0.52.6" + [[audits.winnow]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.6.13 -> 0.6.18" +[[audits.zcash_address]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.5.0" + +[[audits.zcash_address]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.5.0 -> 0.5.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.zcash_client_backend]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.12.1 -> 0.13.0" + +[[audits.zcash_client_backend]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.13.0 -> 0.13.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.zcash_encoding]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.1 -> 0.2.1@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.zcash_keys]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.3.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.zcash_primitives]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.16.0 -> 0.17.0" + +[[audits.zcash_primitives]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.17.0 -> 0.17.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.zcash_proofs]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.16.0 -> 0.17.0" + +[[audits.zcash_protocol]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.1 -> 0.2.0" + +[[audits.zcash_protocol]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.1 -> 0.3.0" + +[[audits.zcash_protocol]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.3.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + +[[audits.zebra-chain]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-consensus]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-grpc]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.0-alpha.5 -> 0.1.0-alpha.6" + +[[audits.zebra-network]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-node-services]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-rpc]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-script]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-state]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-test]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebra-utils]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.0.0-beta.38 -> 1.0.0-beta.39" + +[[audits.zebrad]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "1.8.0 -> 1.9.0" + +[[audits.zip321]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +version = "0.1.0" + +[[audits.zip321]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.1.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +importable = false + [[trusted.clap]] criteria = "safe-to-deploy" user-id = 6743 # Ed Page (epage) diff --git a/supply-chain/config.toml b/supply-chain/config.toml index 21bfeebddba..7a20193f958 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -1,3 +1,4 @@ + # cargo-vet config file [cargo-vet] @@ -15,12 +16,36 @@ url = "https://raw.githubusercontent.com/zcash/rust-ecosystem/main/supply-chain/ [imports.zcashd] url = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" +[policy.equihash] +audit-as-crates-io = true + +[policy.f4jumble] +audit-as-crates-io = true + [policy.tower-batch-control] audit-as-crates-io = true [policy.tower-fallback] audit-as-crates-io = true +[policy.zcash_address] +audit-as-crates-io = true + +[policy.zcash_client_backend] +audit-as-crates-io = true + +[policy.zcash_encoding] +audit-as-crates-io = true + +[policy.zcash_keys] +audit-as-crates-io = true + +[policy.zcash_primitives] +audit-as-crates-io = true + +[policy.zcash_protocol] +audit-as-crates-io = true + [policy.zebra-chain] audit-as-crates-io = true @@ -57,6 +82,9 @@ audit-as-crates-io = true [policy.zebrad] audit-as-crates-io = true +[policy.zip321] +audit-as-crates-io = true + [[exemptions.abscissa_core]] version = "0.7.0" criteria = "safe-to-deploy" @@ -69,10 +97,6 @@ criteria = "safe-to-deploy" version = "0.21.0" criteria = "safe-to-deploy" -[[exemptions.adler]] -version = "1.0.2" -criteria = "safe-to-deploy" - [[exemptions.aead]] version = "0.5.2" criteria = "safe-to-deploy" @@ -89,10 +113,6 @@ criteria = "safe-to-deploy" version = "1.1.3" criteria = "safe-to-deploy" -[[exemptions.allocator-api2]] -version = "0.2.18" -criteria = "safe-to-deploy" - [[exemptions.android-tzdata]] version = "0.1.1" criteria = "safe-to-deploy" @@ -197,14 +217,6 @@ criteria = "safe-to-deploy" version = "1.3.3" criteria = "safe-to-deploy" -[[exemptions.bip0039]] -version = "0.10.1" -criteria = "safe-to-deploy" - -[[exemptions.bitflags]] -version = "1.3.2" -criteria = "safe-to-deploy" - [[exemptions.bitflags-serde-legacy]] version = "0.1.1" criteria = "safe-to-deploy" @@ -249,10 +261,6 @@ criteria = "safe-to-deploy" version = "1.2.2" criteria = "safe-to-deploy" -[[exemptions.byteorder]] -version = "1.5.0" -criteria = "safe-to-deploy" - [[exemptions.bytes]] version = "1.6.0" criteria = "safe-to-deploy" @@ -369,10 +377,6 @@ criteria = "safe-to-deploy" version = "0.2.12" criteria = "safe-to-deploy" -[[exemptions.crc32fast]] -version = "1.4.2" -criteria = "safe-to-deploy" - [[exemptions.criterion]] version = "0.5.1" criteria = "safe-to-run" @@ -513,10 +517,6 @@ criteria = "safe-to-deploy" version = "0.4.2" criteria = "safe-to-deploy" -[[exemptions.flate2]] -version = "1.0.30" -criteria = "safe-to-deploy" - [[exemptions.flume]] version = "0.10.14" criteria = "safe-to-deploy" @@ -621,10 +621,6 @@ criteria = "safe-to-deploy" version = "7.5.4" criteria = "safe-to-deploy" -[[exemptions.hdwallet]] -version = "0.4.1" -criteria = "safe-to-deploy" - [[exemptions.heck]] version = "0.3.3" criteria = "safe-to-deploy" @@ -905,10 +901,6 @@ criteria = "safe-to-deploy" version = "0.2.1" criteria = "safe-to-deploy" -[[exemptions.miniz_oxide]] -version = "0.7.4" -criteria = "safe-to-deploy" - [[exemptions.mio]] version = "0.8.11" criteria = "safe-to-deploy" @@ -1033,18 +1025,10 @@ criteria = "safe-to-deploy" version = "0.9.10" criteria = "safe-to-deploy" -[[exemptions.password-hash]] -version = "0.3.2" -criteria = "safe-to-deploy" - [[exemptions.pasta_curves]] version = "0.5.1" criteria = "safe-to-deploy" -[[exemptions.pbkdf2]] -version = "0.10.1" -criteria = "safe-to-deploy" - [[exemptions.percent-encoding]] version = "2.3.1" criteria = "safe-to-deploy" @@ -1265,10 +1249,6 @@ criteria = "safe-to-deploy" version = "0.8.37" criteria = "safe-to-deploy" -[[exemptions.ring]] -version = "0.16.20" -criteria = "safe-to-deploy" - [[exemptions.ring]] version = "0.17.8" criteria = "safe-to-deploy" @@ -1461,10 +1441,6 @@ criteria = "safe-to-deploy" version = "0.1.1" criteria = "safe-to-deploy" -[[exemptions.spin]] -version = "0.5.2" -criteria = "safe-to-deploy" - [[exemptions.spin]] version = "0.9.8" criteria = "safe-to-deploy" @@ -1481,10 +1457,6 @@ criteria = "safe-to-deploy" version = "0.8.0" criteria = "safe-to-deploy" -[[exemptions.strsim]] -version = "0.11.1" -criteria = "safe-to-deploy" - [[exemptions.structopt]] version = "0.3.26" criteria = "safe-to-deploy" @@ -1633,10 +1605,6 @@ criteria = "safe-to-deploy" version = "0.1.27" criteria = "safe-to-deploy" -[[exemptions.tracing-core]] -version = "0.1.32" -criteria = "safe-to-deploy" - [[exemptions.tracing-error]] version = "0.2.0" criteria = "safe-to-deploy" @@ -1713,14 +1681,6 @@ criteria = "safe-to-deploy" version = "0.5.1" criteria = "safe-to-deploy" -[[exemptions.unsafe-libyaml]] -version = "0.2.11" -criteria = "safe-to-deploy" - -[[exemptions.untrusted]] -version = "0.7.1" -criteria = "safe-to-deploy" - [[exemptions.untrusted]] version = "0.9.0" criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index b9dd505d67b..b855130e47d 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1,6 +1,10 @@ # cargo-vet imports lock +[[unpublished.zebra-scan]] +version = "0.1.0-alpha.8" +audited_as = "0.1.0-alpha.7" + [[publisher.cexpr]] version = "0.6.0" when = "2021-10-11" @@ -9,22 +13,22 @@ user-login = "emilio" user-name = "Emilio Cobos Álvarez" [[publisher.clap]] -version = "4.5.13" -when = "2024-07-31" +version = "4.5.18" +when = "2024-09-20" user-id = 6743 user-login = "epage" user-name = "Ed Page" [[publisher.clap_builder]] -version = "4.5.13" -when = "2024-07-31" +version = "4.5.18" +when = "2024-09-20" user-id = 6743 user-login = "epage" user-name = "Ed Page" [[publisher.clap_derive]] -version = "4.5.13" -when = "2024-07-31" +version = "4.5.18" +when = "2024-09-20" user-id = 6743 user-login = "epage" user-name = "Ed Page" @@ -44,8 +48,8 @@ user-login = "hsivonen" user-name = "Henri Sivonen" [[publisher.serde_json]] -version = "1.0.122" -when = "2024-08-01" +version = "1.0.128" +when = "2024-09-04" user-id = 3618 user-login = "dtolnay" user-name = "David Tolnay" @@ -58,15 +62,15 @@ user-login = "dtolnay" user-name = "David Tolnay" [[publisher.syn]] -version = "2.0.72" -when = "2024-07-21" +version = "2.0.79" +when = "2024-09-27" user-id = 3618 user-login = "dtolnay" user-name = "David Tolnay" [[publisher.tokio]] -version = "1.39.2" -when = "2024-07-27" +version = "1.40.0" +when = "2024-08-30" user-id = 6741 user-login = "Darksonn" user-name = "Alice Ryhl" @@ -85,6 +89,19 @@ user-id = 1139 user-login = "Manishearth" user-name = "Manish Goregaokar" +[[audits.google.audits.adler]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.2" +notes = ''' +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'`, `'\bunsafe\b'` +and there were no hits (except in comments and in the `README.md` file). + +Note that some additional, internal notes about an older version of this crate +can be found at go/image-crate-chromium-security-review. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.async-stream]] who = "Tyler Mandry " criteria = "safe-to-deploy" @@ -146,6 +163,22 @@ version = "0.13.1" notes = "Skimmed the uses of `std` to ensure that nothing untoward is happening. Code uses `forbid(unsafe_code)` and, indeed, there are no uses of `unsafe`" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" +[[audits.google.audits.bitflags]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.3.2" +notes = """ +Security review of earlier versions of the crate can be found at +(Google-internal, sorry): go/image-crate-chromium-security-review + +The crate exposes a function marked as `unsafe`, but doesn't use any +`unsafe` blocks (except for tests of the single `unsafe` function). I +think this justifies marking this crate as `ub-risk-1`. + +Additional review comments can be found at https://crrev.com/c/4723145/31 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.bitflags]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -179,30 +212,21 @@ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_p [[audits.google.audits.bytemuck]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" -version = "1.14.3" -notes = "Additional review notes may be found in https://crrev.com/c/5362675." -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.bytemuck]] -who = "Adrian Taylor " -criteria = "safe-to-deploy" -delta = "1.14.3 -> 1.15.0" +version = "1.16.3" +notes = """ +Review notes from the original audit (of 1.14.3) may be found in +https://crrev.com/c/5362675. Note that this audit has initially missed UB risk +that was fixed in 1.16.2 - see https://github.com/Lokathor/bytemuck/pull/258. +Because of this, the original audit has been edited to certify version `1.16.3` +instead (see also https://crrev.com/c/5771867). +""" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" -[[audits.google.audits.bytemuck]] +[[audits.google.audits.byteorder]] who = "danakj " criteria = "safe-to-deploy" -delta = "1.15.0 -> 1.16.0" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.bytemuck]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -delta = "1.16.0 -> 1.16.1" -notes = """ -The delta only adds `f16` and `f128` support (with some other minor changes) -and has no impact on the audit criteria. -""" +version = "1.5.0" +notes = "Unsafe review in https://crrev.com/c/5838022" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" [[audits.google.audits.cast]] @@ -217,6 +241,18 @@ criteria = "safe-to-deploy" version = "1.0.0" aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" +[[audits.google.audits.crc32fast]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.4.2" +notes = """ +Security review of earlier versions of the crate can be found at +(Google-internal, sorry): go/image-crate-chromium-security-review + +Audit comments for 1.4.2 can be found at https://crrev.com/c/4723145. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.equivalent]] who = "George Burgess IV " criteria = "safe-to-deploy" @@ -233,6 +269,41 @@ that the RNG here is not cryptographically secure. """ aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" +[[audits.google.audits.flate2]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.30" +notes = ''' +WARNING: This certification is a result of a **partial** audit. The +`any_zlib` code has **not** been audited. Ability to track partial +audits is tracked in https://github.com/mozilla/cargo-vet/issues/380 +Chromium does use the `any_zlib` feature(s). Accidentally depending on +this feature in the future is prevented using the `ban_features` feature +of `gnrt` - see: +https://crrev.com/c/4723145/31/third_party/rust/chromium_crates_io/gnrt_config.toml + +Security review of earlier versions of the crate can be found at +(Google-internal, sorry): go/image-crate-chromium-security-review + +I grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'`, `'\bunsafe\b'`. + +All `unsafe` in `flate2` is gated behind `#[cfg(feature = "any_zlib")]`: + +* The code under `src/ffi/...` will not be used because the `mod c` + declaration in `src/ffi/mod.rs` depends on the `any_zlib` config +* 7 uses of `unsafe` in `src/mem.rs` also all depend on the + `any_zlib` config: + - 2 in `fn set_dictionary` (under `impl Compress`) + - 2 in `fn set_level` (under `impl Compress`) + - 3 in `fn set_dictionary` (under `impl Decompress`) + +All hits of `'\bfs\b'` are in comments, or example code, or test code +(but not in product code). + +There were no hits of `-i cipher`, `-i crypto`, `'\bnet\b'`. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.futures]] who = "George Burgess IV " criteria = "safe-to-deploy" @@ -311,6 +382,22 @@ delta = "1.4.0 -> 1.5.0" notes = "Unsafe review notes: https://crrev.com/c/5650836" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" +[[audits.google.audits.miniz_oxide]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.7.4" +notes = ''' +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'`, `'\bunsafe\b'` +and there were no hits, except for some mentions of "unsafe" in the `README.md` +and in a comment in `src/deflate/core.rs`. The comment discusses whether a +function should be treated as unsafe, but there is no actual `unsafe` code, so +the crate meets the `ub-risk-0` criteria. + +Note that some additional, internal notes about an older version of this crate +can be found at go/image-crate-chromium-security-review. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.nom]] who = "danakj@chromium.org" criteria = "safe-to-deploy" @@ -432,6 +519,16 @@ criteria = "safe-to-deploy" delta = "1.0.35 -> 1.0.36" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" +[[audits.google.audits.quote]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.36 -> 1.0.37" +notes = """ +The delta just 1) inlines/expands `impl ToTokens` that used to be handled via +`primitive!` macro and 2) adds `impl ToTokens` for `CStr` and `CString`. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.rustversion]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -541,6 +638,32 @@ criteria = "safe-to-deploy" delta = "1.0.203 -> 1.0.204" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.204 -> 1.0.207" +notes = "The small change in `src/private/ser.rs` should have no impact on `ub-risk-2`." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.207 -> 1.0.209" +notes = """ +The delta carries fairly small changes in `src/private/de.rs` and +`src/private/ser.rs` (see https://crrev.com/c/5812194/2..5). AFAICT the +delta has no impact on the `unsafe`, `from_utf8_unchecked`-related parts +of the crate (in `src/de/format.rs` and `src/ser/impls.rs`). +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.209 -> 1.0.210" +notes = "Almost no new code - just feature rearrangement" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.serde_derive]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -573,6 +696,32 @@ criteria = "safe-to-deploy" delta = "1.0.203 -> 1.0.204" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.204 -> 1.0.207" +notes = 'Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.207 -> 1.0.209" +notes = ''' +There are no code changes in this delta - see https://crrev.com/c/5812194/2..5 + +I've neverthless also grepped for `-i cipher`, `-i crypto`, `\bfs\b`, +`\bnet\b`, and `\bunsafe\b`. There were no hits. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.209 -> 1.0.210" +notes = "Almost no new code - just feature rearrangement" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + [[audits.google.audits.static_assertions]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -746,6 +895,12 @@ end = "2024-05-03" notes = "All code written or reviewed by Manish" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.allocator-api2]] +who = "Nicolas Silva " +criteria = "safe-to-deploy" +version = "0.2.18" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.android_system_properties]] who = "Nicolas Silva " criteria = "safe-to-deploy" @@ -834,6 +989,13 @@ version = "0.6.3" notes = "Another crate I own via contain-rs that is ancient and in maintenance mode but otherwise perfectly fine." aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.cfg_aliases]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "0.1.1 -> 0.2.1" +notes = "Very minor changes." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.core-foundation]] who = "Teodor Tanasoaia " criteria = "safe-to-deploy" @@ -871,6 +1033,12 @@ criteria = "safe-to-deploy" delta = "1.9.0 -> 2.0.0" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.fastrand]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "2.0.1 -> 2.1.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.fnv]] who = "Bobby Holley " criteria = "safe-to-deploy" @@ -943,6 +1111,47 @@ delta = "0.4.18 -> 0.4.20" notes = "Only cfg attribute and internal macro changes and module refactorings" aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" +[[audits.mozilla.audits.nix]] +who = "Gabriele Svelto " +criteria = "safe-to-deploy" +delta = "0.15.0 -> 0.25.0" +notes = "Plenty of new bindings but also several important bug fixes (including buffer overflows). New unsafe sections are restricted to wrappers and are no more dangerous than calling the C functions." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.nix]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.25.0 -> 0.25.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.nix]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.25.1 -> 0.26.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.nix]] +who = "Gabriele Svelto " +criteria = "safe-to-deploy" +delta = "0.26.2 -> 0.27.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.nix]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "0.27.1 -> 0.28.0" +notes = """ +Many new features and bugfixes. Obviously there's a lot of unsafe code calling +libc, but the usage looks correct. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.nix]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "0.28.0 -> 0.29.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.num-conv]] who = "Alex Franchuk " criteria = "safe-to-deploy" @@ -970,6 +1179,12 @@ version = "1.1.0" notes = "Straightforward crate with no unsafe code, does what it says on the tin." aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.strsim]] +who = "Ben Dean-Kawamura " +criteria = "safe-to-deploy" +delta = "0.10.0 -> 0.11.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.synstructure]] who = "Nika Layzell " criteria = "safe-to-deploy" @@ -1017,6 +1232,17 @@ criteria = "safe-to-deploy" delta = "0.2.10 -> 0.2.18" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.tracing-core]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.1.30" +notes = """ +Most unsafe code is in implementing non-std sync primitives. Unsafe impls are +logically correct and justified in comments, and unsafe code is sound and +justified in comments. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.zerocopy]] who = "Alex Franchuk " criteria = "safe-to-deploy" @@ -1043,32 +1269,33 @@ criteria = "safe-to-deploy" delta = "1.2.0 -> 1.3.0" aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" -[[audits.zcash.audits.fastrand]] +[[audits.zcash.audits.bip32]] who = "Jack Grigg " criteria = "safe-to-deploy" -delta = "2.0.0 -> 2.0.1" +version = "0.5.1" +notes = """ +- Crate has no unsafe code, and sets `#![forbid(unsafe_code)]`. +- Crate has no powerful imports. Only filesystem acces is via `include_str!`, and is safe. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.bytes]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.7.1 -> 1.7.2" aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" [[audits.zcash.audits.fastrand]] -who = "Daira-Emma Hopwood " +who = "Jack Grigg " criteria = "safe-to-deploy" -delta = "2.0.1 -> 2.0.2" +delta = "2.0.0 -> 2.0.1" aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" [[audits.zcash.audits.fastrand]] -who = "Daira-Emma Hopwood " +who = "Jack Grigg " criteria = "safe-to-deploy" -delta = "2.0.2 -> 2.1.0" -notes = """ -As noted in the changelog, this version produces different output for a given seed. -The documentation did not mention stability. It is possible that some uses relying on -determinism across the update would be broken. - -The new constants do appear to match WyRand v4.2 (modulo ordering issues that I have not checked): -https://github.com/wangyi-fudan/wyhash/blob/408620b6d12b7d667b3dd6ae39b7929a39e8fa05/wyhash.h#L145 -I have no way to check whether these constants are an improvement or not. -""" -aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" +delta = "2.1.0 -> 2.1.1" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" [[audits.zcash.audits.futures]] who = "Jack Grigg " @@ -1190,6 +1417,12 @@ be set correctly by `cargo`. """ aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" +[[audits.zcash.audits.secp256k1]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.26.0 -> 0.27.0" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + [[audits.zcash.audits.signature]] who = "Daira Emma Hopwood " criteria = "safe-to-deploy" @@ -1268,6 +1501,34 @@ criteria = "safe-to-deploy" delta = "0.12.0 -> 0.12.1" aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" +[[audits.zcash.audits.tracing-core]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.30 -> 0.1.31" +notes = """ +The only new `unsafe` block is to intentionally leak a scoped subscriber onto +the heap when setting it as the global default dispatcher. I checked that the +global default can only be set once and is never dropped. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.tracing-core]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.31 -> 0.1.32" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.visibility]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +version = "0.1.1" +notes = """ +- Crate has no unsafe code, and sets `#![forbid(unsafe_code)]`. +- Crate has no powerful imports, and exclusively provides a proc macro + that safely malleates a visibility modifier. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + [[audits.zcash.audits.wagyu-zcash-parameters]] who = "Sean Bowe " criteria = "safe-to-deploy" @@ -1316,6 +1577,40 @@ criteria = "safe-to-deploy" version = "0.2.92" aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" +[[audits.zcash.audits.zcash_address]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +delta = "0.3.2 -> 0.4.0" +notes = "This release contains no unsafe code and consists soley of added convenience methods." +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.zcash_encoding]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +delta = "0.2.0 -> 0.2.1" +notes = "This release adds minor convenience methods and involves no unsafe code." +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.zcash_keys]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +delta = "0.2.0 -> 0.3.0" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.zcash_primitives]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +delta = "0.15.1 -> 0.16.0" +notes = "The primary change here is the switch from the `hdwallet` dependency to using `bip32`." +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.zcash_proofs]] +who = "Kris Nuttycombe " +criteria = "safe-to-deploy" +delta = "0.15.0 -> 0.16.0" +notes = "This release involves only updates of previously-vetted dependencies." +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + [[audits.zcash.audits.zerocopy]] who = "Daira-Emma Hopwood " criteria = "safe-to-deploy" diff --git a/tower-batch-control/Cargo.toml b/tower-batch-control/Cargo.toml index bbb5e7a4e6d..09b959fb5ed 100644 --- a/tower-batch-control/Cargo.toml +++ b/tower-batch-control/Cargo.toml @@ -26,8 +26,8 @@ futures = "0.3.30" futures-core = "0.3.28" pin-project = "1.1.5" rayon = "1.10.0" -tokio = { version = "1.39.2", features = ["time", "sync", "tracing", "macros"] } -tokio-util = "0.7.11" +tokio = { version = "1.40.0", features = ["time", "sync", "tracing", "macros"] } +tokio-util = "0.7.12" tower = { version = "0.4.13", features = ["util", "buffer"] } tracing = "0.1.39" tracing-futures = "0.2.5" @@ -41,7 +41,7 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } ed25519-zebra = "4.0.3" rand = "0.8.5" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } tokio-test = "0.4.4" tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.15" } tower-test = "0.4.0" diff --git a/tower-fallback/Cargo.toml b/tower-fallback/Cargo.toml index 071753b822b..4ddf8a8401d 100644 --- a/tower-fallback/Cargo.toml +++ b/tower-fallback/Cargo.toml @@ -22,6 +22,6 @@ futures-core = "0.3.28" tracing = "0.1.39" [dev-dependencies] -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index a6ec5c1f342..3e9b998916a 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -81,7 +81,7 @@ group = "0.13.0" incrementalmerkletree.workspace = true jubjub = "0.10.0" lazy_static = "1.4.0" -tempfile = "3.11.0" +tempfile = "3.13.0" dirs = "5.0.1" num-integer = "0.1.46" primitive-types = "0.12.2" @@ -90,7 +90,7 @@ ripemd = "0.1.3" # Matches version used by hdwallet secp256k1 = { version = "0.26.0", features = ["serde"] } sha2 = { version = "0.10.7", features = ["compress"] } -uint = "0.9.5" +uint = "0.10.0" x25519-dalek = { version = "2.0.1", features = ["serde"] } # ECC deps @@ -110,12 +110,12 @@ humantime = "2.1.0" # Error Handling & Formatting static_assertions = "1.1.0" -thiserror = "1.0.63" +thiserror = "1.0.64" tracing = "0.1.39" # Serialization hex = { version = "0.4.3", features = ["serde"] } -serde = { version = "1.0.204", features = ["serde_derive", "rc"] } +serde = { version = "1.0.210", features = ["serde_derive", "rc"] } serde_with = "3.9.0" serde-big-array = "0.5.1" @@ -130,10 +130,10 @@ redjubjub = "0.7.0" reddsa = "0.5.1" # Production feature json-conversion -serde_json = { version = "1.0.122", optional = true } +serde_json = { version = "1.0.128", optional = true } # Production feature async-error and testing feature proptest-impl -tokio = { version = "1.39.2", optional = true } +tokio = { version = "1.40.0", optional = true } # Experimental feature shielded-scan zcash_client_backend = { workspace = true, optional = true } @@ -166,7 +166,7 @@ proptest-derive = "0.5.0" rand = "0.8.5" rand_chacha = "0.3.1" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } diff --git a/zebra-chain/src/work/difficulty.rs b/zebra-chain/src/work/difficulty.rs index 8388cd7fbc5..20fc638453e 100644 --- a/zebra-chain/src/work/difficulty.rs +++ b/zebra-chain/src/work/difficulty.rs @@ -457,10 +457,7 @@ impl ExpandedDifficulty { /// Zebra displays difficulties in big-endian byte-order, /// following the u256 convention set by Bitcoin and zcashd. pub fn bytes_in_display_order(&self) -> [u8; 32] { - let mut reversed_bytes = [0; 32]; - self.0.to_big_endian(&mut reversed_bytes); - - reversed_bytes + self.0.to_big_endian() } /// Convert bytes in big-endian byte-order into an [`ExpandedDifficulty`]. diff --git a/zebra-chain/src/work/u256.rs b/zebra-chain/src/work/u256.rs index 1897f9ecd1c..b9b85dbb278 100644 --- a/zebra-chain/src/work/u256.rs +++ b/zebra-chain/src/work/u256.rs @@ -4,6 +4,7 @@ #![allow(clippy::all)] #![allow(clippy::range_plus_one)] #![allow(clippy::fallible_impl_from)] +#![allow(missing_docs)] use uint::construct_uint; diff --git a/zebra-consensus/Cargo.toml b/zebra-consensus/Cargo.toml index f49041d0ba1..3914087e997 100644 --- a/zebra-consensus/Cargo.toml +++ b/zebra-consensus/Cargo.toml @@ -46,13 +46,13 @@ rayon = "1.10.0" chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } lazy_static = "1.4.0" once_cell = "1.18.0" -serde = { version = "1.0.204", features = ["serde_derive"] } +serde = { version = "1.0.210", features = ["serde_derive"] } futures = "0.3.30" futures-util = "0.3.28" metrics = "0.23.0" -thiserror = "1.0.63" -tokio = { version = "1.39.2", features = ["time", "sync", "tracing", "rt-multi-thread"] } +thiserror = "1.0.64" +tokio = { version = "1.40.0", features = ["time", "sync", "tracing", "rt-multi-thread"] } tower = { version = "0.4.13", features = ["timeout", "util", "buffer"] } tracing = "0.1.39" tracing-futures = "0.2.5" @@ -90,7 +90,7 @@ proptest = "1.4.0" proptest-derive = "0.5.0" spandoc = "0.2.2" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } tracing-error = "0.2.0" tracing-subscriber = "0.3.18" diff --git a/zebra-grpc/Cargo.toml b/zebra-grpc/Cargo.toml index 32e67186242..9cdaadafa2d 100644 --- a/zebra-grpc/Cargo.toml +++ b/zebra-grpc/Cargo.toml @@ -17,12 +17,12 @@ categories = ["cryptography::cryptocurrencies"] [dependencies] futures-util = "0.3.28" -tonic = "0.12.1" -tonic-reflection = "0.12.1" -prost = "0.13.1" -serde = { version = "1.0.204", features = ["serde_derive"] } -tokio = { version = "1.39.2", features = ["macros", "rt-multi-thread"] } -tokio-stream = "0.1.15" +tonic = "0.12.3" +tonic-reflection = "0.12.3" +prost = "0.13.3" +serde = { version = "1.0.210", features = ["serde_derive"] } +tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread"] } +tokio-stream = "0.1.16" tower = { version = "0.4.13", features = ["util", "buffer", "timeout"] } color-eyre = "0.6.3" @@ -32,10 +32,10 @@ zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.3 zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" } [build-dependencies] -tonic-build = "0.12.1" +tonic-build = "0.12.3" [dev-dependencies] -insta = { version = "1.39.0", features = ["redactions", "json", "ron"] } +insta = { version = "1.40.0", features = ["redactions", "json", "ron"] } zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] } zebra-state = { path = "../zebra-state" } diff --git a/zebra-grpc/build.rs b/zebra-grpc/build.rs index 31669063262..f118f59831b 100644 --- a/zebra-grpc/build.rs +++ b/zebra-grpc/build.rs @@ -10,7 +10,7 @@ fn main() -> Result<(), Box> { .protoc_arg("--experimental_allow_proto3_optional") .type_attribute(".", "#[derive(serde::Deserialize, serde::Serialize)]") .file_descriptor_set_path(out_dir.join("scanner_descriptor.bin")) - .compile(&["proto/scanner.proto"], &[""])?; + .compile_protos(&["proto/scanner.proto"], &[""])?; Ok(()) } diff --git a/zebra-grpc/src/server.rs b/zebra-grpc/src/server.rs index d20d9944028..f10421c4ac5 100644 --- a/zebra-grpc/src/server.rs +++ b/zebra-grpc/src/server.rs @@ -459,7 +459,7 @@ where let service = ScannerRPC { scan_service }; let reflection_service = tonic_reflection::server::Builder::configure() .register_encoded_file_descriptor_set(crate::scanner::FILE_DESCRIPTOR_SET) - .build() + .build_v1() .unwrap(); let tcp_listener = tokio::net::TcpListener::bind(listen_addr).await?; diff --git a/zebra-network/Cargo.toml b/zebra-network/Cargo.toml index c207910af87..39cd209c49e 100644 --- a/zebra-network/Cargo.toml +++ b/zebra-network/Cargo.toml @@ -42,12 +42,12 @@ proptest-impl = ["proptest", "proptest-derive", "zebra-chain/proptest-impl"] [dependencies] bitflags = "2.5.0" byteorder = "1.5.0" -bytes = "1.7.1" +bytes = "1.7.2" chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } dirs = "5.0.1" hex = "0.4.3" humantime-serde = "1.1.1" -indexmap = { version = "2.3.0", features = ["serde"] } +indexmap = { version = "2.5.0", features = ["serde"] } itertools = "0.13.0" lazy_static = "1.4.0" num-integer = "0.1.46" @@ -55,15 +55,15 @@ ordered-map = "0.4.2" pin-project = "1.1.5" rand = "0.8.5" rayon = "1.10.0" -regex = "1.10.6" -serde = { version = "1.0.204", features = ["serde_derive"] } -tempfile = "3.11.0" -thiserror = "1.0.63" +regex = "1.11.0" +serde = { version = "1.0.210", features = ["serde_derive"] } +tempfile = "3.13.0" +thiserror = "1.0.64" futures = "0.3.30" -tokio = { version = "1.39.2", features = ["fs", "io-util", "net", "time", "tracing", "macros", "rt-multi-thread"] } -tokio-stream = { version = "0.1.15", features = ["sync", "time"] } -tokio-util = { version = "0.7.11", features = ["codec"] } +tokio = { version = "1.40.0", features = ["fs", "io-util", "net", "time", "tracing", "macros", "rt-multi-thread"] } +tokio-stream = { version = "0.1.16", features = ["sync", "time"] } +tokio-util = { version = "0.7.12", features = ["codec"] } tower = { version = "0.4.13", features = ["retry", "discover", "load", "load-shed", "timeout", "util", "buffer"] } metrics = "0.23.0" @@ -90,7 +90,7 @@ proptest = "1.4.0" proptest-derive = "0.5.0" static_assertions = "1.1.0" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } toml = "0.8.19" zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] } diff --git a/zebra-node-services/Cargo.toml b/zebra-node-services/Cargo.toml index 8d0992dcf5a..e0da107d053 100644 --- a/zebra-node-services/Cargo.toml +++ b/zebra-node-services/Cargo.toml @@ -46,14 +46,14 @@ color-eyre = { version = "0.6.3", optional = true } jsonrpc-core = { version = "18.0.0", optional = true } # Security: avoid default dependency on openssl reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true } -serde = { version = "1.0.204", optional = true } -serde_json = { version = "1.0.122", optional = true } -tokio = { version = "1.39.2", features = ["time", "sync"] } +serde = { version = "1.0.210", optional = true } +serde_json = { version = "1.0.128", optional = true } +tokio = { version = "1.40.0", features = ["time", "sync"] } [dev-dependencies] color-eyre = "0.6.3" jsonrpc-core = "18.0.0" reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"] } -serde = "1.0.204" -serde_json = "1.0.122" +serde = "1.0.210" +serde_json = "1.0.128" diff --git a/zebra-rpc/Cargo.toml b/zebra-rpc/Cargo.toml index babae9123f1..909d9a468f6 100644 --- a/zebra-rpc/Cargo.toml +++ b/zebra-rpc/Cargo.toml @@ -65,10 +65,10 @@ jsonrpc-derive = "18.0.0" jsonrpc-http-server = "18.0.0" # zebra-rpc needs the preserve_order feature in serde_json, which is a dependency of jsonrpc-core -serde_json = { version = "1.0.122", features = ["preserve_order"] } -indexmap = { version = "2.3.0", features = ["serde"] } +serde_json = { version = "1.0.128", features = ["preserve_order"] } +indexmap = { version = "2.5.0", features = ["serde"] } -tokio = { version = "1.39.2", features = [ +tokio = { version = "1.40.0", features = [ "time", "rt-multi-thread", "macros", @@ -77,15 +77,15 @@ tokio = { version = "1.39.2", features = [ tower = "0.4.13" # indexer-rpcs dependencies -tonic = { version = "0.12.1", optional = true } -tonic-reflection = { version = "0.12.1", optional = true } -prost = { version = "0.13.1", optional = true } -tokio-stream = { version = "0.1.15", optional = true } +tonic = { version = "0.12.3", optional = true } +tonic-reflection = { version = "0.12.3", optional = true } +prost = { version = "0.13.3", optional = true } +tokio-stream = { version = "0.1.16", optional = true } tracing = "0.1.39" hex = { version = "0.4.3", features = ["serde"] } -serde = { version = "1.0.204", features = ["serde_derive"] } +serde = { version = "1.0.210", features = ["serde_derive"] } # For the `stop` RPC method. nix = { version = "0.29.0", features = ["signal"] } @@ -112,15 +112,15 @@ zebra-script = { path = "../zebra-script", version = "1.0.0-beta.39" } zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" } [build-dependencies] -tonic-build = { version = "0.12.1", optional = true } +tonic-build = { version = "0.12.3", optional = true } [dev-dependencies] -insta = { version = "1.39.0", features = ["redactions", "json", "ron"] } +insta = { version = "1.40.0", features = ["redactions", "json", "ron"] } proptest = "1.4.0" -thiserror = "1.0.63" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +thiserror = "1.0.64" +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = [ "proptest-impl", diff --git a/zebra-rpc/build.rs b/zebra-rpc/build.rs index 75db7fd2a86..bbb84746f5f 100644 --- a/zebra-rpc/build.rs +++ b/zebra-rpc/build.rs @@ -8,7 +8,7 @@ fn main() -> Result<(), Box> { tonic_build::configure() .type_attribute(".", "#[derive(serde::Deserialize, serde::Serialize)]") .file_descriptor_set_path(out_dir.unwrap().join("indexer_descriptor.bin")) - .compile(&["proto/indexer.proto"], &[""])?; + .compile_protos(&["proto/indexer.proto"], &[""])?; } Ok(()) diff --git a/zebra-rpc/src/indexer/server.rs b/zebra-rpc/src/indexer/server.rs index fcd3a3ac63a..43e82f33c4e 100644 --- a/zebra-rpc/src/indexer/server.rs +++ b/zebra-rpc/src/indexer/server.rs @@ -54,7 +54,7 @@ where let reflection_service = tonic_reflection::server::Builder::configure() .register_encoded_file_descriptor_set(crate::indexer::FILE_DESCRIPTOR_SET) - .build() + .build_v1() .unwrap(); tracing::info!("Trying to open indexer RPC endpoint at {}...", listen_addr,); diff --git a/zebra-scan/Cargo.toml b/zebra-scan/Cargo.toml index 8ef7cae2577..6a5bd10e203 100644 --- a/zebra-scan/Cargo.toml +++ b/zebra-scan/Cargo.toml @@ -61,11 +61,11 @@ results-reader = [ [dependencies] color-eyre = "0.6.3" -indexmap = { version = "2.3.0", features = ["serde"] } +indexmap = { version = "2.5.0", features = ["serde"] } itertools = "0.13.0" semver = "1.0.23" -serde = { version = "1.0.204", features = ["serde_derive"] } -tokio = { version = "1.39.2", features = ["time"] } +serde = { version = "1.0.210", features = ["serde_derive"] } +tokio = { version = "1.40.0", features = ["time"] } tower = "0.4.13" tracing = "0.1.39" futures = "0.3.30" @@ -103,7 +103,7 @@ zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39", optional = tru tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } structopt = "0.3.26" lazy_static = "1.4.0" -serde_json = "1.0.122" +serde_json = "1.0.128" jsonrpc = { version = "0.18.0", optional = true } hex = { version = "0.4.3", optional = true } @@ -111,8 +111,8 @@ hex = { version = "0.4.3", optional = true } zebrad = { path = "../zebrad", version = "1.8.1" } [dev-dependencies] -insta = { version = "1.39.0", features = ["ron", "redactions"] } -tokio = { version = "1.39.2", features = ["test-util"] } +insta = { version = "1.40.0", features = ["ron", "redactions"] } +tokio = { version = "1.40.0", features = ["test-util"] } proptest = "1.4.0" proptest-derive = "0.5.0" @@ -121,10 +121,10 @@ ff = "0.13.0" group = "0.13.0" jubjub = "0.10.0" rand = "0.8.5" -tempfile = "3.11.0" +tempfile = "3.13.0" zcash_note_encryption = "0.4.0" toml = "0.8.19" -tonic = "0.12.1" +tonic = "0.12.3" zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] } zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" } diff --git a/zebra-script/Cargo.toml b/zebra-script/Cargo.toml index c2f8c4ee5f6..095e0ed2950 100644 --- a/zebra-script/Cargo.toml +++ b/zebra-script/Cargo.toml @@ -18,7 +18,7 @@ categories = ["api-bindings", "cryptography::cryptocurrencies"] zcash_script = "0.2.0" zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" } -thiserror = "1.0.63" +thiserror = "1.0.64" [dev-dependencies] hex = "0.4.3" diff --git a/zebra-state/Cargo.toml b/zebra-state/Cargo.toml index db14f448c4b..f1776424b13 100644 --- a/zebra-state/Cargo.toml +++ b/zebra-state/Cargo.toml @@ -54,28 +54,28 @@ hex = "0.4.3" hex-literal = "0.4.1" humantime-serde = "1.1.1" human_bytes = { version = "0.4.3", default-features = false } -indexmap = "2.3.0" +indexmap = "2.5.0" itertools = "0.13.0" lazy_static = "1.4.0" metrics = "0.23.0" mset = "0.1.1" -regex = "1.10.6" -rlimit = "0.10.1" +regex = "1.11.0" +rlimit = "0.10.2" rocksdb = { version = "0.22.0", default-features = false, features = ["lz4"] } semver = "1.0.23" -serde = { version = "1.0.204", features = ["serde_derive"] } -tempfile = "3.11.0" -thiserror = "1.0.63" +serde = { version = "1.0.210", features = ["serde_derive"] } +tempfile = "3.13.0" +thiserror = "1.0.64" rayon = "1.10.0" -tokio = { version = "1.39.2", features = ["rt-multi-thread", "sync", "tracing"] } +tokio = { version = "1.40.0", features = ["rt-multi-thread", "sync", "tracing"] } tower = { version = "0.4.13", features = ["buffer", "util"] } tracing = "0.1.39" # elasticsearch specific dependencies. # Security: avoid default dependency on openssl elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true } -serde_json = { version = "1.0.122", package = "serde_json", optional = true } +serde_json = { version = "1.0.128", package = "serde_json", optional = true } zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["async-error"] } @@ -97,7 +97,7 @@ once_cell = "1.18.0" spandoc = "0.2.2" hex = { version = "0.4.3", features = ["serde"] } -insta = { version = "1.39.0", features = ["ron", "redactions"] } +insta = { version = "1.40.0", features = ["ron", "redactions"] } proptest = "1.4.0" proptest-derive = "0.5.0" @@ -106,7 +106,7 @@ rand = "0.8.5" halo2 = { package = "halo2_proofs", version = "0.3.0" } jubjub = "0.10.0" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] } zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } diff --git a/zebra-test/Cargo.toml b/zebra-test/Cargo.toml index cbbf5ac6b6a..66c2f168284 100644 --- a/zebra-test/Cargo.toml +++ b/zebra-test/Cargo.toml @@ -16,16 +16,16 @@ categories = ["command-line-utilities", "cryptography::cryptocurrencies"] [dependencies] hex = "0.4.3" -indexmap = "2.3.0" +indexmap = "2.5.0" lazy_static = "1.4.0" -insta = "1.39.0" +insta = "1.40.0" itertools = "0.13.0" proptest = "1.4.0" once_cell = "1.18.0" rand = "0.8.5" -regex = "1.10.6" +regex = "1.11.0" -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } tower = { version = "0.4.13", features = ["util"] } futures = "0.3.30" @@ -35,13 +35,13 @@ color-eyre = "0.6.3" tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } humantime = "2.1.0" -owo-colors = "4.0.0" +owo-colors = "4.1.0" spandoc = "0.2.2" -thiserror = "1.0.63" +thiserror = "1.0.64" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing-error = "0.2.0" tracing = "0.1.39" [dev-dependencies] -tempfile = "3.11.0" +tempfile = "3.13.0" diff --git a/zebra-utils/Cargo.toml b/zebra-utils/Cargo.toml index 2c1ce74992e..66c884d3ced 100644 --- a/zebra-utils/Cargo.toml +++ b/zebra-utils/Cargo.toml @@ -89,10 +89,10 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } structopt = "0.3.26" hex = "0.4.3" -serde_json = "1.0.122" +serde_json = "1.0.128" tracing-error = "0.2.0" tracing-subscriber = "0.3.18" -thiserror = "1.0.63" +thiserror = "1.0.64" zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39" } zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" } @@ -104,12 +104,12 @@ zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39", optional = true itertools = { version = "0.13.0", optional = true } # These crates are needed for the search-issue-refs binary -regex = { version = "1.10.6", optional = true } +regex = { version = "1.11.0", optional = true } # Avoid default openssl dependency to reduce the dependency tree and security alerts. reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true } # These crates are needed for the zebra-checkpoints and search-issue-refs binaries -tokio = { version = "1.39.2", features = ["full"], optional = true } +tokio = { version = "1.40.0", features = ["full"], optional = true } jsonrpc = { version = "0.18.0", optional = true } @@ -119,9 +119,9 @@ zcash_protocol.workspace = true # For the openapi generator rand = "0.8.5" -syn = { version = "2.0.72", features = ["full"], optional = true } -quote = { version = "1.0.36", optional = true } +syn = { version = "2.0.79", features = ["full"], optional = true } +quote = { version = "1.0.37", optional = true } serde_yml = { version = "0.0.12", optional = true } -serde = { version = "1.0.204", features = ["serde_derive"], optional = true } -indexmap = "2.3.0" +serde = { version = "1.0.210", features = ["serde_derive"], optional = true } +indexmap = "2.5.0" diff --git a/zebrad/Cargo.toml b/zebrad/Cargo.toml index 6b4f2cfec8d..8d42e2421ea 100644 --- a/zebrad/Cargo.toml +++ b/zebrad/Cargo.toml @@ -168,19 +168,19 @@ zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" } zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.39", optional = true } abscissa_core = "0.7.0" -clap = { version = "4.5.13", features = ["cargo"] } +clap = { version = "4.5.18", features = ["cargo"] } chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } humantime-serde = "1.1.1" -indexmap = "2.3.0" +indexmap = "2.5.0" lazy_static = "1.4.0" semver = "1.0.23" -serde = { version = "1.0.204", features = ["serde_derive"] } +serde = { version = "1.0.210", features = ["serde_derive"] } toml = "0.8.19" futures = "0.3.30" rayon = "1.10.0" -tokio = { version = "1.39.2", features = ["time", "rt-multi-thread", "macros", "tracing", "signal"] } -tokio-stream = { version = "0.1.15", features = ["time"] } +tokio = { version = "1.40.0", features = ["time", "rt-multi-thread", "macros", "tracing", "signal"] } +tokio-stream = { version = "0.1.16", features = ["time"] } tower = { version = "0.4.13", features = ["hedge", "limit"] } pin-project = "1.1.5" @@ -189,7 +189,7 @@ color-eyre = { version = "0.6.3", default-features = false, features = ["issue-u # Enable a feature that makes tinyvec compile much faster. tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } -thiserror = "1.0.63" +thiserror = "1.0.64" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing-appender = "0.2.3" @@ -221,8 +221,8 @@ tracing-journald = { version = "0.3.0", optional = true } # prod feature filter-reload hyper = { version = "1.3.1", features = ["http1", "http2", "server"], optional = true } http-body-util = { version = "0.1.2", optional = true } -hyper-util = { version = "0.1.6", optional = true } -bytes = { version = "1.7.1", optional = true } +hyper-util = { version = "0.1.9", optional = true } +bytes = { version = "1.7.2", optional = true } # prod feature prometheus metrics-exporter-prometheus = { version = "0.15.3", default-features = false, features = ["http-listener"], optional = true } @@ -248,7 +248,7 @@ console-subscriber = { version = "0.4.0", optional = true } vergen = { version = "8.3.2", default-features = false, features = ["cargo", "git", "git2", "rustc"] } # test feature lightwalletd-grpc-tests -tonic-build = { version = "0.12.1", optional = true } +tonic-build = { version = "0.12.3", optional = true } [dev-dependencies] abscissa_core = { version = "0.7.0", features = ["testing"] } @@ -256,22 +256,22 @@ hex = "0.4.3" hex-literal = "0.4.1" jsonrpc-core = "18.0.0" once_cell = "1.18.0" -regex = "1.10.6" -insta = { version = "1.39.0", features = ["json"] } +regex = "1.11.0" +insta = { version = "1.40.0", features = ["json"] } # zebra-rpc needs the preserve_order feature, it also makes test results more stable -serde_json = { version = "1.0.122", features = ["preserve_order"] } -tempfile = "3.11.0" +serde_json = { version = "1.0.128", features = ["preserve_order"] } +tempfile = "3.13.0" hyper = { version = "1.3.1", features = ["http1", "http2", "server"]} tracing-test = { version = "0.2.4", features = ["no-env-filter"] } -tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] } -tokio-stream = "0.1.15" +tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } +tokio-stream = "0.1.16" # test feature lightwalletd-grpc-tests -prost = "0.13.1" -tonic = "0.12.1" +prost = "0.13.3" +tonic = "0.12.3" proptest = "1.4.0" proptest-derive = "0.5.0" diff --git a/zebrad/build.rs b/zebrad/build.rs index b16a5dda330..efac0a69774 100644 --- a/zebrad/build.rs +++ b/zebrad/build.rs @@ -47,7 +47,7 @@ fn main() { // so we can derive `Eq` as well as the default generated `PartialEq` derive. // This fixes `clippy::derive_partial_eq_without_eq` warnings. .message_attribute(".", "#[derive(Eq)]") - .compile( + .compile_protos( &["tests/common/lightwalletd/proto/service.proto"], &["tests/common/lightwalletd/proto"], ) From 7313d5304b0f2054eb14bf336dec7d5212721d90 Mon Sep 17 00:00:00 2001 From: Arya Date: Mon, 7 Oct 2024 16:11:22 -0400 Subject: [PATCH 38/46] Responds with a maximum of 160 block headers (#8913) --- zebra-state/src/constants.rs | 15 +-------------- zebra-state/src/request.rs | 6 +++--- zebra-state/src/service.rs | 5 ++--- 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/zebra-state/src/constants.rs b/zebra-state/src/constants.rs index 905a35969fd..167ce011955 100644 --- a/zebra-state/src/constants.rs +++ b/zebra-state/src/constants.rs @@ -107,20 +107,7 @@ pub const MAX_NON_FINALIZED_CHAIN_FORKS: usize = 10; pub const MAX_FIND_BLOCK_HASHES_RESULTS: u32 = 500; /// The maximum number of block headers allowed in `getheaders` responses in the Zcash network protocol. -const MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_PROTOCOL: u32 = 160; - -/// The maximum number of block headers sent by Zebra in `getheaders` responses. -/// -/// Older versions of Zcashd will blindly request more block headers as long as it -/// got 160 block headers in response to a previous query, -/// _even if those headers are already known_. -/// -/// To avoid this behavior, return slightly fewer than the maximum, -/// so `zcashd` thinks it has reached our chain tip. -/// -/// -pub const MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA: u32 = - MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_PROTOCOL - 2; +pub const MAX_FIND_BLOCK_HEADERS_RESULTS: u32 = 160; /// These database versions can be recreated from their directly preceding versions. pub const RESTORABLE_DB_VERSIONS: [u64; 1] = [26]; diff --git a/zebra-state/src/request.rs b/zebra-state/src/request.rs index 1863c56b2ed..56be011d48e 100644 --- a/zebra-state/src/request.rs +++ b/zebra-state/src/request.rs @@ -25,7 +25,7 @@ use zebra_chain::{ /// will work with inline links. #[allow(unused_imports)] use crate::{ - constants::{MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA}, + constants::{MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS}, ReadResponse, Response, }; @@ -721,7 +721,7 @@ pub enum Request { /// Stops the list of headers after: /// * adding the best tip, /// * adding the header matching the `stop` hash to the list, if it is in the best chain, or - /// * adding [`MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA`] headers to the list. + /// * adding [`MAX_FIND_BLOCK_HEADERS_RESULTS`] headers to the list. /// /// Returns an empty list if the state is empty. /// @@ -925,7 +925,7 @@ pub enum ReadRequest { /// Stops the list of headers after: /// * adding the best tip, /// * adding the header matching the `stop` hash to the list, if it is in the best chain, or - /// * adding [`MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA`] headers to the list. + /// * adding [`MAX_FIND_BLOCK_HEADERS_RESULTS`] headers to the list. /// /// Returns an empty list if the state is empty. /// diff --git a/zebra-state/src/service.rs b/zebra-state/src/service.rs index 4f970be89d4..adc61f887ae 100644 --- a/zebra-state/src/service.rs +++ b/zebra-state/src/service.rs @@ -44,8 +44,7 @@ use zebra_chain::{block::Height, serialization::ZcashSerialize}; use crate::{ constants::{ - MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA, - MAX_LEGACY_CHAIN_BLOCKS, + MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS, MAX_LEGACY_CHAIN_BLOCKS, }, service::{ block_iter::any_ancestor_blocks, @@ -1476,7 +1475,7 @@ impl Service for ReadStateService { &state.db, known_blocks, stop, - MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA, + MAX_FIND_BLOCK_HEADERS_RESULTS, ) }, ); From 63b866544ff712ef063ecaebcbd1feaf3e9bef9d Mon Sep 17 00:00:00 2001 From: Arya Date: Mon, 7 Oct 2024 17:05:03 -0400 Subject: [PATCH 39/46] Updates post-NU6 funding stream address for FPF on Mainnet (#8914) --- zebra-chain/src/parameters/network/subsidy.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/zebra-chain/src/parameters/network/subsidy.rs b/zebra-chain/src/parameters/network/subsidy.rs index 6900eae07e6..c7ff373f55d 100644 --- a/zebra-chain/src/parameters/network/subsidy.rs +++ b/zebra-chain/src/parameters/network/subsidy.rs @@ -234,8 +234,7 @@ lazy_static! { ), ( FundingStreamReceiver::MajorGrants, - // TODO: Update these addresses - FundingStreamRecipient::new(8, FUNDING_STREAM_MG_ADDRESSES_MAINNET), + FundingStreamRecipient::new(8, POST_NU6_FUNDING_STREAM_FPF_ADDRESSES_MAINNET), ), ] .into_iter() @@ -405,6 +404,18 @@ pub const FUNDING_STREAM_ZF_ADDRESSES_MAINNET: [&str; FUNDING_STREAMS_NUM_ADDRES pub const FUNDING_STREAM_MG_ADDRESSES_MAINNET: [&str; FUNDING_STREAMS_NUM_ADDRESSES_MAINNET] = ["t3XyYW8yBFRuMnfvm5KLGFbEVz25kckZXym"; FUNDING_STREAMS_NUM_ADDRESSES_MAINNET]; +/// Number of addresses for each post-NU6 funding stream on Mainnet. +/// In the spec ([protocol specification §7.10][7.10]) this is defined as: `fs.addressindex(fs.endheight - 1)` +/// however we know this value beforehand so we prefer to make it a constant instead. +/// +/// [7.10]: https://zips.z.cash/protocol/protocol.pdf#fundingstreams +pub const POST_NU6_FUNDING_STREAMS_NUM_ADDRESSES_MAINNET: usize = 12; + +/// List of addresses for the Major Grants post-NU6 funding stream on Mainnet administered by the Financial Privacy Fund (FPF). +pub const POST_NU6_FUNDING_STREAM_FPF_ADDRESSES_MAINNET: [&str; + POST_NU6_FUNDING_STREAMS_NUM_ADDRESSES_MAINNET] = + ["t3cFfPt1Bcvgez9ZbMBFWeZsskxTkPzGCow"; POST_NU6_FUNDING_STREAMS_NUM_ADDRESSES_MAINNET]; + /// Number of addresses for each funding stream in the Testnet. /// In the spec ([protocol specification §7.10][7.10]) this is defined as: `fs.addressindex(fs.endheight - 1)` /// however we know this value beforehand so we prefer to make it a constant instead. @@ -482,7 +493,7 @@ pub const FUNDING_STREAM_MG_ADDRESSES_TESTNET: [&str; FUNDING_STREAMS_NUM_ADDRES /// [7.10]: https://zips.z.cash/protocol/protocol.pdf#fundingstreams pub const POST_NU6_FUNDING_STREAMS_NUM_ADDRESSES_TESTNET: usize = 13; -/// List of addresses for the Major Grants post-NU6 funding stream in the Testnet administered by the Financial Privacy Fund (FPF). +/// List of addresses for the Major Grants post-NU6 funding stream on Testnet administered by the Financial Privacy Fund (FPF). pub const POST_NU6_FUNDING_STREAM_FPF_ADDRESSES_TESTNET: [&str; POST_NU6_FUNDING_STREAMS_NUM_ADDRESSES_TESTNET] = ["t2HifwjUj9uyxr9bknR8LFuQbc98c3vkXtu"; POST_NU6_FUNDING_STREAMS_NUM_ADDRESSES_TESTNET]; From 3220520592444217fac030ce0119e0c50880ea4c Mon Sep 17 00:00:00 2001 From: Skylar Saveland Date: Mon, 7 Oct 2024 15:14:03 -0700 Subject: [PATCH 40/46] Update docker-compose.yml - tiny typo (#8893) --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 9264fd406d4..22359488de1 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -42,7 +42,7 @@ configs: zebra_config: # Change the following line to point to a zebrad.toml on your host machine # to allow for easy configuration changes without rebuilding the image - file: ../zebrad/tests/common/configs/v1.0.0-rc.2.toml/ + file: ../zebrad/tests/common/configs/v1.0.0-rc.2.toml volumes: zebrad-cache: From a28210300f8179b75592fcfa188a01463dbc233a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:02:09 +0000 Subject: [PATCH 41/46] build(deps): bump the devops group with 3 updates (#8919) Bumps the devops group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [tj-actions/changed-files](https://github.com/tj-actions/changed-files) and [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action). Updates `actions/checkout` from 4.2.0 to 4.2.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.2.0...v4.2.1) Updates `tj-actions/changed-files` from 45.0.2 to 45.0.3 - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v45.0.2...v45.0.3) Updates `docker/setup-buildx-action` from 3.6.1 to 3.7.1 - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3.6.1...v3.7.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch dependency-group: devops - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-patch dependency-group: devops - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: devops ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cd-deploy-nodes-gcp.yml | 4 ++-- .github/workflows/chore-delete-gcp-resources.yml | 4 ++-- .github/workflows/ci-build-crates.patch.yml | 2 +- .github/workflows/ci-build-crates.yml | 4 ++-- .github/workflows/ci-coverage.yml | 2 +- .github/workflows/ci-lint.yml | 14 +++++++------- .github/workflows/ci-unit-tests-os.yml | 10 +++++----- .github/workflows/docs-deploy-firebase.yml | 4 ++-- .github/workflows/docs-dockerhub-description.yml | 2 +- .github/workflows/manual-zcashd-deploy.yml | 2 +- .github/workflows/release-crates-io.yml | 2 +- .github/workflows/sub-build-docker-image.yml | 4 ++-- .../workflows/sub-deploy-integration-tests-gcp.yml | 6 +++--- .github/workflows/sub-find-cached-disks.yml | 2 +- .github/workflows/sub-test-zebra-config.yml | 2 +- 15 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/cd-deploy-nodes-gcp.yml b/.github/workflows/cd-deploy-nodes-gcp.yml index 9b403b53025..c096d531ddf 100644 --- a/.github/workflows/cd-deploy-nodes-gcp.yml +++ b/.github/workflows/cd-deploy-nodes-gcp.yml @@ -219,7 +219,7 @@ jobs: if: ${{ !cancelled() && !failure() && ((github.event_name == 'push' && github.ref_name == 'main') || github.event_name == 'release') }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false @@ -329,7 +329,7 @@ jobs: if: github.event_name == 'workflow_dispatch' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/chore-delete-gcp-resources.yml b/.github/workflows/chore-delete-gcp-resources.yml index 614ae82431e..4470d244029 100644 --- a/.github/workflows/chore-delete-gcp-resources.yml +++ b/.github/workflows/chore-delete-gcp-resources.yml @@ -39,7 +39,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false @@ -106,7 +106,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/ci-build-crates.patch.yml b/.github/workflows/ci-build-crates.patch.yml index 3e35849ea0e..c4333a86aba 100644 --- a/.github/workflows/ci-build-crates.patch.yml +++ b/.github/workflows/ci-build-crates.patch.yml @@ -23,7 +23,7 @@ jobs: outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 # Setup Rust with stable toolchain and minimal profile - name: Setup Rust diff --git a/.github/workflows/ci-build-crates.yml b/.github/workflows/ci-build-crates.yml index fe764136144..67404f75972 100644 --- a/.github/workflows/ci-build-crates.yml +++ b/.github/workflows/ci-build-crates.yml @@ -60,7 +60,7 @@ jobs: outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 - uses: r7kamura/rust-problem-matchers@v1.5.0 # Setup Rust with stable toolchain and minimal profile @@ -122,7 +122,7 @@ jobs: matrix: ${{ fromJson(needs.matrix.outputs.matrix) }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index 50d9d911a4b..057cc1cf916 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -69,7 +69,7 @@ jobs: runs-on: ubuntu-latest-xl steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index 4c354ebaaeb..4fb148e1b38 100644 --- a/.github/workflows/ci-lint.yml +++ b/.github/workflows/ci-lint.yml @@ -37,14 +37,14 @@ jobs: rust: ${{ steps.changed-files-rust.outputs.any_changed == 'true' }} workflows: ${{ steps.changed-files-workflows.outputs.any_changed == 'true' }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false fetch-depth: 0 - name: Rust files id: changed-files-rust - uses: tj-actions/changed-files@v45.0.2 + uses: tj-actions/changed-files@v45.0.3 with: files: | **/*.rs @@ -56,7 +56,7 @@ jobs: - name: Workflow files id: changed-files-workflows - uses: tj-actions/changed-files@v45.0.2 + uses: tj-actions/changed-files@v45.0.3 with: files: | .github/workflows/*.yml @@ -69,7 +69,7 @@ jobs: if: ${{ needs.changed-files.outputs.rust == 'true' }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false @@ -119,7 +119,7 @@ jobs: if: ${{ needs.changed-files.outputs.rust == 'true' }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -149,7 +149,7 @@ jobs: needs: changed-files if: ${{ needs.changed-files.outputs.workflows == 'true' }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 - name: actionlint uses: reviewdog/action-actionlint@v1.48.0 with: @@ -166,7 +166,7 @@ jobs: runs-on: ubuntu-latest needs: changed-files steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 - uses: codespell-project/actions-codespell@v2.1 with: only_warn: 1 diff --git a/.github/workflows/ci-unit-tests-os.yml b/.github/workflows/ci-unit-tests-os.yml index 036be178d34..372cef69218 100644 --- a/.github/workflows/ci-unit-tests-os.yml +++ b/.github/workflows/ci-unit-tests-os.yml @@ -94,7 +94,7 @@ jobs: rust: beta steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -183,7 +183,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -205,7 +205,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -248,7 +248,7 @@ jobs: continue-on-error: ${{ matrix.checks == 'advisories' }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -269,7 +269,7 @@ jobs: steps: - name: Checkout git repository - uses: actions/checkout@v4.2.0 + uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 diff --git a/.github/workflows/docs-deploy-firebase.yml b/.github/workflows/docs-deploy-firebase.yml index e9431693fd7..9da2c869f94 100644 --- a/.github/workflows/docs-deploy-firebase.yml +++ b/.github/workflows/docs-deploy-firebase.yml @@ -85,7 +85,7 @@ jobs: pull-requests: write steps: - name: Checkout the source code - uses: actions/checkout@v4.2.0 + uses: actions/checkout@v4.2.1 with: persist-credentials: false @@ -138,7 +138,7 @@ jobs: pull-requests: write steps: - name: Checkout the source code - uses: actions/checkout@v4.2.0 + uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/docs-dockerhub-description.yml b/.github/workflows/docs-dockerhub-description.yml index e232c55fb5d..b96a2e2fb1c 100644 --- a/.github/workflows/docs-dockerhub-description.yml +++ b/.github/workflows/docs-dockerhub-description.yml @@ -17,7 +17,7 @@ jobs: dockerHubDescription: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/manual-zcashd-deploy.yml b/.github/workflows/manual-zcashd-deploy.yml index b805289aa30..05872f2532d 100644 --- a/.github/workflows/manual-zcashd-deploy.yml +++ b/.github/workflows/manual-zcashd-deploy.yml @@ -29,7 +29,7 @@ jobs: id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/release-crates-io.yml b/.github/workflows/release-crates-io.yml index 5270af8ac27..60db739b236 100644 --- a/.github/workflows/release-crates-io.yml +++ b/.github/workflows/release-crates-io.yml @@ -70,7 +70,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@v1.5.0 - name: Checkout git repository - uses: actions/checkout@v4.2.0 + uses: actions/checkout@v4.2.1 with: persist-credentials: false diff --git a/.github/workflows/sub-build-docker-image.yml b/.github/workflows/sub-build-docker-image.yml index aea227d1e46..11b6399d625 100644 --- a/.github/workflows/sub-build-docker-image.yml +++ b/.github/workflows/sub-build-docker-image.yml @@ -80,7 +80,7 @@ jobs: env: DOCKER_BUILD_SUMMARY: ${{ vars.DOCKER_BUILD_SUMMARY }} steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false - uses: r7kamura/rust-problem-matchers@v1.5.0 @@ -152,7 +152,7 @@ jobs: # Setup Docker Buildx to use Docker Build Cloud - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v3.6.1 + uses: docker/setup-buildx-action@v3.7.1 with: version: "lab:latest" driver: cloud diff --git a/.github/workflows/sub-deploy-integration-tests-gcp.yml b/.github/workflows/sub-deploy-integration-tests-gcp.yml index 1145a1d6740..fb880a8a369 100644 --- a/.github/workflows/sub-deploy-integration-tests-gcp.yml +++ b/.github/workflows/sub-deploy-integration-tests-gcp.yml @@ -140,7 +140,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false fetch-depth: '2' @@ -390,7 +390,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false fetch-depth: '2' @@ -686,7 +686,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false fetch-depth: '2' diff --git a/.github/workflows/sub-find-cached-disks.yml b/.github/workflows/sub-find-cached-disks.yml index e52ef86327e..c936d65f8bd 100644 --- a/.github/workflows/sub-find-cached-disks.yml +++ b/.github/workflows/sub-find-cached-disks.yml @@ -58,7 +58,7 @@ jobs: contents: 'read' id-token: 'write' steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false fetch-depth: 0 diff --git a/.github/workflows/sub-test-zebra-config.yml b/.github/workflows/sub-test-zebra-config.yml index 92791f31d54..1f8c455b4b9 100644 --- a/.github/workflows/sub-test-zebra-config.yml +++ b/.github/workflows/sub-test-zebra-config.yml @@ -38,7 +38,7 @@ jobs: timeout-minutes: 30 runs-on: ubuntu-latest-m steps: - - uses: actions/checkout@v4.2.0 + - uses: actions/checkout@v4.2.1 with: persist-credentials: false From 1600edebefdd56883e8f28b71707265e5dbf3e99 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 10 Oct 2024 10:19:27 -0300 Subject: [PATCH 42/46] upgrade checkpoints (#8924) --- .../src/checkpoint/main-checkpoints.txt | 126 ++++++++++++++++++ .../src/checkpoint/test-checkpoints.txt | 99 ++++++++++++++ 2 files changed, 225 insertions(+) diff --git a/zebra-consensus/src/checkpoint/main-checkpoints.txt b/zebra-consensus/src/checkpoint/main-checkpoints.txt index 4c9a9c0d44d..aff5d444225 100644 --- a/zebra-consensus/src/checkpoint/main-checkpoints.txt +++ b/zebra-consensus/src/checkpoint/main-checkpoints.txt @@ -12177,3 +12177,129 @@ 2624406 0000000000d8c3a66ac5a0a8c3938f27537b734c7f35a5b6c4c9f3e9ef029cd8 2624806 00000000014e4268c9a2190fd52e4da77f6a887b966846d8f25aa6948a64d7a8 2625206 0000000000e70fb2297446280d68e7263e155c548ce47c9eafa2ebb55ec35a98 +2625606 00000000014f4e3c63d4a271f4ab19beffb6c680a98ab5d5265c6ed7224e96d7 +2626006 00000000004be1b5b382402702ecd413d60deb1b8f3519e49ead6c187eeb5edd +2626406 00000000001425180f380fb03df0b0cdcf682a2d46dab03aca2eddcae4145c46 +2626806 00000000008624d7b6d78cf1062a126645c403059e07a83550fa3346cac37664 +2627206 000000000015f6d6e1795b16bd9bee7dc7b4cee491eb3c71f7e8da9be00a60b0 +2627606 000000000101e9cdadd025d74ac82de012ed067913138ab8b86c515057a18cbd +2628006 0000000000249f3277f5bfef73fbb67debc2bdffb67ae844236b941421e35321 +2628406 00000000003d20ba5ed506854cfbb9eae39c9e57f0d6fb9e632691b3a051eac5 +2628806 0000000000d3d6f596e37413c3bad56e4c31baaf0627d9f73b6dbdc595f7880e +2629206 000000000075a542fec59d5d0b020b154e43aab3169da1b4a8425b7269bd653e +2629606 0000000000eeb9713c5e03aefa95696c038ba0ffde7e6ad9772c44a9a470e4b4 +2630006 0000000000133e359d6e60fbc2d568959ed56b17123ccfbdd159f1aa4951ad22 +2630406 0000000002245d9d2741a7892d64d6e9b4044e7d7f71560a8201595e298860a0 +2630806 0000000001c1a365c6a07dc5d99ac874cc8595590a7fd4dd62dcb3bc246e1b5c +2631206 00000000002570be7f316695395d552040d1c82c89b8c5dde859b683c2a9d6af +2631606 00000000007773e7e3eebef9300a01cc9b620f17f31c0b92139155be50fb2c6e +2632006 0000000000c54ddff6249bbd5dd90055660e427f01449a52e744b6b35a966b1e +2632406 0000000001abf33764a6d32b88e07936ccdabca43d482c8be63d38d17b8464dc +2632806 0000000001b57c8c4f7b60458fb596d8a86ae771f1a335950673af77f3e80c06 +2633206 0000000001a1202491a9ca9099b3e94c66028ff7ad0f1fbbb8100e27e41049f9 +2633606 0000000001e75b12f152437b13a079fb8f4b8ce5a95bc439d8b67a02a73f4c9d +2634006 000000000176f27d9ab309ae3a64d289020005744b7aee4f65b7d5cf16280b47 +2634406 00000000018c027107de01e1d3f1b9af5abb3ab52f53063c4d26ab7a4a9b7a2a +2634806 00000000007a9e53b36faecd9f411e1bd69ac9f48c18d7ad6b02074352cd639c +2635206 00000000011a33012b9ec50e0eac0495819531251d9f902b2c905387f238592d +2635606 0000000000358d644665a7adb57d890fe29cf4e0f9bc8108ab76df8b7b6ec65e +2636006 000000000070c7b0c258add3088d8d950f9f0165c0457efd219177ac5b032c8a +2636406 00000000014162f4bdca385858793e0cc0597ad9fedd7bfbdd1fe0ffae0e7a84 +2636806 00000000009e8387c54398809453d6489cd673d6ef0d33040a706a1876e488a1 +2637206 0000000001b6eb252c6fe78c7ad9c24559abb42cf7d34616c2ca2b5da3273fa2 +2637606 000000000173649f52e37ea5d1fa8de0538875b645d74db4bb98bc8ff23c6659 +2638006 0000000000538f7b7dfd18e5dc5dfed46a5c09a8de595838d82d9e965cdf4b36 +2638406 00000000012dee8d0b2433cc06d1f9820c28d076864cd8ce5a602dfc9b477c80 +2638806 000000000197ce6b2ba05b715e836f1a0a3e9b11eda2f14803987cfaff7bd9fc +2639206 0000000001c68825a4959681d07f64305f17b1d504d37423a86684d5cf5187b9 +2639606 00000000009f7e8b638a6e8ca8ed85434c42ac1fb280806a9a6f7e335d8e973b +2640006 00000000001558caa2ccb0e9ae27aae0c286268b5f722898e8301f79ef7aea78 +2640406 00000000013260c881a0711070837af189836627ce9998aeda0b82203db24ae4 +2640806 000000000082fe2a1061bc6c1b323f5444b932b81fab63c97dd440adee66a752 +2641206 0000000000d8e4eb37e7cb549112928b420d468b408c5aadb0a12f2f08108db8 +2641606 0000000000a1d5ac6e3d8b0f498537f8722bb02ad02ec289330d89f897cad312 +2642006 00000000025ab840bddbbb2caeb864889c099548f8be8744e4d743cbf7994a9e +2642406 0000000001bde94e940f10ef00990633eac776bee7ecd9752ddcace1b3e7f60b +2642806 00000000017b1aa7d94ff71496ef48fedd89eaa8816cc368e0c39ec989cb9b55 +2643206 000000000131af29cba7406cac833d67538b5b70f76891a76277cfe873e26455 +2643606 00000000008f42389bde6acd102d38510e7f9fed47b9e8410631a4c1e7b6e73a +2644006 0000000000f318f41fec3fb21e85eb25cab31d3cca14c78f09be15c7eb932c65 +2644406 0000000000060ed5eaca03b133c7830e1235fdfb70ac30de8c6e91902216a734 +2644806 000000000105ae213f8efaba6c882610a70741102399c493b3257c49ed3349ee +2645206 00000000000f1adce304a1b234f858301717be9782649e2212e3c0b820e6b12e +2645606 000000000005388844935f1ae0d1b1437832396a6a0ea1d7ca2aee2d2fb4fb2e +2646006 00000000018f5afcb6c97e0a9fae2ae4daff69147b52320344009d3a37beb220 +2646406 0000000001671aafb84735f971ab5d0b6f6419de6279444d03f5be7e35456c73 +2646806 000000000055de6c58155329b8e807c6c16ed6655e1a15a7a39b6e0d898ea548 +2647206 000000000176b93f66fa7190a14f63764aa2320ae1167a31d25c2c2bc10836d9 +2647606 00000000018032e1ecd0260c40ec9ce723cc32fab394162954a24ec9997cf6b5 +2648006 000000000140e67c12607105f2fdb7da6782e2dd09052f9dc7ce6ac77cec2c5a +2648406 0000000000e0e92a1c15b010583334198671bdae6d65bc50d7f7d701334bc1ad +2648806 00000000011cb84c9074707c73648a7d8e9e2823e3110d20d083fde9113ce796 +2649206 0000000000784bb776439b174c508282af2898bd876d11e595f3c1e59bca026a +2649606 0000000000f8d05e0633826998972f85be111c6d2520eebaadf15a3c44769725 +2650006 000000000005ff8fc9d62923fcffd38b58ca30345a009a3ae0d44b1da5f7d5b1 +2650406 00000000002054af7959069600f29b3845dcd1f5f27de2b3fd7bcd1a2f43838b +2650806 0000000001b50e2b3eb69094af355b1225e1c2a9962b3a0162e069459a6b9ed8 +2651206 000000000169c5a4db126a40a68e4a50d61f85579e702c50123b2ad2122bafda +2651606 0000000000b41cc2ca140869c3215437a1c09a408bd0dc72b5effdbefb962e67 +2652006 000000000124555a8e903be04bda53070b923f43cb2024aa22992775f2653f0e +2652406 0000000001558002fe04eaf473124328278d9fe2bf18dc813c8f5a8b050363c8 +2652806 0000000001c3557aed4416d9c14a6d698b40c8e16226444fdabdf41aa1526d0d +2653206 0000000001b74f14c79d9de792a9a0dd1df2ce35f1b13055c7d430aff1822a2e +2653606 0000000001a2785cb10a797523e7cdbb88bca211256ebd946d71111e1a86472c +2654006 0000000000deac02824ca6591e0d1b66bf2891fb09c57bf3858d62aae27cb46c +2654406 0000000001666379a4b4c66263fb56c2f317bae2951bc7d35dc6bcf721303968 +2654806 00000000007e593bbc26925ad6e56481bd1cb64c051c4deeddb89f9188760d9e +2655206 000000000172fa70e819f750f963651ed564c6ed719afd7415efd83268e670b8 +2655606 00000000017d51fd805e1181026cfe89ae19c8f092b01e1ff352ceebd3f2428b +2656006 000000000185810960c4295874601ad1eaeaec7f90562500d6c6f2bc309552d2 +2656406 000000000205514fd4d2202516ab6060b2d3a79a20bb50eda855e9efe921f461 +2656806 0000000001dbf4b39d66c6e0b766aa11a1ef0896421180e0d4b6415ec5c2056a +2657206 000000000141640da893de1c2f2fe10f9990993e1c0ae04f2199f4a25c0c06f9 +2657606 000000000111b1c350c3beb6c16e628b7da8e4e897fec0c2318be1a0a1e8b445 +2658006 00000000019faefa1417f4a13ff0cd6e865af4ee3c262eb294325fe5f0c96383 +2658406 000000000126e89df37808b0443aa804ee65e143158929f357b7071d6fa2fb70 +2658806 0000000001a27d45f3892a3ff3ba3d559dc4cf3a7d6cf3606149e547fbf3e1a4 +2659206 0000000001d42a455ff283dfdb2bb66083473b63a36c3ee440806de2dbe40846 +2659606 00000000008842d5742bf1224a521b38fbecaf5b4162fba26f9f8739cbb59c0f +2660006 00000000012e8baef3d981f90eb6a74940b3fe222010278ed3e2cf67a3306459 +2660406 0000000001b0a045708ee6d89c0d9444e23c48854a525146072b1dc73706f6b2 +2660806 000000000154dec42b8febdd350b5b925b8cb25db43525382b087fe1dba292f5 +2661206 0000000001ce18bddb0c49d2fb905a4d16ecb60b316b7041cd6554242c2f0205 +2661606 0000000000f9b5b25d9c6e6908e40174e18eda6367c682c97d036419b33745a4 +2662006 00000000014d6372cbbeeb054f20834e5faaddec3413c16f9e2c0ef996e1a9c4 +2662406 0000000000ea0f41591f19d0b7d615a421fb17b7538b0494eea9d1c993ef237a +2662806 0000000001611c661c32ffff2b681d3ce612695b5b89bed1bc71633d5a8cc2db +2663206 00000000008018fb5e984d384041ac864676a7c53970777b0409afb2ad2920b7 +2663606 00000000010805c3d6854f43bcfb3c17d6c018fd41b6a6d78f7d468b59fd94e7 +2664006 00000000013c678433f116eaa67b98e6198c374cc3cdd172d73a9f6c602bc957 +2664406 00000000004d34e909abea6990a5571207304d8d9d1799a9cdd4f2d15b7e3988 +2664806 000000000174bf5fd65181b56a308a3e3d564f8277842e82f6c188249e07fec7 +2665206 0000000001ec8c45ce6ee60b1921f6f72cba031ae7e51518bb4db5281101eca0 +2665606 000000000043a7bb25e301a8f6880fad235d9a29ead7e3aa1ed4a5362a837891 +2666006 00000000016416ec8c24b492b4f9a16b15f2bf1aedce1d90e875998cb577edba +2666406 00000000009f1c02edd6339af8e216f620ed32a6cb6ce4fb284d7bdf82305ee0 +2666806 00000000013b50bb104f73cfaa00fd652e67b4a89588baa27dd95aab2a59a452 +2667206 00000000003f0ae07948979983175156a732bb79610096dfbc0fa7a29eaf48ed +2667606 00000000001a94fdb7d9dd3eb37b3783ebc30864a304dd8ddad6802f94b7a3d9 +2668006 0000000000d5d7aab1d70e2fdfa27586d2760d4d4ee234ffcf5136be94ced6bd +2668406 000000000156144469688a7399c479d1d80cb0ff30f49326bcfee27c372823a4 +2668806 0000000000ab2254331ff5f51112bf8e08f7fc9bbadb3836e6dd070ab2d96718 +2669206 00000000010496c02ac9094f9647c92d7be9b8fa18e8d73a82203009b52d3ac7 +2669606 0000000000f8c1992cc04a608c8716748134e2b8d095ec03bd8d79e6935532c3 +2670006 0000000000312d25ce5cd017d41bf3cdc26deafc073f11237b1df7c7c47f566f +2670406 00000000010d11aa21b44f48f6d44b5045128c3b36c3a05a5438776680615abe +2670806 00000000017f15485570574b715a2bafb80d35df6b9bcfc15f0a901ac806c47e +2671206 0000000000812c9f41ad666bca5d9d41bd37bf14c638940f983fb3960331c04a +2671606 00000000005d4d7d6a403a2a064b7ff117af665ded46f592cafed26aaf9b8ca4 +2672006 00000000003f61a2bfc7715db9d7ac1720b98b504e504764a609e5ef1e02e9f0 +2672406 000000000136c4e46ed63f4eb6409af4024952861ba95f372882c5251e0a249f +2672806 000000000173052e6bcc30a2af8792343bcf75b207cbcc2a9bcc2611b5c551f4 +2673206 000000000146c90abab2bb4919cad89f10e198562a0e5c7a543ad8357facb667 +2673606 00000000009364e3ec0954c9090a2db6b2be08ad1b679dfc0d429ed9e57bd972 +2674006 000000000191a821de364efb3ca613dc20c2e1377734a841f2e88bfc825d5e3f +2674406 0000000001535fb080dea37cf6d973178f6a3014851ab26d1914456742163ef3 +2674806 00000000014f2059c0d91a8ed6023b08294593de773268abb0b4ad79d9d20581 +2675206 00000000003ebb8baab4ceaf73fde6753d4281edfa07c897458ce9a1c5ff57ee +2675606 0000000000065afdce346665ab6ca463930733149eaaf1e79033b08232f7a363 diff --git a/zebra-consensus/src/checkpoint/test-checkpoints.txt b/zebra-consensus/src/checkpoint/test-checkpoints.txt index 0b6cde440d3..484621f8a1f 100644 --- a/zebra-consensus/src/checkpoint/test-checkpoints.txt +++ b/zebra-consensus/src/checkpoint/test-checkpoints.txt @@ -7434,3 +7434,102 @@ 2973200 0032c83ee743bcfd5795caaa601d0275f6b54fb75574750a51e5d22c24b14ea8 2973600 0012655ae0ade4590af7c05dd609415b422d33f7ceb1dbb15d2c381bf0576dd2 2974000 004a2810cfe2a2bd83c202a0311cff47c80364ee2a874a93bae34404380e2b98 +2974400 0022bbb634b3c87ba01cf9e88637eaf43cfa81641b82d33d9b362add0fd8c41b +2974800 00458fbb5c826bcda26fc5936915353df569091b51b335480b12031692a6d5a6 +2975200 002c923c7ea37b4fdc0a4ae792ddf9b5087288512702891335c539c1910cd10c +2975600 00179853d41830957b6e4dada1d1bb709f4460497b7ae49e080d933efa201744 +2976000 0017d56ed80077f45eb88f11d50f4306ee1fbf95892c9a9cb7a9538e72ceabc1 +2976400 00584d9303c8817a82d09e2797b2cf488ed6c4efef322b915bdcfd230a42de2f +2976800 00160f1ba661be6e2d48099e3ff72345f6051a571b1d363df1382c8a6c422102 +2977200 0022accee852fc0d84ac932773bc7b71d53f8ff8d4c439bd982cd6ff4747ac60 +2977600 004554ac744c87257595f32dfa77e0446a0dad1e9193c12de3f14a4a29fb2045 +2978000 0022e4822a5b6749d6dfc7fa90845e8d185d0fe04197c6fd4f0e18066006fa6f +2978400 0052824498a9414802d98e56ab3e48919f9397e3c0bc573283a4e4d471bf12bc +2978800 0046d673c6d74676bdcadc63a868c0886b16a4538f0d7045d6d61399b4292c4e +2979200 00dead16ec073ce4a919eff239f21508997232a9c598de0b6b10c8e00fd4e413 +2979600 0031ee45acf915c0d36441583aedd05c36c10a3cf03ac090f6994f46bb359ace +2980000 00074a97178ddee1c90add32065c3dcba94026ed94a7abbad74d95754e4bca63 +2980400 005f3be21f2c324b5c0f3014e8621e31ad9dbb146393208b0597191827bb8ed3 +2980800 001eabd1939746320b0322a8e853ead97ff31537e167336dab15ffc3e5a76e25 +2981200 00699b9d0952eb987e6a3907c56bd218401756b982d5adf5103f755176c09838 +2981600 002a23f230985a0a6b5708837b21e930ee54f62c394b6fbb704ba5a7a8e48177 +2982000 00d030142777ac5f04a38153b83ccc72a5bd4b1ef6a449b5acb5c86b64792e73 +2982400 00264619ba50c766d638ed99b5b167edadfc3588bbfd3da7c63cf7a6f5048c97 +2982800 00486d6ecfc4b9c13fe5c30275298308aa8344f33e37e5aaa9a80b97f2a815d1 +2983200 002de3fea65b06c40080240a21d664b0dea224b146c6c2c00c3c6306a7297fab +2983600 06d4fffdd467139d9d2f80ed0a670a0eb27e2dddf863600d157b4d872aec469a +2984000 0009b56289a49bfca3c0fe9ed50d1f7eaeca7ba34258f73006f1420a41a32fc5 +2984400 000532dfb34a7f7937eef7dd4bd87a9543057efea82506c42c9ac8f5a3454537 +2984800 00323df998c2bc31631cf76cf832e577bc0d804ccdcc8680dfcd74c0953a866f +2985200 001be73a9c3c041da1bd6a2bfc26cfbd2cbde992e11b64c7b8e53c711d36ceab +2985600 0019d10c111c6031c24bf5381327731d3701da501f092e636f3a3f2c1be0eb93 +2986000 0014687fc704f084257ccd48be14f4f8147aa5c8c1d6e518b041e5763dbb463c +2986400 0010521021fd245c6d4d0b5881c72d73cc9c7232bfb9648636af35519999e444 +2986800 000ac5b70875bccf25fcdbbf7690c0d0c5f39133b3bc4c5a5489a4628e976bb0 +2987200 006f4c27c6de76acf6942c0c6771679b23a983c27935aeb4b4db068400a6747c +2987600 001cf3cd65806efc218dca11184be3e34fbfdb9d9c66eecf79b451306fb08e42 +2988000 00385974ef8716fe45a001bac4b9ba70e98e36e6d733f85842001d8361fb6ad1 +2988400 00aa453bb6feebc5ca98e23cc3e50dde6b1bd9d2cb50cc07f10f1c2ab64eed1e +2988800 006456c1419697679b5fab7c75e540cdb4a3b55a244af57eede27f48ef37bbe1 +2989200 00e183f9b91d77afb1fdddf6617ff015933b32b38632ff704bdbafcf0969abe3 +2989600 008e8aec2cdfcd038a8124828bd1c7be65ae2927b520800a37e22f11c0c6c5c0 +2990000 00af170515d9182896b815fd8fa7067ec32e7ae2d1013655203aab9035482cd5 +2990400 00903b7b501a8a36fc381412b98ea7935075d5d36ad3412b3de70370bb835e26 +2990800 002eabb0e34c2f5911ce9472b8a97a3591ba5fb9b5d699bad5ca7e8e7dff29ec +2991200 00e2e4839d4781d8b654791382ad762aca8fa2a9337a551aeaf65ff8469f949e +2991600 005a44c5e8d1ea2268df01d49f964c13c2b6c415e64a92982be877a51b9367f3 +2992000 0048db0454853598652ea3e7975ae0678e3ab4f80b24d2d8eab5f4491aeae341 +2992400 00604fa9e6e883419e67793510d61fd07c0c566a4357e5f236db4863909bca4c +2992800 009bc0379eb615cfa73a14252fe60e06ca8d677a850ffb216111a03a51f3d2ba +2993200 00262af418a3f14f6fd704eed3cbedb6feedab7ed1d336149ba60190dd8d5627 +2993600 004c9599e33c92fcbff384f46dd2d32acfe67535bb7585c1e6aa20a45b0d9437 +2994000 0035d3cd6c8fe730067378073189eb4d39b978664da0a227148d973ce4a2769d +2994400 005b3851f75804e4775f27a44775b09e1acd42d6f84a4b352f2ff9ee4d7445f5 +2994800 001a326e8ab266490db69bad4b603fca01ec6c4014347c3ccabc8b470dc55fa7 +2995200 000ddfb141559989861252d06883e6f85e882f344d49d39405c1a8b5da8a6973 +2995600 0045c05ff5d9c2800762636813acf05d227a350c061d6ab9ed84b763c51ab443 +2996000 007de7332473a328a114d2a1ea1760d133e6d7afc45d12fbcea5e060b5c0e0ad +2996400 0070f19bebf84c4d115999b02d30a792ffa234ccb49b4c3144beedbaffcdb35a +2996800 005c06bca5b702ddd66537882a1a960b140d72072f60d078b575d2d46af634fe +2997200 0055708e62124e1dabb01e2e6b808e8454774c0c358defcf896100c84e80a254 +2997600 01cf554f19e2c3b3baf645ba0fed77029c74286f4361eaf401e6822d28a127e3 +2998000 0006dc2e8b057c43a1b3aa9e565b3912b71614ccd83b96c64c7af7604bfc2afb +2998400 0013966207316fbb6c91606c32afbb937daac81a7927299d2697cf1e6dd52b2c +2998800 001147a0eaff7ece55c60087187767ef19a1c2c6e833cf8a8b84f4c457a8db4a +2999200 001ed62bd7508d0d529ab2bb129784eebb9e93ae920e7cf95b4952330e960dab +2999600 00975335c00f798a2a7e04707f763443d5644cd65d82de99ac076b679f3c2417 +3000000 0031432018aa59e440804fa87974ec791ae174fa2909470f3c3a8a93842a659f +3000400 00b7d239d9ca1f3c12ab873fb8481bb1b2dbb217c9184c20d6bfed56bddc3e73 +3000800 00fe4dcad3cede4648dc0145ef4739eafdd7ee5a917eebdb3039f939414909be +3001200 00156bd2823f54d74d16619385f784908f550cbd251a9e26eba7b75c008672dc +3001600 068d6954e2d9c83a16895c96b152c07d18e9ff9a72ae34da00d9ecf708d91843 +3002000 0000e8a565bc879836b498a045bdfdd889c119ddc074233281db25fa5405c1dd +3002400 07031d3ff01c5bf5bdf488ec327a0912c667cfd6c65adb53df5d9c29ebeb77b2 +3002800 07aaa1a5f9efe3b10b7d06f5cc6547d5086889b11c0403926a1506fd20f72d6d +3003200 00062726eecd4bde3da20713575797eeb6c131270114a5e4f478256997f91386 +3003600 000b56fe1770444f38cfe6ab206351b012e6b2aef48bd97d7a1c9e9915f35c2c +3004000 0038d09a6031912f36207f8e14020e12989e9fa5c7405ee69f792ac07af04e38 +3004400 009ef06fb016e582b0d286adb72f2b39b118f3193eb883733e5020fc4cc995eb +3004800 00508822b2e469b412628a7da879d4b302c867a7fbfb6c142776b2b30ea1f811 +3005200 001ab12b2a505bedfcf9fa3d64480dbb977efe71940d7a8b0a738d2f97e6cb00 +3005600 001257424eb2683058899922d185a8a8b955c217f10dc106f91cdeb38c3d1c66 +3006000 000ee0de408e16df398189b18c5bd9fd3c6ee55fb28b7afaf0304627c5f13267 +3006400 006d417c0a56b9a2aaf686360aa3c111671017a8dc493ef9e50f65768102a2d4 +3006800 00561d7b3a8bcc57e2069996890f0074d7f0b3601a27688f44c24a83d3c6b4e8 +3007200 010cb5a8e3e9ba661dd7ab7b087f5f55dc243bcd13481034ddf56efd8b643ed2 +3007600 0037e87b458d6faf64750c8556b329eb11308d9a5cc921bec15053bf43985245 +3008000 0010a31899ab3650a999a3eb98786ee59f2ed890d93f338f36194cd0c73511e6 +3008400 003b99ec2366bdedb6811fcbaab13393a436eac72e68194acb725729984331d3 +3008800 000659dfa07df7883d44fc58b2ddbcd930ee950698ee5d27b8f6faeea8a8382a +3009200 000f96accb21165fb5ea8c7da816f007116d3309412acad32fe28c269f652357 +3009600 00533daa091bbcd0008035ddaa56f684be41d7fe66fea665ae8f4fd85cf4ea9d +3010000 00bf309a67faef45356683ee7aa30ec167854515b6aba1b05592385e5caf4652 +3010400 00959a4d4f653186485b260ed851999f695a039f1ddf39e02b93adcb592fe812 +3010800 00637c7b49f3d9a1bdc05c14939855d40c1de1f8273070be9f9c2518d5c3607e +3011200 005b320c531b36611ea3b718eb09a622a602a50a1bec93f475eac598ff8726d1 +3011600 0020653b72946047c7afbfa3c74b28deff29c55627a862d8437ee7038b2ea92f +3012000 001717262f28c5ca078cffc7d8c1887a4c98a44f9e93eb841975294fcb3b3d65 +3012400 0014b2b3692aade71cf14910d91181cd238a5ecd14f6344c69817c4349e8766c +3012800 00a5a4c7aa1e5120b05358100083165fdae6d3da4932391f806dc70b17de43b0 +3013200 005816e627c296c77a1088915b359185349a4b4b345a325a889a4854c6598f71 +3013600 0067f8576378bcfa73c91f734526234125ab0cc306bcbfc415359000f54908fe From 8cd4d96085e5e469d13e791f90b377256448d02f Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 10 Oct 2024 14:09:04 -0300 Subject: [PATCH 43/46] build(deps): Upgrade ECC crates for Zebra `v2.0.0-rc.0` release candidate (#8918) * update ECC dependencies for release candidate * cargo vet * fix denies * fix parsing, remove not needed entries * update `secp256k1` * remove elasticsearch from denies * readd elasticsearch from deny.toml * downgrade to revisions * add more patches * typo in comment * cargo vet changes * update denies * add more git sources * Apply suggestions from code review Co-authored-by: Arya * update cargo.lock --------- Co-authored-by: Arya --- Cargo.lock | 280 +++++++++++---------------------------- Cargo.toml | 17 ++- deny.toml | 30 +++-- supply-chain/audits.toml | 114 ++++++++++++++-- supply-chain/config.toml | 44 +++++- zebra-chain/Cargo.toml | 4 +- zebra-scan/Cargo.toml | 7 +- 7 files changed, 260 insertions(+), 236 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72541a4a72c..2572faa0e18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -438,7 +438,7 @@ dependencies = [ "hmac", "rand_core 0.6.4", "ripemd", - "secp256k1 0.27.0", + "secp256k1", "sha2", "subtle", "zeroize", @@ -539,11 +539,11 @@ dependencies = [ [[package]] name = "bridgetree" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62227647af796dd9f1637da0392676a2e200973b817b082fc9be89bf93ddd74" +checksum = "cef977c7f8e75aa81fc589064c121ab8d32448b7939d34d58df479aa93e65ea5" dependencies = [ - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", ] [[package]] @@ -1323,7 +1323,7 @@ dependencies = [ [[package]] name = "equihash" version = "0.2.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "blake2b_simd", "byteorder", @@ -1367,7 +1367,7 @@ dependencies = [ [[package]] name = "f4jumble" version = "0.1.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "blake2b_simd", ] @@ -2104,6 +2104,14 @@ dependencies = [ "either", ] +[[package]] +name = "incrementalmerkletree" +version = "0.7.0" +source = "git+https://github.com/zcash/incrementalmerkletree?rev=ffe4234788fd22662b937ba7c6ea01535fcc1293#ffe4234788fd22662b937ba7c6ea01535fcc1293" +dependencies = [ + "either", +] + [[package]] name = "indenter" version = "0.3.3" @@ -2798,9 +2806,8 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchard" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc7bde644aeb980be296cd908c6650894dc8541deb56f9f5294c52ed7ca568f" +version = "0.9.1" +source = "git+https://github.com/zcash/orchard?rev=55fb089a335bbbc1cda186c706bc037073df8eb7#55fb089a335bbbc1cda186c706bc037073df8eb7" dependencies = [ "aes", "bitvec", @@ -2811,7 +2818,7 @@ dependencies = [ "halo2_gadgets", "halo2_proofs", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", "lazy_static", "memuse", "nonempty", @@ -3789,8 +3796,7 @@ dependencies = [ [[package]] name = "sapling-crypto" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e379398fffad84e49f9a45a05635fc004f66086e65942dbf4eb95332c26d2a" +source = "git+https://github.com/zcash/sapling-crypto?rev=b1ad3694ee13a2fc5d291ad04721a6252da0993c#b1ad3694ee13a2fc5d291ad04721a6252da0993c" dependencies = [ "aes", "bellman", @@ -3804,7 +3810,7 @@ dependencies = [ "fpe", "group", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", "jubjub", "lazy_static", "memuse", @@ -3834,16 +3840,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "secp256k1" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" -dependencies = [ - "secp256k1-sys", - "serde", -] - [[package]] name = "secp256k1" version = "0.27.0" @@ -3851,6 +3847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ "secp256k1-sys", + "serde", ] [[package]] @@ -4135,12 +4132,11 @@ dependencies = [ [[package]] name = "shardtree" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78222845cd8bbe5eb95687407648ff17693a35de5e8abaa39a4681fb21e033f9" +source = "git+https://github.com/zcash/incrementalmerkletree?rev=ffe4234788fd22662b937ba7c6ea01535fcc1293#ffe4234788fd22662b937ba7c6ea01535fcc1293" dependencies = [ "bitflags 2.6.0", "either", - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", "tracing", ] @@ -5611,81 +5607,28 @@ dependencies = [ "bech32", "bs58", "f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding", "zcash_protocol 0.2.0", ] [[package]] name = "zcash_address" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14bccd6cefb76f87b6d15a9e7b02b6c0515648c6de8e806c4e2d6f0f6ae640c5" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "bech32", "bs58", - "f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "zcash_address" -version = "0.5.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" -dependencies = [ - "bech32", - "bs58", - "f4jumble 0.1.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)", - "zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)", + "f4jumble 0.1.0 (git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792)", + "zcash_encoding", + "zcash_protocol 0.3.0", ] [[package]] name = "zcash_client_backend" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e3a0f3e5d7f299d8b7ef3237697630989c31ab1b162824c99c1cd8bc83715e" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ - "base64 0.21.7", - "bech32", - "bls12_381", - "bs58", - "crossbeam-channel", - "document-features", - "group", - "hex", - "incrementalmerkletree", - "memuse", - "nom", - "nonempty", - "percent-encoding", - "prost", - "rand_core 0.6.4", - "rayon", - "sapling-crypto", - "secrecy", - "shardtree", - "subtle", - "time", - "tonic-build", - "tracing", - "which", - "zcash_address 0.4.0", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_keys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_note_encryption", - "zcash_primitives 0.16.0", - "zcash_protocol 0.2.0", - "zip32", - "zip321 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "zcash_client_backend" -version = "0.13.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" -dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bech32", "bls12_381", "bs58", @@ -5693,7 +5636,7 @@ dependencies = [ "document-features", "group", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", "memuse", "nom", "nonempty", @@ -5709,30 +5652,20 @@ dependencies = [ "tonic-build", "tracing", "which", - "zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)", - "zcash_keys 0.3.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_address 0.5.0", + "zcash_encoding", + "zcash_keys 0.3.0 (git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792)", "zcash_note_encryption", - "zcash_primitives 0.17.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_primitives 0.17.0", + "zcash_protocol 0.3.0", "zip32", - "zip321 0.1.0 (git+https://github.com/zcash/librustzcash/)", + "zip321", ] [[package]] name = "zcash_encoding" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052d8230202f0a018cd9b5d1b56b94cd25e18eccc2d8665073bcea8261ab87fc" -dependencies = [ - "byteorder", - "nonempty", -] - -[[package]] -name = "zcash_encoding" -version = "0.2.1" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "byteorder", "nonempty", @@ -5741,8 +5674,7 @@ dependencies = [ [[package]] name = "zcash_history" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fde17bf53792f9c756b313730da14880257d7661b5bfc69d0571c3a7c11a76d" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "blake2b_simd", "byteorder", @@ -5769,7 +5701,7 @@ dependencies = [ "subtle", "tracing", "zcash_address 0.4.0", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding", "zcash_primitives 0.16.0", "zcash_protocol 0.2.0", "zip32", @@ -5778,7 +5710,7 @@ dependencies = [ [[package]] name = "zcash_keys" version = "0.3.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "bech32", "blake2b_simd", @@ -5793,10 +5725,10 @@ dependencies = [ "secrecy", "subtle", "tracing", - "zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)", - "zcash_primitives 0.17.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_address 0.5.0", + "zcash_encoding", + "zcash_primitives 0.17.0", + "zcash_protocol 0.3.0", "zip32", ] @@ -5829,7 +5761,7 @@ dependencies = [ "fpe", "group", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.6.0", "jubjub", "memuse", "nonempty", @@ -5842,7 +5774,7 @@ dependencies = [ "subtle", "tracing", "zcash_address 0.4.0", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_encoding", "zcash_note_encryption", "zcash_protocol 0.2.0", "zcash_spec", @@ -5852,8 +5784,7 @@ dependencies = [ [[package]] name = "zcash_primitives" version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d87ab6a55591a8cf1866749fdc739ae1bbd06e6cec07ab0bbe5d57ee3390eb2" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "aes", "bip32", @@ -5861,12 +5792,12 @@ dependencies = [ "bs58", "byteorder", "document-features", - "equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "equihash 0.2.0 (git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792)", "ff", "fpe", "group", "hex", - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", "jubjub", "memuse", "nonempty", @@ -5876,49 +5807,14 @@ dependencies = [ "redjubjub", "ripemd", "sapling-crypto", - "secp256k1 0.27.0", - "sha2", - "subtle", - "tracing", - "zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_note_encryption", - "zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_spec", - "zip32", -] - -[[package]] -name = "zcash_primitives" -version = "0.17.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" -dependencies = [ - "aes", - "blake2b_simd", - "bs58", - "byteorder", - "document-features", - "equihash 0.2.0 (git+https://github.com/zcash/librustzcash/)", - "ff", - "fpe", - "group", - "hex", - "incrementalmerkletree", - "jubjub", - "memuse", - "nonempty", - "orchard", - "rand 0.8.5", - "rand_core 0.6.4", - "redjubjub", - "sapling-crypto", + "secp256k1", "sha2", "subtle", "tracing", - "zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)", + "zcash_address 0.5.0", + "zcash_encoding", "zcash_note_encryption", - "zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_protocol 0.3.0", "zcash_spec", "zip32", ] @@ -5926,8 +5822,7 @@ dependencies = [ [[package]] name = "zcash_proofs" version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9fc0032b3d90f000f50dba7a996ad6556b7dba5b5145f93ab67b6eb74d3a48" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "bellman", "blake2b_simd", @@ -5943,7 +5838,7 @@ dependencies = [ "sapling-crypto", "tracing", "xdg", - "zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.17.0", ] [[package]] @@ -5959,17 +5854,7 @@ dependencies = [ [[package]] name = "zcash_protocol" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1ff002bd41ba76b42d42a02ee11de06790b7fdbc904bdea4486b9a93b2a5e4" -dependencies = [ - "document-features", - "memuse", -] - -[[package]] -name = "zcash_protocol" -version = "0.3.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ "document-features", "memuse", @@ -6017,7 +5902,7 @@ dependencies = [ "halo2_proofs", "hex", "humantime", - "incrementalmerkletree", + "incrementalmerkletree 0.7.0", "itertools 0.13.0", "jubjub", "lazy_static", @@ -6034,7 +5919,7 @@ dependencies = [ "redjubjub", "ripemd", "sapling-crypto", - "secp256k1 0.26.0", + "secp256k1", "serde", "serde-big-array", "serde_json", @@ -6049,13 +5934,13 @@ dependencies = [ "tracing", "uint 0.10.0", "x25519-dalek", - "zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_client_backend 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address 0.5.0", + "zcash_client_backend", + "zcash_encoding", "zcash_history", "zcash_note_encryption", - "zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.17.0", + "zcash_protocol 0.3.0", "zebra-test", ] @@ -6120,7 +6005,7 @@ dependencies = [ "tonic-build", "tonic-reflection", "tower", - "zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_primitives 0.17.0", "zebra-chain", "zebra-node-services", "zebra-state", @@ -6207,8 +6092,8 @@ dependencies = [ "tonic-reflection", "tower", "tracing", - "zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_address 0.5.0", + "zcash_primitives 0.17.0", "zebra-chain", "zebra-consensus", "zebra-network", @@ -6250,11 +6135,11 @@ dependencies = [ "tower", "tracing", "tracing-subscriber", - "zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_client_backend 0.13.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_address 0.5.0", + "zcash_client_backend", "zcash_keys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_note_encryption", - "zcash_primitives 0.17.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_primitives 0.17.0", "zebra-chain", "zebra-grpc", "zebra-node-services", @@ -6372,9 +6257,9 @@ dependencies = [ "tokio", "tracing-error", "tracing-subscriber", - "zcash_client_backend 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zcash_client_backend", + "zcash_primitives 0.17.0", + "zcash_protocol 0.3.0", "zebra-chain", "zebra-node-services", "zebra-rpc", @@ -6506,24 +6391,11 @@ dependencies = [ [[package]] name = "zip321" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dc85f862f7be64fb0d46f9eb5b82ad54e58cde314fa979d5bae591bc0143693" +source = "git+https://github.com/zcash/librustzcash.git?rev=1410f1449100a417bfbc4f6c7167aa9808e38792#1410f1449100a417bfbc4f6c7167aa9808e38792" dependencies = [ - "base64 0.21.7", - "nom", - "percent-encoding", - "zcash_address 0.4.0", - "zcash_protocol 0.2.0", -] - -[[package]] -name = "zip321" -version = "0.1.0" -source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4" -dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "nom", "percent-encoding", - "zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)", - "zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)", + "zcash_address 0.5.0", + "zcash_protocol 0.3.0", ] diff --git a/Cargo.toml b/Cargo.toml index a006d6eb8a6..976c259130d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ resolver = "2" # `cargo release` settings [workspace.dependencies] -incrementalmerkletree = "0.6.0" +incrementalmerkletree = "0.7.0" orchard = "0.9.0" sapling-crypto = "0.2.0" zcash_address = "0.5.0" @@ -102,3 +102,18 @@ panic = "abort" # - add "-flto=thin" to all C/C++ code builds # - see https://doc.rust-lang.org/rustc/linker-plugin-lto.html#cc-code-as-a-dependency-in-rust lto = "thin" + +# We can remove this patches after we get out of 2.0 release candidate and upgrade the ECC dependencies above. +# This revisions are at the commit just before setting mainnet activation heights. +[patch.crates-io] +zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +zcash_client_backend = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +zcash_protocol = { git = "https://github.com/zcash/librustzcash.git", rev = "1410f1449100a417bfbc4f6c7167aa9808e38792" } +sapling-crypto = { git = "https://github.com/zcash/sapling-crypto", rev = "b1ad3694ee13a2fc5d291ad04721a6252da0993c" } +orchard = { git = "https://github.com/zcash/orchard", rev = "55fb089a335bbbc1cda186c706bc037073df8eb7" } +incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "ffe4234788fd22662b937ba7c6ea01535fcc1293" } +shardtree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "ffe4234788fd22662b937ba7c6ea01535fcc1293" } diff --git a/deny.toml b/deny.toml index bf51d9dcafc..b8d35b41cc4 100644 --- a/deny.toml +++ b/deny.toml @@ -84,19 +84,26 @@ skip-tree = [ { name = "http-body", version = "=0.4.6" }, { name = "hyper", version = "=0.14.30" }, - # TODO: Remove this after we upgrade ECC dependencies to a crates.io version (#8749) - { name = "equihash", version = "=0.2.0" }, - { name = "f4jumble", version = "=0.1.0" }, - { name = "secp256k1", version = "=0.26.0" }, - { name = "zcash_address", version = "=0.5.0" }, - { name = "zcash_client_backend", version = "=0.13.0" }, - - # wait for structopt-derive to update heck { name = "heck", version = "=0.3.3" }, # wait for librocksdb-sys to update bindgen to one that uses newer itertools - { name = "itertools", version = "=0.12.1" } + { name = "itertools", version = "=0.12.1" }, + + # wait for halo2_gadgets and primitive-types to update uint + { name = "uint", version = "=0.9.5" }, + + # wait for dirs-sys to update windows-sys + { name = "windows-sys", version = "=0.48.0" }, + + # Remove after release candicate period is over and the ECC crates are not patched anymore + { name = "equihash", version = "=0.2.0" }, + { name = "f4jumble", version = "=0.1.0" }, + { name = "incrementalmerkletree", version = "=0.6.0" }, + { name = "zcash_address", version = "=0.4.0" }, + { name = "zcash_keys", version = "=0.3.0" }, + { name = "zcash_primitives", version = "=0.16.0" }, + { name = "zcash_protocol", version = "=0.2.0" } ] # This section is considered when running `cargo deny check sources`. @@ -114,7 +121,10 @@ unknown-git = "deny" allow-registry = ["https://github.com/rust-lang/crates.io-index"] # List of URLs for allowed Git repositories allow-git = [ - "https://github.com/zcash/librustzcash.git" + "https://github.com/zcash/librustzcash.git", + "https://github.com/zcash/incrementalmerkletree", + "https://github.com/zcash/orchard", + "https://github.com/zcash/sapling-crypto" ] [sources.allow-org] diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 963d1771ca3..284db15ec14 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -26,6 +26,11 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.4.0 -> 0.5.0" +[[audits.bridgetree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.5.0 -> 0.6.0" + [[audits.bytemuck]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -94,13 +99,13 @@ delta = "0.3.0 -> 0.4.0" [[audits.equihash]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.2.0 -> 0.2.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.2.0 -> 0.2.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false [[audits.f4jumble]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.1.0 -> 0.1.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.1.0 -> 0.1.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false [[audits.git2]] @@ -128,6 +133,17 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.5.1 -> 0.6.0" +[[audits.incrementalmerkletree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.6.0 -> 0.7.0" + +[[audits.incrementalmerkletree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.7.0 -> 0.7.0@git:ffe4234788fd22662b937ba7c6ea01535fcc1293" +importable = false + [[audits.indexmap]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -208,6 +224,17 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.8.0 -> 0.9.0" +[[audits.orchard]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.9.0 -> 0.10.0" + +[[audits.orchard]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.10.0 -> 0.9.1@git:55fb089a335bbbc1cda186c706bc037073df8eb7" +importable = false + [[audits.owo-colors]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -283,6 +310,17 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.1.3 -> 0.2.0" +[[audits.sapling-crypto]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.0 -> 0.3.0" + +[[audits.sapling-crypto]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.2.0@git:b1ad3694ee13a2fc5d291ad04721a6252da0993c" +importable = false + [[audits.serde_spanned]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -318,6 +356,17 @@ who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.3.1 -> 0.4.0" +[[audits.shardtree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.5.0" + +[[audits.shardtree]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.5.0 -> 0.4.0@git:ffe4234788fd22662b937ba7c6ea01535fcc1293" +importable = false + [[audits.tempfile]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -541,9 +590,14 @@ delta = "0.4.0 -> 0.5.0" [[audits.zcash_address]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.5.0 -> 0.5.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.5.0 -> 0.5.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false +[[audits.zcash_address]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.5.0 -> 0.6.0" + [[audits.zcash_client_backend]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -552,19 +606,35 @@ delta = "0.12.1 -> 0.13.0" [[audits.zcash_client_backend]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.13.0 -> 0.13.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.13.0 -> 0.14.0" + +[[audits.zcash_client_backend]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.14.0 -> 0.13.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false [[audits.zcash_encoding]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.2.1 -> 0.2.1@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.2.1 -> 0.2.1@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false +[[audits.zcash_history]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.4.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" +importable = false + +[[audits.zcash_keys]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.4.0" + [[audits.zcash_keys]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.3.0 -> 0.3.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.4.0 -> 0.3.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false [[audits.zcash_primitives]] @@ -575,14 +645,30 @@ delta = "0.16.0 -> 0.17.0" [[audits.zcash_primitives]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.17.0 -> 0.17.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.17.0 -> 0.17.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false +[[audits.zcash_primitives]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.17.0 -> 0.19.0" + [[audits.zcash_proofs]] who = "Alfredo Garcia " criteria = "safe-to-deploy" delta = "0.16.0 -> 0.17.0" +[[audits.zcash_proofs]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.17.0 -> 0.17.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" +importable = false + +[[audits.zcash_proofs]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.17.0 -> 0.19.0" + [[audits.zcash_protocol]] who = "Alfredo Garcia " criteria = "safe-to-deploy" @@ -596,7 +682,12 @@ delta = "0.1.1 -> 0.3.0" [[audits.zcash_protocol]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.3.0 -> 0.3.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.3.0 -> 0.4.0" + +[[audits.zcash_protocol]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.3.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false [[audits.zebra-chain]] @@ -662,7 +753,12 @@ version = "0.1.0" [[audits.zip321]] who = "Alfredo Garcia " criteria = "safe-to-deploy" -delta = "0.1.0 -> 0.1.0@git:a1047adf0b6f324dad415db34762dc26f8367ce4" +delta = "0.1.0 -> 0.2.0" + +[[audits.zip321]] +who = "Alfredo Garcia " +criteria = "safe-to-deploy" +delta = "0.2.0 -> 0.1.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792" importable = false [[trusted.clap]] diff --git a/supply-chain/config.toml b/supply-chain/config.toml index 7a20193f958..cdbb79de93f 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -16,10 +16,28 @@ url = "https://raw.githubusercontent.com/zcash/rust-ecosystem/main/supply-chain/ [imports.zcashd] url = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" -[policy.equihash] +[policy."equihash:0.2.0"] + +[policy."equihash:0.2.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"] +audit-as-crates-io = true + +[policy."f4jumble:0.1.0"] + +[policy."f4jumble:0.1.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"] +audit-as-crates-io = true + +[policy."incrementalmerkletree:0.6.0"] + +[policy."incrementalmerkletree:0.7.0@git:ffe4234788fd22662b937ba7c6ea01535fcc1293"] audit-as-crates-io = true -[policy.f4jumble] +[policy.orchard] +audit-as-crates-io = true + +[policy.sapling-crypto] +audit-as-crates-io = true + +[policy.shardtree] audit-as-crates-io = true [policy.tower-batch-control] @@ -28,7 +46,9 @@ audit-as-crates-io = true [policy.tower-fallback] audit-as-crates-io = true -[policy.zcash_address] +[policy."zcash_address:0.4.0"] + +[policy."zcash_address:0.5.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"] audit-as-crates-io = true [policy.zcash_client_backend] @@ -37,13 +57,25 @@ audit-as-crates-io = true [policy.zcash_encoding] audit-as-crates-io = true -[policy.zcash_keys] +[policy.zcash_history] audit-as-crates-io = true -[policy.zcash_primitives] +[policy."zcash_keys:0.3.0"] + +[policy."zcash_keys:0.3.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"] audit-as-crates-io = true -[policy.zcash_protocol] +[policy."zcash_primitives:0.16.0"] + +[policy."zcash_primitives:0.17.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"] +audit-as-crates-io = true + +[policy.zcash_proofs] +audit-as-crates-io = true + +[policy."zcash_protocol:0.2.0"] + +[policy."zcash_protocol:0.3.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"] audit-as-crates-io = true [policy.zebra-chain] diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index 3e9b998916a..6ffb22409c3 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -68,7 +68,7 @@ bitflags = "2.5.0" bitflags-serde-legacy = "0.1.1" blake2b_simd = "1.0.2" blake2s_simd = "1.0.2" -bridgetree = "0.5.0" +bridgetree = "0.6.0" bs58 = { version = "0.5.1", features = ["check"] } byteorder = "1.5.0" @@ -88,7 +88,7 @@ primitive-types = "0.12.2" rand_core = "0.6.4" ripemd = "0.1.3" # Matches version used by hdwallet -secp256k1 = { version = "0.26.0", features = ["serde"] } +secp256k1 = { version = "0.27.0", features = ["serde"] } sha2 = { version = "0.10.7", features = ["compress"] } uint = "0.10.0" x25519-dalek = { version = "2.0.1", features = ["serde"] } diff --git a/zebra-scan/Cargo.toml b/zebra-scan/Cargo.toml index 6a5bd10e203..c81c749632f 100644 --- a/zebra-scan/Cargo.toml +++ b/zebra-scan/Cargo.toml @@ -71,11 +71,10 @@ tracing = "0.1.39" futures = "0.3.30" # ECC dependencies. -# TODO: we can't use the workspace version for all ECC dependencies in this crate yet (#8809) -zcash_client_backend = { git = "https://github.com/zcash/librustzcash/", commit = "40ca428c6081c61d5a2bf3f2053eb9e18219ca95" } +zcash_client_backend.workspace = true zcash_keys = { workspace = true, features = ["sapling"] } -zcash_primitives = { git = "https://github.com/zcash/librustzcash/", commit = "40ca428c6081c61d5a2bf3f2053eb9e18219ca95" } -zcash_address = { git = "https://github.com/zcash/librustzcash/", commit = "40ca428c6081c61d5a2bf3f2053eb9e18219ca95" } +zcash_primitives.workspace = true +zcash_address.workspace = true sapling-crypto.workspace = true zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["shielded-scan"] } From f2e7bc95ce8904d06e3a52df49ee3feba179cb98 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 10 Oct 2024 15:26:54 -0300 Subject: [PATCH 44/46] feat(regtest): Add regtest halving interval and port test (#8888) * add halving interval to regtest and to custom testnet * add nuparams.py rpc test * fix inconsistency in nu6 name in rpc methods * rename `halving_interval` to `pre_blossom_halving_interval` in the config * make fixes * Suggestion for "feat(regtest): Add regtest halving interval and port test" (#8894) * adds `height_for_halving_index()` and `num_halvings()` fns * avoid unnecessary panic * avoid using constant pre/post blossom halving intervals in num_halvings() * make regtest and testnet constant more private * move `height_for_halving_index` * fmt * add a `funding_stream_address_change_interval` method * add checked operations to `height_for_halving_index` fn * add post_blossom interval as paramneters + other refactors * rename function * fix docs * move constant * Updates `new_regtest()` method to return a Testnet without funding streams, updates funding stream setter methods to set a flag indicating that parameters affecting the funding stream address period should be locked, updates the setter methods for parameters that affect the funding stream address period to panic if those parameters should be locked. (#8921) --------- Co-authored-by: Arya --- zebra-chain/src/parameters/network/subsidy.rs | 96 ++++++- zebra-chain/src/parameters/network/testnet.rs | 221 ++++++++++----- .../src/parameters/network/tests/vectors.rs | 2 +- zebra-chain/src/parameters/network_upgrade.rs | 1 + zebra-consensus/src/block/subsidy/general.rs | 74 +++-- zebra-network/src/config.rs | 24 +- zebra-rpc/qa/base_config.toml | 4 + zebra-rpc/qa/pull-tester/rpc-tests.py | 3 +- zebra-rpc/qa/rpc-tests/nuparams.py | 266 ++++++++++++++++++ .../get_blockchain_info@testnet_10.snap | 2 +- ..._info_future_nu6_height@nu6testnet_10.snap | 2 +- 11 files changed, 586 insertions(+), 109 deletions(-) create mode 100755 zebra-rpc/qa/rpc-tests/nuparams.py diff --git a/zebra-chain/src/parameters/network/subsidy.rs b/zebra-chain/src/parameters/network/subsidy.rs index c7ff373f55d..cb043f6b05c 100644 --- a/zebra-chain/src/parameters/network/subsidy.rs +++ b/zebra-chain/src/parameters/network/subsidy.rs @@ -48,7 +48,10 @@ pub const POST_BLOSSOM_HALVING_INTERVAL: HeightDiff = /// as specified in [protocol specification §7.10.1][7.10.1] /// /// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams -pub const FIRST_HALVING_TESTNET: Height = Height(1_116_000); +pub(crate) const FIRST_HALVING_TESTNET: Height = Height(1_116_000); + +/// The first halving height in the regtest is at block height `287`. +const FIRST_HALVING_REGTEST: Height = Height(287); /// The funding stream receiver categories. #[derive(Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)] @@ -378,6 +381,20 @@ pub trait ParameterSubsidy { /// /// [7.10]: fn height_for_first_halving(&self) -> Height; + + /// Returns the halving interval after Blossom + fn post_blossom_halving_interval(&self) -> HeightDiff; + + /// Returns the halving interval before Blossom + fn pre_blossom_halving_interval(&self) -> HeightDiff; + + /// Returns the address change interval for funding streams + /// as described in [protocol specification §7.10][7.10]. + /// + /// > FSRecipientChangeInterval := PostBlossomHalvingInterval / 48 + /// + /// [7.10]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams + fn funding_stream_address_change_interval(&self) -> HeightDiff; } /// Network methods related to Block Subsidy and Funding Streams @@ -390,10 +407,35 @@ impl ParameterSubsidy for Network { Network::Mainnet => NetworkUpgrade::Canopy .activation_height(self) .expect("canopy activation height should be available"), - // TODO: Check what zcashd does here, consider adding a field to `testnet::Parameters` to make this configurable. - Network::Testnet(_params) => FIRST_HALVING_TESTNET, + Network::Testnet(params) => { + if params.is_regtest() { + FIRST_HALVING_REGTEST + } else if params.is_default_testnet() { + FIRST_HALVING_TESTNET + } else { + height_for_halving(1, self).expect("first halving height should be available") + } + } + } + } + + fn post_blossom_halving_interval(&self) -> HeightDiff { + match self { + Network::Mainnet => POST_BLOSSOM_HALVING_INTERVAL, + Network::Testnet(params) => params.post_blossom_halving_interval(), + } + } + + fn pre_blossom_halving_interval(&self) -> HeightDiff { + match self { + Network::Mainnet => PRE_BLOSSOM_HALVING_INTERVAL, + Network::Testnet(params) => params.pre_blossom_halving_interval(), } } + + fn funding_stream_address_change_interval(&self) -> HeightDiff { + self.post_blossom_halving_interval() / 48 + } } /// List of addresses for the Zcash Foundation funding stream in the Mainnet. @@ -514,10 +556,54 @@ pub fn funding_stream_address_period(height: Height, networ let height_after_first_halving = height - network.height_for_first_halving(); - let address_period = (height_after_first_halving + POST_BLOSSOM_HALVING_INTERVAL) - / FUNDING_STREAM_ADDRESS_CHANGE_INTERVAL; + let address_period = (height_after_first_halving + network.post_blossom_halving_interval()) + / network.funding_stream_address_change_interval(); address_period .try_into() .expect("all values are positive and smaller than the input height") } + +/// The first block height of the halving at the provided halving index for a network. +/// +/// See `Halving(height)`, as described in [protocol specification §7.8][7.8] +/// +/// [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies +pub fn height_for_halving(halving: u32, network: &Network) -> Option { + if halving == 0 { + return Some(Height(0)); + } + + let slow_start_shift = i64::from(network.slow_start_shift().0); + let blossom_height = i64::from( + NetworkUpgrade::Blossom + .activation_height(network) + .expect("blossom activation height should be available") + .0, + ); + let pre_blossom_halving_interval = network.pre_blossom_halving_interval(); + let halving_index = i64::from(halving); + + let unscaled_height = halving_index + .checked_mul(pre_blossom_halving_interval) + .expect("Multiplication overflow: consider reducing the halving interval"); + + let pre_blossom_height = unscaled_height + .min(blossom_height) + .checked_add(slow_start_shift) + .expect("Addition overflow: consider reducing the halving interval"); + + let post_blossom_height = 0 + .max(unscaled_height - blossom_height) + .checked_mul(i64::from(BLOSSOM_POW_TARGET_SPACING_RATIO)) + .expect("Multiplication overflow: consider reducing the halving interval") + .checked_add(slow_start_shift) + .expect("Addition overflow: consider reducing the halving interval"); + + let height = pre_blossom_height + .checked_add(post_blossom_height) + .expect("Addition overflow: consider reducing the halving interval"); + + let height = u32::try_from(height).ok()?; + height.try_into().ok() +} diff --git a/zebra-chain/src/parameters/network/testnet.rs b/zebra-chain/src/parameters/network/testnet.rs index 80cb8419c77..96ecfcdf3ff 100644 --- a/zebra-chain/src/parameters/network/testnet.rs +++ b/zebra-chain/src/parameters/network/testnet.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, fmt}; use crate::{ - block::{self, Height}, + block::{self, Height, HeightDiff}, parameters::{ constants::{magics, SLOW_START_INTERVAL, SLOW_START_SHIFT}, network_upgrade::TESTNET_ACTIVATION_HEIGHTS, @@ -15,9 +15,11 @@ use crate::{ use super::{ magic::Magic, subsidy::{ - FundingStreamReceiver, FundingStreamRecipient, FundingStreams, ParameterSubsidy, - FIRST_HALVING_TESTNET, POST_NU6_FUNDING_STREAMS_MAINNET, POST_NU6_FUNDING_STREAMS_TESTNET, - PRE_NU6_FUNDING_STREAMS_MAINNET, PRE_NU6_FUNDING_STREAMS_TESTNET, + FundingStreamReceiver, FundingStreamRecipient, FundingStreams, + BLOSSOM_POW_TARGET_SPACING_RATIO, POST_BLOSSOM_HALVING_INTERVAL, + POST_NU6_FUNDING_STREAMS_MAINNET, POST_NU6_FUNDING_STREAMS_TESTNET, + PRE_BLOSSOM_HALVING_INTERVAL, PRE_NU6_FUNDING_STREAMS_MAINNET, + PRE_NU6_FUNDING_STREAMS_TESTNET, }, }; @@ -50,14 +52,9 @@ const REGTEST_GENESIS_HASH: &str = const TESTNET_GENESIS_HASH: &str = "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38"; -/// Used to validate number of funding stream recipient addresses on configured Testnets. -struct TestnetParameterSubsidyImpl; - -impl ParameterSubsidy for TestnetParameterSubsidyImpl { - fn height_for_first_halving(&self) -> Height { - FIRST_HALVING_TESTNET - } -} +/// The halving height interval in the regtest is 6 hours. +/// [zcashd regtest halving interval](https://github.com/zcash/zcash/blob/v5.10.0/src/consensus/params.h#L252) +const PRE_BLOSSOM_REGTEST_HALVING_INTERVAL: HeightDiff = 144; /// Configurable funding stream recipient for configured Testnets. #[derive(Deserialize, Clone, Debug)] @@ -94,7 +91,12 @@ pub struct ConfiguredFundingStreams { impl ConfiguredFundingStreams { /// Converts a [`ConfiguredFundingStreams`] to a [`FundingStreams`], using the provided default values /// if `height_range` or `recipients` are None. - fn convert_with_default(self, default_funding_streams: FundingStreams) -> FundingStreams { + fn convert_with_default( + self, + default_funding_streams: FundingStreams, + parameters_builder: &ParametersBuilder, + ) -> FundingStreams { + let network = parameters_builder.to_network_unchecked(); let height_range = self .height_range .unwrap_or(default_funding_streams.height_range().clone()); @@ -116,43 +118,7 @@ impl ConfiguredFundingStreams { let funding_streams = FundingStreams::new(height_range.clone(), recipients); - // check that receivers have enough addresses. - - let expected_min_num_addresses = - 1u32.checked_add(funding_stream_address_period( - height_range - .end - .previous() - .expect("end height must be above start height and genesis height"), - &TestnetParameterSubsidyImpl, - )) - .expect("no overflow should happen in this sum") - .checked_sub(funding_stream_address_period( - height_range.start, - &TestnetParameterSubsidyImpl, - )) - .expect("no overflow should happen in this sub") as usize; - - for (&receiver, recipient) in funding_streams.recipients() { - if receiver == FundingStreamReceiver::Deferred { - // The `Deferred` receiver doesn't need any addresses. - continue; - } - - assert!( - recipient.addresses().len() >= expected_min_num_addresses, - "recipients must have a sufficient number of addresses for height range, \ - minimum num addresses required: {expected_min_num_addresses}" - ); - - for address in recipient.addresses() { - assert_eq!( - address.network_kind(), - NetworkKind::Testnet, - "configured funding stream addresses must be for Testnet" - ); - } - } + check_funding_stream_address_period(&funding_streams, &network); // check that sum of receiver numerators is valid. @@ -172,6 +138,44 @@ impl ConfiguredFundingStreams { } } +/// Checks that the provided [`FundingStreams`] has sufficient recipient addresses for the +/// funding stream address period of the provided [`Network`]. +fn check_funding_stream_address_period(funding_streams: &FundingStreams, network: &Network) { + let height_range = funding_streams.height_range(); + let expected_min_num_addresses = + 1u32.checked_add(funding_stream_address_period( + height_range + .end + .previous() + .expect("end height must be above start height and genesis height"), + network, + )) + .expect("no overflow should happen in this sum") + .checked_sub(funding_stream_address_period(height_range.start, network)) + .expect("no overflow should happen in this sub") as usize; + + for (&receiver, recipient) in funding_streams.recipients() { + if receiver == FundingStreamReceiver::Deferred { + // The `Deferred` receiver doesn't need any addresses. + continue; + } + + assert!( + recipient.addresses().len() >= expected_min_num_addresses, + "recipients must have a sufficient number of addresses for height range, \ + minimum num addresses required: {expected_min_num_addresses}" + ); + + for address in recipient.addresses() { + assert_eq!( + address.network_kind(), + NetworkKind::Testnet, + "configured funding stream addresses must be for Testnet" + ); + } + } +} + /// Configurable activation heights for Regtest and configured Testnets. #[derive(Deserialize, Default, Clone)] #[serde(rename_all = "PascalCase", deny_unknown_fields)] @@ -213,10 +217,17 @@ pub struct ParametersBuilder { pre_nu6_funding_streams: FundingStreams, /// Post-NU6 funding streams for this network post_nu6_funding_streams: FundingStreams, + /// A flag indicating whether to allow changes to fields that affect + /// the funding stream address period. + should_lock_funding_stream_address_period: bool, /// Target difficulty limit for this network target_difficulty_limit: ExpandedDifficulty, /// A flag for disabling proof-of-work checks when Zebra is validating blocks disable_pow: bool, + /// The pre-Blossom halving interval for this network + pre_blossom_halving_interval: HeightDiff, + /// The post-Blossom halving interval for this network + post_blossom_halving_interval: HeightDiff, } impl Default for ParametersBuilder { @@ -249,6 +260,9 @@ impl Default for ParametersBuilder { disable_pow: false, pre_nu6_funding_streams: PRE_NU6_FUNDING_STREAMS_TESTNET.clone(), post_nu6_funding_streams: POST_NU6_FUNDING_STREAMS_TESTNET.clone(), + should_lock_funding_stream_address_period: false, + pre_blossom_halving_interval: PRE_BLOSSOM_HALVING_INTERVAL, + post_blossom_halving_interval: POST_BLOSSOM_HALVING_INTERVAL, } } } @@ -318,6 +332,10 @@ impl ParametersBuilder { ) -> Self { use NetworkUpgrade::*; + if self.should_lock_funding_stream_address_period { + panic!("activation heights on ParametersBuilder must not be set after setting funding streams"); + } + // # Correctness // // These must be in order so that later network upgrades overwrite prior ones @@ -377,7 +395,8 @@ impl ParametersBuilder { funding_streams: ConfiguredFundingStreams, ) -> Self { self.pre_nu6_funding_streams = - funding_streams.convert_with_default(PRE_NU6_FUNDING_STREAMS_TESTNET.clone()); + funding_streams.convert_with_default(PRE_NU6_FUNDING_STREAMS_TESTNET.clone(), &self); + self.should_lock_funding_stream_address_period = true; self } @@ -387,7 +406,8 @@ impl ParametersBuilder { funding_streams: ConfiguredFundingStreams, ) -> Self { self.post_nu6_funding_streams = - funding_streams.convert_with_default(POST_NU6_FUNDING_STREAMS_TESTNET.clone()); + funding_streams.convert_with_default(POST_NU6_FUNDING_STREAMS_TESTNET.clone(), &self); + self.should_lock_funding_stream_address_period = true; self } @@ -411,8 +431,20 @@ impl ParametersBuilder { self } + /// Sets the pre and post Blosssom halving intervals to be used in the [`Parameters`] being built. + pub fn with_halving_interval(mut self, pre_blossom_halving_interval: HeightDiff) -> Self { + if self.should_lock_funding_stream_address_period { + panic!("halving interval on ParametersBuilder must not be set after setting funding streams"); + } + + self.pre_blossom_halving_interval = pre_blossom_halving_interval; + self.post_blossom_halving_interval = + self.pre_blossom_halving_interval * (BLOSSOM_POW_TARGET_SPACING_RATIO as HeightDiff); + self + } + /// Converts the builder to a [`Parameters`] struct - pub fn finish(self) -> Parameters { + fn finish(self) -> Parameters { let Self { network_name, network_magic, @@ -421,8 +453,11 @@ impl ParametersBuilder { slow_start_interval, pre_nu6_funding_streams, post_nu6_funding_streams, + should_lock_funding_stream_address_period: _, target_difficulty_limit, disable_pow, + pre_blossom_halving_interval, + post_blossom_halving_interval, } = self; Parameters { network_name, @@ -435,12 +470,29 @@ impl ParametersBuilder { post_nu6_funding_streams, target_difficulty_limit, disable_pow, + pre_blossom_halving_interval, + post_blossom_halving_interval, } } /// Converts the builder to a configured [`Network::Testnet`] + fn to_network_unchecked(&self) -> Network { + Network::new_configured_testnet(self.clone().finish()) + } + + /// Checks funding streams and converts the builder to a configured [`Network::Testnet`] pub fn to_network(self) -> Network { - Network::new_configured_testnet(self.finish()) + let network = self.to_network_unchecked(); + + // Final check that the configured funding streams will be valid for these Testnet parameters. + // TODO: Always check funding stream address period once the testnet parameters are being serialized (#8920). + #[cfg(not(any(test, feature = "proptest-impl")))] + { + check_funding_stream_address_period(&self.pre_nu6_funding_streams, &network); + check_funding_stream_address_period(&self.post_nu6_funding_streams, &network); + } + + network } /// Returns true if these [`Parameters`] should be compatible with the default Testnet parameters. @@ -453,8 +505,11 @@ impl ParametersBuilder { slow_start_interval, pre_nu6_funding_streams, post_nu6_funding_streams, + should_lock_funding_stream_address_period: _, target_difficulty_limit, disable_pow, + pre_blossom_halving_interval, + post_blossom_halving_interval, } = Self::default(); self.activation_heights == activation_heights @@ -465,6 +520,8 @@ impl ParametersBuilder { && self.post_nu6_funding_streams == post_nu6_funding_streams && self.target_difficulty_limit == target_difficulty_limit && self.disable_pow == disable_pow + && self.pre_blossom_halving_interval == pre_blossom_halving_interval + && self.post_blossom_halving_interval == post_blossom_halving_interval } } @@ -495,6 +552,10 @@ pub struct Parameters { target_difficulty_limit: ExpandedDifficulty, /// A flag for disabling proof-of-work checks when Zebra is validating blocks disable_pow: bool, + /// Pre-Blossom halving interval for this network + pre_blossom_halving_interval: HeightDiff, + /// Post-Blossom halving interval for this network + post_blossom_halving_interval: HeightDiff, } impl Default for Parameters { @@ -523,24 +584,32 @@ impl Parameters { #[cfg(any(test, feature = "proptest-impl"))] let nu5_activation_height = nu5_activation_height.or(Some(100)); + let parameters = Self::build() + .with_genesis_hash(REGTEST_GENESIS_HASH) + // This value is chosen to match zcashd, see: + .with_target_difficulty_limit(U256::from_big_endian(&[0x0f; 32])) + .with_disable_pow(true) + .with_slow_start_interval(Height::MIN) + // Removes default Testnet activation heights if not configured, + // most network upgrades are disabled by default for Regtest in zcashd + .with_activation_heights(ConfiguredActivationHeights { + canopy: Some(1), + nu5: nu5_activation_height, + nu6: nu6_activation_height, + ..Default::default() + }) + .with_halving_interval(PRE_BLOSSOM_REGTEST_HALVING_INTERVAL); + + // TODO: Always clear funding streams on Regtest once the testnet parameters are being serialized (#8920). + #[cfg(not(any(test, feature = "proptest-impl")))] + let parameters = parameters + .with_pre_nu6_funding_streams(ConfiguredFundingStreams::default()) + .with_post_nu6_funding_streams(ConfiguredFundingStreams::default()); + Self { network_name: "Regtest".to_string(), network_magic: magics::REGTEST, - ..Self::build() - .with_genesis_hash(REGTEST_GENESIS_HASH) - // This value is chosen to match zcashd, see: - .with_target_difficulty_limit(U256::from_big_endian(&[0x0f; 32])) - .with_disable_pow(true) - .with_slow_start_interval(Height::MIN) - // Removes default Testnet activation heights if not configured, - // most network upgrades are disabled by default for Regtest in zcashd - .with_activation_heights(ConfiguredActivationHeights { - canopy: Some(1), - nu5: nu5_activation_height, - nu6: nu6_activation_height, - ..Default::default() - }) - .finish() + ..parameters.finish() } } @@ -568,6 +637,8 @@ impl Parameters { post_nu6_funding_streams, target_difficulty_limit, disable_pow, + pre_blossom_halving_interval, + post_blossom_halving_interval, } = Self::new_regtest(None, None); self.network_name == network_name @@ -578,6 +649,8 @@ impl Parameters { && self.post_nu6_funding_streams == post_nu6_funding_streams && self.target_difficulty_limit == target_difficulty_limit && self.disable_pow == disable_pow + && self.pre_blossom_halving_interval == pre_blossom_halving_interval + && self.post_blossom_halving_interval == post_blossom_halving_interval } /// Returns the network name @@ -629,6 +702,16 @@ impl Parameters { pub fn disable_pow(&self) -> bool { self.disable_pow } + + /// Returns the pre-Blossom halving interval for this network + pub fn pre_blossom_halving_interval(&self) -> HeightDiff { + self.pre_blossom_halving_interval + } + + /// Returns the post-Blossom halving interval for this network + pub fn post_blossom_halving_interval(&self) -> HeightDiff { + self.post_blossom_halving_interval + } } impl Network { diff --git a/zebra-chain/src/parameters/network/tests/vectors.rs b/zebra-chain/src/parameters/network/tests/vectors.rs index c839a26c116..4282c86844f 100644 --- a/zebra-chain/src/parameters/network/tests/vectors.rs +++ b/zebra-chain/src/parameters/network/tests/vectors.rs @@ -139,7 +139,7 @@ fn activates_network_upgrades_correctly() { let expected_default_regtest_activation_heights = &[ (Height(0), NetworkUpgrade::Genesis), (Height(1), NetworkUpgrade::Canopy), - // TODO: Remove this once the testnet parameters are being serialized. + // TODO: Remove this once the testnet parameters are being serialized (#8920). (Height(100), NetworkUpgrade::Nu5), ]; diff --git a/zebra-chain/src/parameters/network_upgrade.rs b/zebra-chain/src/parameters/network_upgrade.rs index 356ae86577f..957b96de944 100644 --- a/zebra-chain/src/parameters/network_upgrade.rs +++ b/zebra-chain/src/parameters/network_upgrade.rs @@ -59,6 +59,7 @@ pub enum NetworkUpgrade { #[serde(rename = "NU5")] Nu5, /// The Zcash protocol after the NU6 upgrade. + #[serde(rename = "NU6")] Nu6, } diff --git a/zebra-consensus/src/block/subsidy/general.rs b/zebra-consensus/src/block/subsidy/general.rs index 03ebac36d21..d871751da34 100644 --- a/zebra-consensus/src/block/subsidy/general.rs +++ b/zebra-consensus/src/block/subsidy/general.rs @@ -23,40 +23,39 @@ use crate::{block::SubsidyError, funding_stream_values}; /// /// Returns `None` if the divisor would overflow a `u64`. pub fn halving_divisor(height: Height, network: &Network) -> Option { + // Some far-future shifts can be more than 63 bits + 1u64.checked_shl(num_halvings(height, network)) +} + +/// The halving index for a block height and network. +/// +/// `Halving(height)`, as described in [protocol specification §7.8][7.8] +/// +/// [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies +pub fn num_halvings(height: Height, network: &Network) -> u32 { + let slow_start_shift = network.slow_start_shift(); let blossom_height = Blossom .activation_height(network) .expect("blossom activation height should be available"); - if height < blossom_height { - let pre_blossom_height = height - network.slow_start_shift(); - let halving_shift = pre_blossom_height / PRE_BLOSSOM_HALVING_INTERVAL; - - let halving_div = 1u64 - .checked_shl( - halving_shift - .try_into() - .expect("already checked for negatives"), - ) - .expect("pre-blossom heights produce small shifts"); - - Some(halving_div) + let halving_index = if height < slow_start_shift { + 0 + } else if height < blossom_height { + let pre_blossom_height = height - slow_start_shift; + pre_blossom_height / network.pre_blossom_halving_interval() } else { - let pre_blossom_height = blossom_height - network.slow_start_shift(); + let pre_blossom_height = blossom_height - slow_start_shift; let scaled_pre_blossom_height = pre_blossom_height * HeightDiff::from(BLOSSOM_POW_TARGET_SPACING_RATIO); let post_blossom_height = height - blossom_height; - let halving_shift = - (scaled_pre_blossom_height + post_blossom_height) / POST_BLOSSOM_HALVING_INTERVAL; + (scaled_pre_blossom_height + post_blossom_height) / network.post_blossom_halving_interval() + }; - // Some far-future shifts can be more than 63 bits - 1u64.checked_shl( - halving_shift - .try_into() - .expect("already checked for negatives"), - ) - } + halving_index + .try_into() + .expect("already checked for negatives") } /// `BlockSubsidy(height)` as described in [protocol specification §7.8][7.8] @@ -503,4 +502,33 @@ mod test { Ok(()) } + + #[test] + fn check_height_for_num_halvings() { + for network in Network::iter() { + for halving in 1..1000 { + let Some(height_for_halving) = + zebra_chain::parameters::subsidy::height_for_halving(halving, &network) + else { + panic!("could not find height for halving {halving}"); + }; + + let prev_height = height_for_halving + .previous() + .expect("there should be a previous height"); + + assert_eq!( + halving, + num_halvings(height_for_halving, &network), + "num_halvings should match the halving index" + ); + + assert_eq!( + halving - 1, + num_halvings(prev_height, &network), + "num_halvings for the prev height should be 1 less than the halving index" + ); + } + } + } } diff --git a/zebra-network/src/config.rs b/zebra-network/src/config.rs index 7936ea0e787..8619507fa0d 100644 --- a/zebra-network/src/config.rs +++ b/zebra-network/src/config.rs @@ -597,6 +597,7 @@ impl<'de> Deserialize<'de> for Config { activation_heights: Option, pre_nu6_funding_streams: Option, post_nu6_funding_streams: Option, + pre_blossom_halving_interval: Option, } #[derive(Deserialize)] @@ -686,6 +687,7 @@ impl<'de> Deserialize<'de> for Config { activation_heights, pre_nu6_funding_streams, post_nu6_funding_streams, + pre_blossom_halving_interval, }), ) => { let mut params_builder = testnet::Parameters::build(); @@ -708,14 +710,6 @@ impl<'de> Deserialize<'de> for Config { ); } - if let Some(funding_streams) = pre_nu6_funding_streams { - params_builder = params_builder.with_pre_nu6_funding_streams(funding_streams); - } - - if let Some(funding_streams) = post_nu6_funding_streams { - params_builder = params_builder.with_post_nu6_funding_streams(funding_streams); - } - if let Some(target_difficulty_limit) = target_difficulty_limit.clone() { params_builder = params_builder.with_target_difficulty_limit( target_difficulty_limit @@ -733,6 +727,20 @@ impl<'de> Deserialize<'de> for Config { params_builder = params_builder.with_activation_heights(activation_heights) } + if let Some(halving_interval) = pre_blossom_halving_interval { + params_builder = params_builder.with_halving_interval(halving_interval.into()) + } + + // Set configured funding streams after setting any parameters that affect the funding stream address period. + + if let Some(funding_streams) = pre_nu6_funding_streams { + params_builder = params_builder.with_pre_nu6_funding_streams(funding_streams); + } + + if let Some(funding_streams) = post_nu6_funding_streams { + params_builder = params_builder.with_post_nu6_funding_streams(funding_streams); + } + // Return an error if the initial testnet peers includes any of the default initial Mainnet or Testnet // peers and the configured network parameters are incompatible with the default public Testnet. if !params_builder.is_compatible_with_default_parameters() diff --git a/zebra-rpc/qa/base_config.toml b/zebra-rpc/qa/base_config.toml index 502a2a75b1d..c0cc5391f4b 100644 --- a/zebra-rpc/qa/base_config.toml +++ b/zebra-rpc/qa/base_config.toml @@ -10,3 +10,7 @@ listen_addr = "127.0.0.1:0" [state] cache_dir = "" + +[network.testnet_parameters.activation_heights] +NU5 = 290 +NU6 = 291 diff --git a/zebra-rpc/qa/pull-tester/rpc-tests.py b/zebra-rpc/qa/pull-tester/rpc-tests.py index 00194f0aa53..e8f48ac9861 100755 --- a/zebra-rpc/qa/pull-tester/rpc-tests.py +++ b/zebra-rpc/qa/pull-tester/rpc-tests.py @@ -39,7 +39,8 @@ # Scripts that are run by the travis build process # Longest test should go first, to favor running tests in parallel 'reindex.py', - 'getmininginfo.py'] + 'getmininginfo.py', + 'nuparams.py'] ZMQ_SCRIPTS = [ # ZMQ test can only be run if bitcoin was built with zmq-enabled. diff --git a/zebra-rpc/qa/rpc-tests/nuparams.py b/zebra-rpc/qa/rpc-tests/nuparams.py new file mode 100755 index 00000000000..5ed74e4ac34 --- /dev/null +++ b/zebra-rpc/qa/rpc-tests/nuparams.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + start_nodes, + nuparams, + nustr, + OVERWINTER_BRANCH_ID, + SAPLING_BRANCH_ID, + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + NU6_BRANCH_ID, +) +from decimal import Decimal + + +class NuparamsTest(BitcoinTestFramework): + ''' + Test that unspecified network upgrades are activated automatically; + this is really more of a test of the test framework. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.cache_behavior = 'clean' + + def setup_network(self, split=False): + args = [[] * self.num_nodes] + + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, args) + self.is_network_split = False + self.sync_all() + + def run_test(self): + node = self.nodes[0] + # No blocks have been created, only the genesis block exists (height 0) + bci = node.getblockchaininfo() + print(bci) + assert_equal(bci['blocks'], 0) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'pending') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'pending') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 1) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 1) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 1) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 290) + assert_equal(nu5['status'], 'pending') + + nu6 = upgrades[nustr(NU6_BRANCH_ID)] + assert_equal(nu6['name'], 'NU6') + assert_equal(nu6['activationheight'], 291) + assert_equal(nu6['status'], 'pending') + + # Zebra can't call `getblocksubsidy` before the first halving. + + # Zebra regtest mode hardcodes Canopy, Heartwood, Blossom, Sapling and Overwinter + # to activate at height 1. + node.generate(1) + + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 1) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 1) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 1) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 1) + assert_equal(canopy['status'], 'active') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 290) + assert_equal(nu5['status'], 'pending') + + nu6 = upgrades[nustr(NU6_BRANCH_ID)] + assert_equal(nu6['name'], 'NU6') + assert_equal(nu6['activationheight'], 291) + assert_equal(nu6['status'], 'pending') + + # Zebra can't call `getblocksubsidy` before the first halving. + + # Activate First Halving + node.generate(287) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 288) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 1) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 1) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 1) + assert_equal(canopy['status'], 'active') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 290) + assert_equal(nu5['status'], 'pending') + + nu6 = upgrades[nustr(NU6_BRANCH_ID)] + assert_equal(nu6['name'], 'NU6') + assert_equal(nu6['activationheight'], 291) + assert_equal(nu6['status'], 'pending') + + # The founders' reward ends at Canopy and there are no funding streams + # configured by default for regtest. + assert_equal(node.getblocksubsidy()["miner"], Decimal("3.125")) + + # Activate NU5 + node.generate(2) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 290) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 1) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 1) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 1) + assert_equal(canopy['status'], 'active') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 290) + assert_equal(nu5['status'], 'active') + + nu6 = upgrades[nustr(NU6_BRANCH_ID)] + assert_equal(nu6['name'], 'NU6') + assert_equal(nu6['activationheight'], 291) + assert_equal(nu6['status'], 'pending') + + # Block subsidy remains the same after NU5 + assert_equal(node.getblocksubsidy()["miner"], Decimal("3.125")) + + # Activate NU6 + node.generate(1) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 291) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 1) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 1) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 1) + assert_equal(canopy['status'], 'active') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 290) + assert_equal(nu5['status'], 'active') + + nu6 = upgrades[nustr(NU6_BRANCH_ID)] + assert_equal(nu6['name'], 'NU6') + assert_equal(nu6['activationheight'], 291) + assert_equal(nu6['status'], 'active') + + # Block subsidy remains the same after NU6 as there are not funding streams + # nor lockbox configured by default for regtest. + assert_equal(node.getblocksubsidy()["miner"], Decimal("3.125")) + +if __name__ == '__main__': + NuparamsTest().main() \ No newline at end of file diff --git a/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info@testnet_10.snap b/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info@testnet_10.snap index 0460bb7420f..3bea6c01509 100644 --- a/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info@testnet_10.snap +++ b/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info@testnet_10.snap @@ -66,7 +66,7 @@ expression: info "status": "pending" }, "c8e71055": { - "name": "Nu6", + "name": "NU6", "activationheight": 2976000, "status": "pending" } diff --git a/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info_future_nu6_height@nu6testnet_10.snap b/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info_future_nu6_height@nu6testnet_10.snap index 78e70ab5e26..0f4f6fe26a6 100644 --- a/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info_future_nu6_height@nu6testnet_10.snap +++ b/zebra-rpc/src/methods/tests/snapshots/get_blockchain_info_future_nu6_height@nu6testnet_10.snap @@ -66,7 +66,7 @@ expression: info "status": "pending" }, "c8e71055": { - "name": "Nu6", + "name": "NU6", "activationheight": 2976000, "status": "pending" } From fea9f46fbb199f2eb7d5c798f21ffb4f316c5d25 Mon Sep 17 00:00:00 2001 From: Arya Date: Thu, 10 Oct 2024 19:34:42 -0400 Subject: [PATCH 45/46] Fixes a panic (#8928) --- zebra-chain/src/parameters/network/testnet.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/zebra-chain/src/parameters/network/testnet.rs b/zebra-chain/src/parameters/network/testnet.rs index 96ecfcdf3ff..52d5d18f74a 100644 --- a/zebra-chain/src/parameters/network/testnet.rs +++ b/zebra-chain/src/parameters/network/testnet.rs @@ -89,6 +89,14 @@ pub struct ConfiguredFundingStreams { } impl ConfiguredFundingStreams { + /// Returns an empty [`ConfiguredFundingStreams`]. + fn empty() -> Self { + Self { + height_range: None, + recipients: Some(Vec::new()), + } + } + /// Converts a [`ConfiguredFundingStreams`] to a [`FundingStreams`], using the provided default values /// if `height_range` or `recipients` are None. fn convert_with_default( @@ -601,10 +609,10 @@ impl Parameters { .with_halving_interval(PRE_BLOSSOM_REGTEST_HALVING_INTERVAL); // TODO: Always clear funding streams on Regtest once the testnet parameters are being serialized (#8920). - #[cfg(not(any(test, feature = "proptest-impl")))] + // #[cfg(not(any(test, feature = "proptest-impl")))] let parameters = parameters - .with_pre_nu6_funding_streams(ConfiguredFundingStreams::default()) - .with_post_nu6_funding_streams(ConfiguredFundingStreams::default()); + .with_pre_nu6_funding_streams(ConfiguredFundingStreams::empty()) + .with_post_nu6_funding_streams(ConfiguredFundingStreams::empty()); Self { network_name: "Regtest".to_string(), From b89492168aa7c49bcee6276aa507513d31cba8c0 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Fri, 11 Oct 2024 14:21:07 -0300 Subject: [PATCH 46/46] Release Zebra (`v2.0.0-rc.0`) (#8927) * changelog * add panic fix to changelog * Apply suggestions from code review Co-authored-by: Arya * chore: Release * update release-crates-dry-run workflow script * fix command in release script * change end of support --------- Co-authored-by: Arya --- .../scripts/release-crates-dry-run.sh | 9 ++--- CHANGELOG.md | 36 +++++++++++++++++++ Cargo.lock | 28 +++++++-------- tower-batch-control/Cargo.toml | 6 ++-- tower-fallback/Cargo.toml | 4 +-- zebra-chain/Cargo.toml | 6 ++-- zebra-consensus/Cargo.toml | 20 +++++------ zebra-grpc/Cargo.toml | 6 ++-- zebra-network/Cargo.toml | 4 +-- zebra-node-services/Cargo.toml | 4 +-- zebra-rpc/Cargo.toml | 24 ++++++------- zebra-scan/Cargo.toml | 20 +++++------ zebra-script/Cargo.toml | 6 ++-- zebra-state/Cargo.toml | 10 +++--- zebra-test/Cargo.toml | 2 +- zebra-utils/Cargo.toml | 8 ++--- zebrad/Cargo.toml | 30 ++++++++-------- zebrad/src/components/sync/end_of_support.rs | 6 ++-- 18 files changed, 133 insertions(+), 96 deletions(-) diff --git a/.github/workflows/scripts/release-crates-dry-run.sh b/.github/workflows/scripts/release-crates-dry-run.sh index 7f13647c65e..434e2156acb 100755 --- a/.github/workflows/scripts/release-crates-dry-run.sh +++ b/.github/workflows/scripts/release-crates-dry-run.sh @@ -20,14 +20,15 @@ fi # We use the same commands as the [release drafter](https://github.com/ZcashFoundation/zebra/blob/main/.github/PULL_REQUEST_TEMPLATE/release-checklist.md#update-crate-versions) # with an extra `--no-confirm` argument for non-interactive testing. # Update everything except for alpha crates and zebrad: -cargo release version --verbose --execute --no-confirm --allow-branch '*' --workspace --exclude zebrad --exclude zebra-scan --exclude zebra-grpc beta +cargo release version --verbose --execute --no-confirm --allow-branch '*' --workspace --exclude zebrad --exclude zebra-scan --exclude zebra-grpc patch # Due to a bug in cargo-release, we need to pass exact versions for alpha crates: -cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-scan 0.1.0-alpha.8 -cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-grpc 0.1.0-alpha.6 +cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-scan 0.1.0-alpha.9 +cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-grpc 0.1.0-alpha.7 # Update zebrad: -cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebrad patch +# TODO: Revert `2.0.0-rc.0` to `patch` in the next release candidate. +cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebrad 2.0.0-rc.0 # Continue with the release process: cargo release replace --verbose --execute --no-confirm --allow-branch '*' --package zebrad cargo release commit --verbose --execute --no-confirm --allow-branch '*' diff --git a/CHANGELOG.md b/CHANGELOG.md index 649b14fd26f..5b7d53e5c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,42 @@ All notable changes to Zebra are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org). +## [Zebra 2.0.0-rc.0](https://github.com/ZcashFoundation/zebra/releases/tag/v2.0.0-rc.0) - 2024-10-11 + +This version is a release candidate for the Zcash NU6 network upgrade on the Mainnet. While this version does not yet include the NU6 Mainnet activation height or current protocol version, all required functionality and tests are in place. + +Please note that support for this release candidate is expected to conclude prior to the NU6 activation heights. + +### Security + +- Added Docker Scout vulnerabilities scanning ([#8871](https://github.com/ZcashFoundation/zebra/pull/8871)) + +### Added + +- Added Regtest-only `generate` and `stop` RPC methods ([#8849](https://github.com/ZcashFoundation/zebra/pull/8849), [#8839](https://github.com/ZcashFoundation/zebra/pull/8839), [#8863](https://github.com/ZcashFoundation/zebra/pull/8863)) +- Added fields to `getmininginfo` RPC method response ([#8860](https://github.com/ZcashFoundation/zebra/pull/8860)) +- Copied the Python RPC test framework from zcashd into Zebra ([#8866](https://github.com/ZcashFoundation/zebra/pull/8866)) + +### Changed + +- Regtest halving interval to match zcashd and added a configurable halving interval for custom testnets ([#8888](https://github.com/ZcashFoundation/zebra/pull/8888), [#8928](https://github.com/ZcashFoundation/zebra/pull/8928)) +- Updates post-NU6 Major Grants funding stream address on Mainnet ([#8914](https://github.com/ZcashFoundation/zebra/pull/8914)) + +### Fixed + +- Remove debugging output by default in Docker image ([#8870](https://github.com/ZcashFoundation/zebra/pull/8870)) +- Fixes a typo in configuration file path of the docker-compose file ([#8893](https://github.com/ZcashFoundation/zebra/pull/8893)) +- Return verification errors from `sendrawtransaction` RPC method ([#8788](https://github.com/ZcashFoundation/zebra/pull/8788)) +- Respond to getheaders requests with a maximum of 160 block headers ([#8913](https://github.com/ZcashFoundation/zebra/pull/8913)) +- Avoids panicking during contextual validation when a parent block is missing ([#8883](https://github.com/ZcashFoundation/zebra/pull/8883)) +- Write database format version to disk atomically to avoid a rare panic ([#8795](https://github.com/ZcashFoundation/zebra/pull/8795)) + +### Contributors + +Thank you to everyone who contributed to this release, we couldn't make Zebra without you: +@arya2, @dismad, @gustavovalverde, @oxarbitrage, @skyl and @upbqdn + + ## [Zebra 1.9.0](https://github.com/ZcashFoundation/zebra/releases/tag/v1.9.0) - 2024-08-02 This release includes deployment of NU6 on Testnet, configurable funding streams on custom Testnets, and updates Zebra's end-of-support (EoS) diff --git a/Cargo.lock b/Cargo.lock index 2572faa0e18..2f4c89b1703 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4734,7 +4734,7 @@ dependencies = [ [[package]] name = "tower-batch-control" -version = "0.2.41-beta.15" +version = "0.2.41-beta.16" dependencies = [ "color-eyre", "ed25519-zebra", @@ -4757,7 +4757,7 @@ dependencies = [ [[package]] name = "tower-fallback" -version = "0.2.41-beta.15" +version = "0.2.41-beta.16" dependencies = [ "futures-core", "pin-project", @@ -5881,7 +5881,7 @@ dependencies = [ [[package]] name = "zebra-chain" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "bitflags 2.6.0", "bitflags-serde-legacy", @@ -5946,7 +5946,7 @@ dependencies = [ [[package]] name = "zebra-consensus" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "bellman", "blake2b_simd", @@ -5992,7 +5992,7 @@ dependencies = [ [[package]] name = "zebra-grpc" -version = "0.1.0-alpha.6" +version = "0.1.0-alpha.7" dependencies = [ "color-eyre", "futures-util", @@ -6014,7 +6014,7 @@ dependencies = [ [[package]] name = "zebra-network" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "bitflags 2.6.0", "byteorder", @@ -6055,7 +6055,7 @@ dependencies = [ [[package]] name = "zebra-node-services" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "color-eyre", "jsonrpc-core", @@ -6068,7 +6068,7 @@ dependencies = [ [[package]] name = "zebra-rpc" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "chrono", "futures", @@ -6105,7 +6105,7 @@ dependencies = [ [[package]] name = "zebra-scan" -version = "0.1.0-alpha.8" +version = "0.1.0-alpha.9" dependencies = [ "bls12_381", "chrono", @@ -6151,7 +6151,7 @@ dependencies = [ [[package]] name = "zebra-script" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "hex", "lazy_static", @@ -6163,7 +6163,7 @@ dependencies = [ [[package]] name = "zebra-state" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "bincode", "chrono", @@ -6208,7 +6208,7 @@ dependencies = [ [[package]] name = "zebra-test" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "color-eyre", "futures", @@ -6236,7 +6236,7 @@ dependencies = [ [[package]] name = "zebra-utils" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" dependencies = [ "color-eyre", "hex", @@ -6267,7 +6267,7 @@ dependencies = [ [[package]] name = "zebrad" -version = "1.9.0" +version = "2.0.0-rc.0" dependencies = [ "abscissa_core", "atty", diff --git a/tower-batch-control/Cargo.toml b/tower-batch-control/Cargo.toml index 09b959fb5ed..8bcc9a3ba34 100644 --- a/tower-batch-control/Cargo.toml +++ b/tower-batch-control/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tower-batch-control" -version = "0.2.41-beta.15" +version = "0.2.41-beta.16" authors = ["Zcash Foundation ", "Tower Maintainers "] description = "Tower middleware for batch request processing" # # Legal @@ -43,10 +43,10 @@ rand = "0.8.5" tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } tokio-test = "0.4.4" -tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.15" } +tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.16" } tower-test = "0.4.0" -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] } diff --git a/tower-fallback/Cargo.toml b/tower-fallback/Cargo.toml index 4ddf8a8401d..a3078d916cc 100644 --- a/tower-fallback/Cargo.toml +++ b/tower-fallback/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tower-fallback" -version = "0.2.41-beta.15" +version = "0.2.41-beta.16" authors = ["Zcash Foundation "] description = "A Tower service combinator that sends requests to a first service, then retries processing on a second fallback service if the first service errors." license = "MIT OR Apache-2.0" @@ -24,4 +24,4 @@ tracing = "0.1.39" [dev-dependencies] tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" } diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index 6ffb22409c3..3f932ea298a 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-chain" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "Core Zcash data structures" license = "MIT OR Apache-2.0" @@ -145,7 +145,7 @@ proptest-derive = { version = "0.5.0", optional = true } rand = { version = "0.8.5", optional = true } rand_chacha = { version = "0.3.1", optional = true } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39", optional = true } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40", optional = true } [dev-dependencies] # Benchmarks @@ -168,7 +168,7 @@ rand_chacha = "0.3.1" tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" } [[bench]] name = "block" diff --git a/zebra-consensus/Cargo.toml b/zebra-consensus/Cargo.toml index 3914087e997..ba71369d060 100644 --- a/zebra-consensus/Cargo.toml +++ b/zebra-consensus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-consensus" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "Implementation of Zcash consensus checks" license = "MIT OR Apache-2.0" @@ -63,13 +63,13 @@ orchard.workspace = true zcash_proofs = { workspace = true, features = ["multicore" ] } wagyu-zcash-parameters = "0.2.0" -tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.15" } -tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.15" } +tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.16" } +tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.16" } -zebra-script = { path = "../zebra-script", version = "1.0.0-beta.39" } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39" } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" } +zebra-script = { path = "../zebra-script", version = "1.0.0-beta.40" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" } # prod feature progress-bar howudoin = { version = "0.1.2", optional = true } @@ -94,6 +94,6 @@ tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } tracing-error = "0.2.0" tracing-subscriber = "0.3.18" -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" } diff --git a/zebra-grpc/Cargo.toml b/zebra-grpc/Cargo.toml index 9cdaadafa2d..9f10802f7d6 100644 --- a/zebra-grpc/Cargo.toml +++ b/zebra-grpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-grpc" -version = "0.1.0-alpha.6" +version = "0.1.0-alpha.7" authors = ["Zcash Foundation "] description = "Zebra gRPC interface" license = "MIT OR Apache-2.0" @@ -28,8 +28,8 @@ color-eyre = "0.6.3" zcash_primitives.workspace = true -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = ["shielded-scan"] } -zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = ["shielded-scan"] } +zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.40" } [build-dependencies] tonic-build = "0.12.3" diff --git a/zebra-network/Cargo.toml b/zebra-network/Cargo.toml index 39cd209c49e..e042e583955 100644 --- a/zebra-network/Cargo.toml +++ b/zebra-network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-network" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation ", "Tower Maintainers "] description = "Networking code for Zebra" # # Legal @@ -83,7 +83,7 @@ howudoin = { version = "0.1.2", optional = true } proptest = { version = "1.4.0", optional = true } proptest-derive = { version = "0.5.0", optional = true } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["async-error"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["async-error"] } [dev-dependencies] proptest = "1.4.0" diff --git a/zebra-node-services/Cargo.toml b/zebra-node-services/Cargo.toml index e0da107d053..01c464b361b 100644 --- a/zebra-node-services/Cargo.toml +++ b/zebra-node-services/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-node-services" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "The interfaces of some Zebra node services" license = "MIT OR Apache-2.0" @@ -37,7 +37,7 @@ rpc-client = [ shielded-scan = [] [dependencies] -zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" } +zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.40" } # Optional dependencies diff --git a/zebra-rpc/Cargo.toml b/zebra-rpc/Cargo.toml index 909d9a468f6..517c565574c 100644 --- a/zebra-rpc/Cargo.toml +++ b/zebra-rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-rpc" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "A Zebra JSON Remote Procedure Call (JSON-RPC) interface" license = "MIT OR Apache-2.0" @@ -100,16 +100,16 @@ zcash_address = { workspace = true, optional = true} # Test-only feature proptest-impl proptest = { version = "1.4.0", optional = true } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = [ +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = [ "json-conversion", ] } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39" } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39" } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = [ +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40" } +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = [ "rpc-client", ] } -zebra-script = { path = "../zebra-script", version = "1.0.0-beta.39" } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" } +zebra-script = { path = "../zebra-script", version = "1.0.0-beta.40" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40" } [build-dependencies] tonic-build = { version = "0.12.3", optional = true } @@ -122,17 +122,17 @@ proptest = "1.4.0" thiserror = "1.0.64" tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = [ +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = [ "proptest-impl", ] } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39", features = [ +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40", features = [ "proptest-impl", ] } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39", features = [ +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40", features = [ "proptest-impl", ] } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = [ +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = [ "proptest-impl", ] } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" } diff --git a/zebra-scan/Cargo.toml b/zebra-scan/Cargo.toml index c81c749632f..8ca2facdb47 100644 --- a/zebra-scan/Cargo.toml +++ b/zebra-scan/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-scan" -version = "0.1.0-alpha.8" +version = "0.1.0-alpha.9" authors = ["Zcash Foundation "] description = "Shielded transaction scanner for the Zcash blockchain" license = "MIT OR Apache-2.0" @@ -77,11 +77,11 @@ zcash_primitives.workspace = true zcash_address.workspace = true sapling-crypto.workspace = true -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["shielded-scan"] } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["shielded-scan"] } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = ["shielded-scan"] } -zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.6" } -zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["shielded-scan"] } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["shielded-scan"] } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = ["shielded-scan"] } +zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.7" } +zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.40" } chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] } @@ -96,7 +96,7 @@ jubjub = { version = "0.10.0", optional = true } rand = { version = "0.8.5", optional = true } zcash_note_encryption = { version = "0.4.0", optional = true } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39", optional = true } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40", optional = true } # zebra-scanner binary dependencies tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } @@ -107,7 +107,7 @@ serde_json = "1.0.128" jsonrpc = { version = "0.18.0", optional = true } hex = { version = "0.4.3", optional = true } -zebrad = { path = "../zebrad", version = "1.8.1" } +zebrad = { path = "../zebrad", version = "2.0.0-rc.0" } [dev-dependencies] insta = { version = "1.40.0", features = ["ron", "redactions"] } @@ -125,6 +125,6 @@ zcash_note_encryption = "0.4.0" toml = "0.8.19" tonic = "0.12.3" -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" } diff --git a/zebra-script/Cargo.toml b/zebra-script/Cargo.toml index 095e0ed2950..28d748c8eff 100644 --- a/zebra-script/Cargo.toml +++ b/zebra-script/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-script" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "Zebra script verification wrapping zcashd's zcash_script library" license = "MIT OR Apache-2.0" @@ -16,11 +16,11 @@ categories = ["api-bindings", "cryptography::cryptocurrencies"] [dependencies] zcash_script = "0.2.0" -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" } thiserror = "1.0.64" [dev-dependencies] hex = "0.4.3" lazy_static = "1.4.0" -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" } diff --git a/zebra-state/Cargo.toml b/zebra-state/Cargo.toml index f1776424b13..a3ee910ef11 100644 --- a/zebra-state/Cargo.toml +++ b/zebra-state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-state" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "State contextual verification and storage code for Zebra" license = "MIT OR Apache-2.0" @@ -77,13 +77,13 @@ tracing = "0.1.39" elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true } serde_json = { version = "1.0.128", package = "serde_json", optional = true } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["async-error"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["async-error"] } # prod feature progress-bar howudoin = { version = "0.1.2", optional = true } # test feature proptest-impl -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39", optional = true } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40", optional = true } proptest = { version = "1.4.0", optional = true } proptest-derive = { version = "0.5.0", optional = true } @@ -108,5 +108,5 @@ jubjub = "0.10.0" tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" } diff --git a/zebra-test/Cargo.toml b/zebra-test/Cargo.toml index 66c2f168284..8cbec5f35ac 100644 --- a/zebra-test/Cargo.toml +++ b/zebra-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-test" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "Test harnesses and test vectors for Zebra" license = "MIT OR Apache-2.0" diff --git a/zebra-utils/Cargo.toml b/zebra-utils/Cargo.toml index 66c884d3ced..9e241bd58f7 100644 --- a/zebra-utils/Cargo.toml +++ b/zebra-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-utils" -version = "1.0.0-beta.39" +version = "1.0.0-beta.40" authors = ["Zcash Foundation "] description = "Developer tools for Zebra maintenance and testing" license = "MIT OR Apache-2.0" @@ -94,11 +94,11 @@ tracing-error = "0.2.0" tracing-subscriber = "0.3.18" thiserror = "1.0.64" -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39" } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" } # These crates are needed for the block-template-to-proposal binary -zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39", optional = true } +zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.40", optional = true } # These crates are needed for the zebra-checkpoints binary itertools = { version = "0.13.0", optional = true } diff --git a/zebrad/Cargo.toml b/zebrad/Cargo.toml index 8d42e2421ea..6020978c1ad 100644 --- a/zebrad/Cargo.toml +++ b/zebrad/Cargo.toml @@ -1,7 +1,7 @@ [package] # Crate metadata name = "zebrad" -version = "1.9.0" +version = "2.0.0-rc.0" authors = ["Zcash Foundation "] description = "The Zcash Foundation's independent, consensus-compatible implementation of a Zcash node" license = "MIT OR Apache-2.0" @@ -157,15 +157,15 @@ test_sync_past_mandatory_checkpoint_mainnet = [] test_sync_past_mandatory_checkpoint_testnet = [] [dependencies] -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39" } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39" } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = ["rpc-client"] } -zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39" } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" } +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40" } +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = ["rpc-client"] } +zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.40" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40" } # Required for crates.io publishing, but it's only used in tests -zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.39", optional = true } +zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.40", optional = true } abscissa_core = "0.7.0" clap = { version = "4.5.18", features = ["cargo"] } @@ -279,13 +279,13 @@ proptest-derive = "0.5.0" # enable span traces and track caller in tests color-eyre = { version = "0.6.3" } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39", features = ["proptest-impl"] } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40", features = ["proptest-impl"] } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" } -zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.6" } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" } +zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.7" } # Used by the checkpoint generation tests via the zebra-checkpoints feature # (the binaries in this crate won't be built unless their features are enabled). @@ -296,7 +296,7 @@ zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.6" } # When `-Z bindeps` is stabilised, enable this binary dependency instead: # https://github.com/rust-lang/cargo/issues/9096 # zebra-utils { path = "../zebra-utils", artifact = "bin:zebra-checkpoints" } -zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.39" } +zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.40" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] } diff --git a/zebrad/src/components/sync/end_of_support.rs b/zebrad/src/components/sync/end_of_support.rs index 553ba2e4b00..1ba3c1863c8 100644 --- a/zebrad/src/components/sync/end_of_support.rs +++ b/zebrad/src/components/sync/end_of_support.rs @@ -13,7 +13,7 @@ use zebra_chain::{ use crate::application::release_version; /// The estimated height that this release will be published. -pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_626_500; +pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_678_363; /// The maximum number of days after `ESTIMATED_RELEASE_HEIGHT` where a Zebra server will run /// without halting. @@ -22,8 +22,8 @@ pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_626_500; /// /// - Zebra will exit with a panic if the current tip height is bigger than the `ESTIMATED_RELEASE_HEIGHT` /// plus this number of days. -/// - Currently set to 14 weeks. -pub const EOS_PANIC_AFTER: u32 = 70; +/// - Currently set to 5 weeks to end support before Mainnet Nu6 activation at block [`2_726_400`](https://zips.z.cash/zip-0253). +pub const EOS_PANIC_AFTER: u32 = 35; /// The number of days before the end of support where Zebra will display warnings. pub const EOS_WARN_AFTER: u32 = EOS_PANIC_AFTER - 14;