diff --git a/.github/mergify.yml b/.github/mergify.yml index ebce6885ebf..95e464822b3 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -10,16 +10,11 @@ merge_queue: # Provides a means to set configuration values that act as fallbacks # for queue_rules and pull_request_rules defaults: - actions: - squash: - # TODO: Adapt our PR template to use title+body - commit_message: all-commits - + # Define our default queue rules queue_rule: # Allow to update/rebase the original pull request if possible to check its mergeability, # and it does not create a draft PR if not needed allow_inplace_checks: True - batch_size: 20 # Wait for about 10% of the time it takes Rust PRs to run CI (~1h) batch_max_wait_time: "10 minutes" queue_conditions: @@ -27,73 +22,48 @@ defaults: # which are the same as the GitHub main branch protection rules # https://docs.mergify.com/conditions/#about-branch-protection - base=main + # is not in draft + - -draft + # does not include the do-not-merge label + - label!=do-not-merge + # has at least one approving reviewer + - "#approved-reviews-by >= 1" + # Allows to define the rules that reign over our merge queues queue_rules: - name: urgent - batch_size: 8 + batch_size: 5 # Wait a short time to embark hotfixes together in a merge train batch_max_wait_time: "2 minutes" + queue_conditions: + # is labeled with Critical priority + - 'label~=^P-Critical' - name: batched + batch_size: 20 + +pull_request_rules: + - name: move to any queue if GitHub Rulesets are satisfied + conditions: [] + actions: + queue: # Rules that will determine which priority a pull request has when entering # our merge queue # # These rules are checked in order, the first one to be satisfied applies priority_rules: - - name: move to urgent queue when CI passes with multiple reviews + - name: urgent conditions: - # This queue handles a PR if it: - # has multiple approving reviewers - - "#approved-reviews-by>=2" # is labeled with Critical priority - 'label~=^P-Critical' - # and satisfies the standard merge conditions: - # targets main - - base=main - # is not in draft - - -draft - # does not include the do-not-merge label - - label!=do-not-merge allow_checks_interruption: true priority: high - - name: move to urgent queue when CI passes with 1 review + - name: low conditions: - # This queue handles a PR if it: - # has at least one approving reviewer (branch protection rule) - # does not need extra reviews - - 'label!=extra-reviews' - # is labeled with Critical priority - - 'label~=^P-Critical' - # and satisfies the standard merge conditions: - - base=main - - -draft - - label!=do-not-merge - priority: high - - - name: move to medium queue when CI passes with multiple reviews - conditions: - # This queue handles a PR if it: - # has multiple approving reviewers - - "#approved-reviews-by>=2" - # is labeled with any other priority (rules are checked in order) - # and satisfies the standard merge conditions: - - base=main - - -draft - - label!=do-not-merge - priority: medium - - - name: move to low queue when CI passes with 1 review - conditions: - # This queue handles a PR if it: - # has at least one approving reviewer (branch protection rule) - # does not need extra reviews - - 'label!=extra-reviews' - # is labeled with any other priority (rules are checked in order) - # and satisfies the standard merge conditions: - - base=main - - -draft - - label!=do-not-merge + # is labeled with Optional or Low priority + - 'label~=^P-(Optional|Low)' + allow_checks_interruption: true priority: low diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index 3d1e3b946c5..1b87753b508 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -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.6.0 + uses: codecov/codecov-action@v5.0.7 diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index 22ec5089c37..43acadbd8ec 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.3 + uses: tj-actions/changed-files@v45.0.4 with: files: | **/*.rs @@ -56,7 +56,7 @@ jobs: - name: Workflow files id: changed-files-workflows - uses: tj-actions/changed-files@v45.0.3 + uses: tj-actions/changed-files@v45.0.4 with: files: | .github/workflows/*.yml diff --git a/.github/workflows/scripts/release-crates-dry-run.sh b/.github/workflows/scripts/release-crates-dry-run.sh index 32fc0e671c7..c83b068f5bd 100755 --- a/.github/workflows/scripts/release-crates-dry-run.sh +++ b/.github/workflows/scripts/release-crates-dry-run.sh @@ -20,11 +20,11 @@ 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 patch +cargo release version --verbose --execute --no-confirm --allow-branch '*' --workspace --exclude zebrad --exclude zebra-scan --exclude zebra-grpc beta # 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.11 -cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-grpc 0.1.0-alpha.9 +cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-scan 0.1.0-alpha.13 +cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-grpc 0.1.0-alpha.11 # Update zebrad: cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebrad patch diff --git a/.github/workflows/sub-build-docker-image.yml b/.github/workflows/sub-build-docker-image.yml index ee95278b9cf..9050d223080 100644 --- a/.github/workflows/sub-build-docker-image.yml +++ b/.github/workflows/sub-build-docker-image.yml @@ -93,7 +93,7 @@ jobs: # Automatic tag management and OCI Image Format Specification for labels - name: Docker meta id: meta - uses: docker/metadata-action@v5.5.1 + uses: docker/metadata-action@v5.6.1 with: # list of Docker images to use as base name for tags # We only publish images to DockerHub if a release is not a pre-release @@ -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.9.0 + uses: docker/build-push-action@v6.10.0 with: target: ${{ inputs.dockerfile_target }} context: . @@ -193,7 +193,7 @@ jobs: # - `dev` for a pull request event - name: Docker Scout id: docker-scout - uses: docker/scout-action@v1.15.0 + uses: docker/scout-action@v1.15.1 # 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. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a345971d3c..f12c495bb75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,45 @@ 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.1.0](https://github.com/ZcashFoundation/zebra/releases/tag/v2.1.0) - 2024-12-06 + +This release adds a check to verify that V5 transactions in the mempool have the correct consensus branch ID; +Zebra would previously accept those and return a transaction ID (indicating success) even though they would +be eventually rejected by the block consensus checks. Similarly, Zebra also now returns an error when trying +to submit transactions that would eventually fail some consensus checks (e.g. double spends) but would also +return a transaction ID indicating success. The release also bumps +Zebra's initial minimum protocol version such that this release of Zebra will always reject connections with peers advertising +a network protocol version below 170,120 on Mainnet and 170,110 on Testnet instead of accepting those connections until Zebra's +chain state reaches the NU6 activation height. +The `getblock` RPC method has been updated and now returns some additional information +such as the block height (even if you provide a block hash) and other fields as supported +by the `getblockheader` RPC call. + +### Breaking Changes + +- Upgrade minimum protocol versions for all Zcash networks ([#9058](https://github.com/ZcashFoundation/zebra/pull/9058)) + +### Added + +- `getblockheader` RPC method ([#8967](https://github.com/ZcashFoundation/zebra/pull/8967)) +- `rust-toolchain.toml` file ([#8985](https://github.com/ZcashFoundation/zebra/pull/8985)) + +### Changed + +- Updated `getblock` RPC to more closely match zcashd ([#9006](https://github.com/ZcashFoundation/zebra/pull/9006)) +- Updated error messages to include inner error types (notably for the transaction verifier) ([#9066](https://github.com/ZcashFoundation/zebra/pull/9066)) + +### Fixed + +- Validate consensus branch ids of mempool transactions ([#9063](https://github.com/ZcashFoundation/zebra/pull/9063)) +- Verify mempool transactions with unmined inputs if those inputs are in the mempool to support TEX transactions ([#8857](https://github.com/ZcashFoundation/zebra/pull/8857)) +- Wait until transactions have been added to the mempool before returning success response from `sendrawtransaction` RPC ([#9067](https://github.com/ZcashFoundation/zebra/pull/9067)) + +### Contributors + +Thank you to everyone who contributed to this release, we couldn't make Zebra without you: +@arya2, @conradoplg, @cypherpepe, @gustavovalverde, @idky137, @oxarbitrage, @pinglanlu and @upbqdn + ## [Zebra 2.0.1](https://github.com/ZcashFoundation/zebra/releases/tag/v2.0.1) - 2024-10-30 - Zebra now supports NU6 on Mainnet. This patch release updates dependencies diff --git a/Cargo.lock b/Cargo.lock index c9e9dcbcb5e..78a19264e9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,13 +12,13 @@ dependencies = [ "arc-swap", "backtrace", "canonical-path", - "clap 4.5.20", + "clap 4.5.23", "color-eyre", "fs-err", "once_cell", "regex", "secrecy", - "semver 1.0.23", + "semver", "serde", "termcolor", "toml 0.5.11", @@ -192,9 +192,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arc-swap" @@ -246,7 +246,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -257,7 +257,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -345,12 +345,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - [[package]] name = "base64" version = "0.13.1" @@ -428,7 +422,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -448,7 +442,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -615,9 +609,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "bzip2-sys" @@ -662,10 +656,10 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.23", + "semver", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -747,9 +741,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -818,15 +812,15 @@ dependencies = [ "bitflags 1.3.2", "strsim 0.8.0", "textwrap", - "unicode-width", + "unicode-width 0.1.14", "vec_map", ] [[package]] name = "clap" -version = "4.5.20" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -834,9 +828,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -853,14 +847,14 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "color-eyre" @@ -905,7 +899,7 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", + "unicode-width 0.1.14", "windows-sys 0.52.0", ] @@ -960,16 +954,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1003,7 +987,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.20", + "clap 4.5.23", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1091,7 +1075,7 @@ dependencies = [ "curve25519-dalek-derive", "digest", "fiat-crypto", - "rustc_version 0.4.1", + "rustc_version", "serde", "subtle", "zeroize", @@ -1105,17 +1089,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", + "syn 2.0.90", ] [[package]] @@ -1124,22 +1098,8 @@ version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -1153,18 +1113,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.85", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core 0.13.4", - "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -1173,9 +1122,9 @@ version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.10", + "darling_core", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -1290,20 +1239,21 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elasticsearch" -version = "8.5.0-alpha.1" +version = "8.16.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40d9bd57d914cc66ce878f098f63ed7b5d5b64c30644a5adb950b008f874a6c6" +checksum = "774166217d4f9b96e9ab9d6832302e3d47196de507fddddb21de8184a39e2c6d" dependencies = [ - "base64 0.11.0", + "base64 0.22.1", "bytes", "dyn-clone", "lazy_static", "percent-encoding", - "reqwest 0.11.27", - "rustc_version 0.2.3", + "reqwest", + "rustc_version", "serde", "serde_json", - "serde_with 1.14.0", + "serde_with", + "tokio", "url", "void", ] @@ -1314,15 +1264,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "env_logger" version = "0.7.1" @@ -1548,7 +1489,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -1665,25 +1606,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util 0.7.12", - "tracing", -] - [[package]] name = "h2" version = "0.4.6" @@ -1696,10 +1618,10 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", - "tokio-util 0.7.12", + "tokio-util 0.7.13", "tracing", ] @@ -1982,7 +1904,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1998,14 +1919,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", + "h2", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -2017,20 +1938,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.31", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", -] - [[package]] name = "hyper-rustls" version = "0.27.3" @@ -2039,14 +1946,14 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", - "rustls 0.23.16", + "rustls", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", "tower-service", - "webpki-roots 0.26.6", + "webpki-roots", ] [[package]] @@ -2055,7 +1962,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", "pin-project-lite", "tokio", @@ -2073,7 +1980,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.5.0", + "hyper 1.5.1", "pin-project-lite", "socket2", "tokio", @@ -2168,9 +2075,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.0", @@ -2179,25 +2086,24 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" dependencies = [ "console", - "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", + "web-time", ] [[package]] name = "inferno" -version = "0.11.21" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" +checksum = "75a5d75fee4d36809e6b021e4b96b686e763d365ffdb03af2bd00786353f84fe" dependencies = [ "ahash", - "is-terminal", "itoa", "log", "num-format", @@ -2218,9 +2124,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f72d3e19488cf7d8ea52d2fc0f8754fc933398b337cd3cbdb28aaeb35159ef" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" dependencies = [ "console", "lazy_static", @@ -2592,9 +2498,9 @@ dependencies = [ [[package]] name = "metrics" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae428771d17306715c5091d446327d1cfdedc82185c65ba8423ab404e45bf10" +checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" dependencies = [ "ahash", "portable-atomic", @@ -2608,14 +2514,14 @@ checksum = "85b6f8152da6d7892ff1b7a1c0fa3f435e92b5918ad67035c3bb432111d9a29b" dependencies = [ "base64 0.22.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", - "indexmap 2.6.0", + "indexmap 2.7.0", "ipnet", "metrics", "metrics-util", "quanta", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -3030,7 +2936,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] @@ -3054,7 +2960,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -3075,7 +2981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -3095,7 +3001,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -3193,7 +3099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -3251,9 +3157,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -3286,14 +3192,14 @@ checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "prost" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" dependencies = [ "bytes", "prost-derive", @@ -3316,21 +3222,21 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.85", + "syn 2.0.90", "tempfile", ] [[package]] name = "prost-derive" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" dependencies = [ "anyhow", "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -3365,9 +3271,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quick-xml" -version = "0.26.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" +checksum = "f22f29bdff3987b4d8632ef95fd6424ec7e4e0a57e2f4fc63e489e75357f6a03" dependencies = [ "memchr", ] @@ -3406,9 +3312,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls 0.23.16", + "rustls", "socket2", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -3423,9 +3329,9 @@ dependencies = [ "rand 0.8.5", "ring", "rustc-hash 2.0.0", - "rustls 0.23.16", + "rustls", "slab", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tracing", ] @@ -3582,7 +3488,7 @@ dependencies = [ "pasta_curves", "rand_core 0.6.4", "serde", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -3595,7 +3501,7 @@ dependencies = [ "rand_core 0.6.4", "reddsa", "serde", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -3625,7 +3531,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3672,55 +3578,13 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "async-compression", - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.31", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-rustls 0.24.1", - "tokio-util 0.7.12", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.25.4", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ + "async-compression", "base64 0.22.1", "bytes", "futures-channel", @@ -3729,8 +3593,8 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", - "hyper-rustls 0.27.3", + "hyper 1.5.1", + "hyper-rustls", "hyper-util", "ipnet", "js-sys", @@ -3740,21 +3604,22 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.16", - "rustls-pemfile 2.2.0", + "rustls", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", + "tokio-util 0.7.13", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.26.6", + "webpki-roots", "windows-registry", ] @@ -3845,29 +3710,20 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver", ] [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -3878,40 +3734,19 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.8", + "rustls-webpki", "subtle", "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -3927,16 +3762,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.102.8" @@ -4019,16 +3844,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "secp256k1" version = "0.27.0" @@ -4058,15 +3873,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.23" @@ -4076,35 +3882,29 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "sentry" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00421ed8fa0c995f07cde48ba6c89e80f2b312f74ff637326f392fbfd23abe02" +checksum = "016958f51b96861dead7c1e02290f138411d05e94fad175c8636a835dee6e51e" dependencies = [ "httpdate", - "reqwest 0.12.9", - "rustls 0.21.12", + "reqwest", + "rustls", "sentry-backtrace", "sentry-contexts", "sentry-core", "sentry-tracing", "tokio", "ureq", - "webpki-roots 0.25.4", + "webpki-roots", ] [[package]] name = "sentry-backtrace" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79194074f34b0cbe5dd33896e5928bbc6ab63a889bd9df2264af5acb186921e" +checksum = "e57712c24e99252ef175b4b06c485294f10ad6bc5b5e1567ff3803ee7a0b7d3f" dependencies = [ "backtrace", "once_cell", @@ -4114,23 +3914,23 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba8870c5dba2bfd9db25c75574a11429f6b95957b0a78ac02e2970dd7a5249a" +checksum = "eba8754ec3b9279e00aa6d64916f211d44202370a1699afde1db2c16cbada089" dependencies = [ "hostname", "libc", "os_info", - "rustc_version 0.4.1", + "rustc_version", "sentry-core", "uname", ] [[package]] name = "sentry-core" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a75011ea1c0d5c46e9e57df03ce81f5c7f0a9e199086334a1f9c0a541e0826" +checksum = "f9f8b6dcd4fbae1e3e22b447f32670360b27e31b62ab040f7fb04e0f80c04d92" dependencies = [ "once_cell", "rand 0.8.5", @@ -4141,9 +3941,9 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f715932bf369a61b7256687c6f0554141b7ce097287e30e3f7ed6e9de82498fe" +checksum = "263f73c757ed7915d3e1e34625eae18cad498a95b4261603d4ce3f87b159a6f0" dependencies = [ "sentry-backtrace", "sentry-core", @@ -4153,16 +3953,16 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.32.3" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4519c900ce734f7a0eb7aba0869dfb225a7af8820634a7dd51449e3b093cfb7c" +checksum = "a71ed3a389948a6a6d92b98e997a2723ca22f09660c5a7b7388ecd509a70a527" dependencies = [ "debugid", "hex", "rand 0.8.5", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "time", "url", "uuid", @@ -4170,9 +3970,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -4188,22 +3988,22 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -4231,16 +4031,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" -dependencies = [ - "serde", - "serde_with_macros 1.5.2", -] - [[package]] name = "serde_with" version = "3.11.0" @@ -4251,36 +4041,24 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", - "serde_with_macros 3.11.0", + "serde_with_macros", "time", ] -[[package]] -name = "serde_with_macros" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" -dependencies = [ - "darling 0.13.4", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "serde_with_macros" version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ - "darling 0.20.10", + "darling", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4289,7 +4067,7 @@ version = "0.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "libyml", "memchr", @@ -4450,12 +4228,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -4505,9 +4277,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -4541,27 +4313,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -4570,9 +4321,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -4596,34 +4347,54 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "1.0.65" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +dependencies = [ + "thiserror-impl 2.0.6", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "thread-priority" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3b04d33c9633b8662b167b847c7ab521f83d1ae20f2321b65b5b925e532e36" +checksum = "cfe075d7053dae61ac5413a34ea7d4913b6e6207844fd726bdd858b37ff72bf5" dependencies = [ "bitflags 2.6.0", "cfg-if 1.0.0", @@ -4703,9 +4474,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -4728,17 +4499,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", + "syn 2.0.90", ] [[package]] @@ -4747,21 +4508,21 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.16", + "rustls", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util 0.7.12", + "tokio-util 0.7.13", ] [[package]] @@ -4793,9 +4554,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -4840,7 +4601,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -4858,11 +4619,11 @@ dependencies = [ "axum", "base64 0.22.1", "bytes", - "h2 0.4.6", + "h2", "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-timeout", "hyper-util", "percent-encoding", @@ -4888,7 +4649,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4919,7 +4680,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.12", + "tokio-util 0.7.13", "tower-layer", "tower-service", "tracing", @@ -4941,7 +4702,7 @@ dependencies = [ [[package]] name = "tower-batch-control" -version = "0.2.41-beta.18" +version = "0.2.41-beta.19" dependencies = [ "color-eyre", "ed25519-zebra", @@ -4953,7 +4714,7 @@ dependencies = [ "tinyvec", "tokio", "tokio-test", - "tokio-util 0.7.12", + "tokio-util 0.7.13", "tower 0.4.13", "tower-fallback", "tower-test", @@ -4964,7 +4725,7 @@ dependencies = [ [[package]] name = "tower-fallback" -version = "0.2.41-beta.18" +version = "0.2.41-beta.19" dependencies = [ "futures-core", "pin-project", @@ -5002,9 +4763,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -5019,27 +4780,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 1.0.69", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -5047,9 +4808,9 @@ dependencies = [ [[package]] name = "tracing-error" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ "tracing", "tracing-subscriber", @@ -5111,9 +4872,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -5145,7 +4906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -5244,6 +5005,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -5275,10 +5042,10 @@ dependencies = [ "base64 0.22.1", "log", "once_cell", - "rustls 0.23.16", + "rustls", "rustls-pki-types", "url", - "webpki-roots 0.26.6", + "webpki-roots", ] [[package]] @@ -5337,7 +5104,7 @@ dependencies = [ "cfg-if 1.0.0", "git2", "regex", - "rustc_version 0.4.1", + "rustc_version", "rustversion", "time", ] @@ -5356,7 +5123,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -5477,7 +5244,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -5511,7 +5278,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5533,10 +5300,14 @@ dependencies = [ ] [[package]] -name = "webpki-roots" -version = "0.25.4" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "webpki-roots" @@ -5796,16 +5567,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - [[package]] name = "wyz" version = "0.5.1" @@ -6039,7 +5800,7 @@ dependencies = [ [[package]] name = "zebra-chain" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "bitflags 2.6.0", "bitflags-serde-legacy", @@ -6081,12 +5842,12 @@ dependencies = [ "serde", "serde-big-array", "serde_json", - "serde_with 3.11.0", + "serde_with", "sha2", "spandoc", "static_assertions", "tempfile", - "thiserror", + "thiserror 2.0.6", "tinyvec", "tokio", "tracing", @@ -6104,7 +5865,7 @@ dependencies = [ [[package]] name = "zebra-consensus" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "bellman", "blake2b_simd", @@ -6129,7 +5890,7 @@ dependencies = [ "sapling-crypto", "serde", "spandoc", - "thiserror", + "thiserror 2.0.6", "tinyvec", "tokio", "tower 0.4.13", @@ -6150,7 +5911,7 @@ dependencies = [ [[package]] name = "zebra-grpc" -version = "0.1.0-alpha.9" +version = "0.1.0-alpha.10" dependencies = [ "color-eyre", "futures-util", @@ -6172,7 +5933,7 @@ dependencies = [ [[package]] name = "zebra-network" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "bitflags 2.6.0", "byteorder", @@ -6183,7 +5944,7 @@ dependencies = [ "hex", "howudoin", "humantime-serde", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.13.0", "lazy_static", "metrics", @@ -6198,10 +5959,10 @@ dependencies = [ "serde", "static_assertions", "tempfile", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", - "tokio-util 0.7.12", + "tokio-util 0.7.13", "toml 0.8.19", "tower 0.4.13", "tracing", @@ -6213,11 +5974,11 @@ dependencies = [ [[package]] name = "zebra-node-services" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "color-eyre", "jsonrpc-core", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "tokio", @@ -6226,14 +5987,14 @@ dependencies = [ [[package]] name = "zebra-rpc" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "base64 0.22.1", "chrono", "color-eyre", "futures", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "insta", "jsonrpc-core", "jsonrpc-derive", @@ -6244,7 +6005,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "thiserror", + "thiserror 2.0.6", "tokio", "tokio-stream", "tonic", @@ -6265,7 +6026,7 @@ dependencies = [ [[package]] name = "zebra-scan" -version = "0.1.0-alpha.11" +version = "0.1.0-alpha.12" dependencies = [ "bls12_381", "chrono", @@ -6274,7 +6035,7 @@ dependencies = [ "futures", "group", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "insta", "itertools 0.13.0", "jsonrpc", @@ -6284,7 +6045,7 @@ dependencies = [ "proptest-derive", "rand 0.8.5", "sapling-crypto", - "semver 1.0.23", + "semver", "serde", "serde_json", "structopt", @@ -6311,11 +6072,11 @@ dependencies = [ [[package]] name = "zebra-script" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "hex", "lazy_static", - "thiserror", + "thiserror 2.0.6", "zcash_script", "zebra-chain", "zebra-test", @@ -6323,7 +6084,7 @@ dependencies = [ [[package]] name = "zebra-state" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "bincode", "chrono", @@ -6337,7 +6098,7 @@ dependencies = [ "howudoin", "human_bytes", "humantime-serde", - "indexmap 2.6.0", + "indexmap 2.7.0", "insta", "itertools 0.13.0", "jubjub", @@ -6352,12 +6113,12 @@ dependencies = [ "regex", "rlimit", "rocksdb", - "semver 1.0.23", + "semver", "serde", "serde_json", "spandoc", "tempfile", - "thiserror", + "thiserror 2.0.6", "tinyvec", "tokio", "tower 0.4.13", @@ -6368,13 +6129,13 @@ dependencies = [ [[package]] name = "zebra-test" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "color-eyre", "futures", "hex", "humantime", - "indexmap 2.6.0", + "indexmap 2.7.0", "insta", "itertools 0.13.0", "lazy_static", @@ -6385,7 +6146,7 @@ dependencies = [ "regex", "spandoc", "tempfile", - "thiserror", + "thiserror 2.0.6", "tinyvec", "tokio", "tower 0.4.13", @@ -6396,23 +6157,23 @@ dependencies = [ [[package]] name = "zebra-utils" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" dependencies = [ "color-eyre", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.13.0", "jsonrpc", "quote", "rand 0.8.5", "regex", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "serde_yml", "structopt", - "syn 2.0.85", - "thiserror", + "syn 2.0.90", + "thiserror 2.0.6", "tinyvec", "tokio", "tracing-error", @@ -6427,13 +6188,13 @@ dependencies = [ [[package]] name = "zebrad" -version = "2.0.1" +version = "2.1.0" dependencies = [ "abscissa_core", "atty", "bytes", "chrono", - "clap 4.5.20", + "clap 4.5.23", "color-eyre", "console-subscriber", "dirs", @@ -6443,9 +6204,9 @@ dependencies = [ "howudoin", "http-body-util", "humantime-serde", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", - "indexmap 2.6.0", + "indexmap 2.7.0", "indicatif", "inferno", "insta", @@ -6463,12 +6224,12 @@ dependencies = [ "rand 0.8.5", "rayon", "regex", - "semver 1.0.23", + "semver", "sentry", "serde", "serde_json", "tempfile", - "thiserror", + "thiserror 2.0.6", "thread-priority", "tinyvec", "tokio", @@ -6515,7 +6276,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -6535,7 +6296,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] diff --git a/book/src/user/docker.md b/book/src/user/docker.md index d77c234b537..6dc852a57ac 100644 --- a/book/src/user/docker.md +++ b/book/src/user/docker.md @@ -37,7 +37,7 @@ docker run -d --platform linux/amd64 \ ### Build it locally ```shell -git clone --depth 1 --branch v2.0.1 https://github.com/ZcashFoundation/zebra.git +git clone --depth 1 --branch v2.1.0 https://github.com/ZcashFoundation/zebra.git docker build --file docker/Dockerfile --target runtime --tag zebra:local . docker run --detach zebra:local ``` diff --git a/book/src/user/install.md b/book/src/user/install.md index 5903adf4337..c72cfbf38c2 100644 --- a/book/src/user/install.md +++ b/book/src/user/install.md @@ -76,7 +76,7 @@ To compile Zebra directly from GitHub, or from a GitHub release source archive: ```sh git clone https://github.com/ZcashFoundation/zebra.git cd zebra -git checkout v2.0.1 +git checkout v2.1.0 ``` 3. Build and Run `zebrad` @@ -89,7 +89,7 @@ target/release/zebrad start ### Compiling from git using cargo install ```sh -cargo install --git https://github.com/ZcashFoundation/zebra --tag v2.0.1 zebrad +cargo install --git https://github.com/ZcashFoundation/zebra --tag v2.1.0 zebrad ``` ### Compiling on ARM diff --git a/deny.toml b/deny.toml index 6c809cabd12..7f804946767 100644 --- a/deny.toml +++ b/deny.toml @@ -107,7 +107,11 @@ skip-tree = [ # wait for zebra to update tower { name = "tower", version = "=0.4.13" }, - { name = "hashbrown", version = "=0.12.3" }, + { name = "hashbrown", version = "=0.14.5" }, + + # wait for zebra to update vergen + { name = "thiserror", version = "=1.0.69" }, + { name = "thiserror-impl", version = "=1.0.69" }, # Remove after release candicate period is over and the ECC crates are not patched anymore { name = "equihash", version = "=0.2.0" }, diff --git a/tower-batch-control/Cargo.toml b/tower-batch-control/Cargo.toml index 517c9cfca9c..9f9dd5661f6 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.18" +version = "0.2.41-beta.19" authors = ["Zcash Foundation ", "Tower Maintainers "] description = "Tower middleware for batch request processing" # # Legal @@ -26,10 +26,10 @@ futures = "0.3.31" futures-core = "0.3.28" pin-project = "1.1.6" rayon = "1.10.0" -tokio = { version = "1.41.0", features = ["time", "sync", "tracing", "macros"] } -tokio-util = "0.7.12" +tokio = { version = "1.42.0", features = ["time", "sync", "tracing", "macros"] } +tokio-util = "0.7.13" tower = { version = "0.4.13", features = ["util", "buffer"] } -tracing = "0.1.39" +tracing = "0.1.41" tracing-futures = "0.2.5" [dev-dependencies] @@ -41,12 +41,12 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } ed25519-zebra = "4.0.3" rand = "0.8.5" -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } tokio-test = "0.4.4" -tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.18" } +tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.19" } tower-test = "0.4.0" -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.42" } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] } diff --git a/tower-fallback/Cargo.toml b/tower-fallback/Cargo.toml index a3d504ed691..bc20a49ef7a 100644 --- a/tower-fallback/Cargo.toml +++ b/tower-fallback/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tower-fallback" -version = "0.2.41-beta.18" +version = "0.2.41-beta.19" 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" @@ -19,9 +19,9 @@ categories = ["algorithms", "asynchronous"] pin-project = "1.1.6" tower = "0.4.13" futures-core = "0.3.28" -tracing = "0.1.39" +tracing = "0.1.41" [dev-dependencies] -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.42" } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43" } diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index b43e77f149a..b7a9b5d9d32 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-chain" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation "] description = "Core Zcash data structures" license = "MIT OR Apache-2.0" @@ -81,7 +81,7 @@ group = "0.13.0" incrementalmerkletree.workspace = true jubjub = "0.10.0" lazy_static = "1.4.0" -tempfile = "3.13.0" +tempfile = "3.14.0" dirs = "5.0.1" num-integer = "0.1.46" primitive-types = "0.12.2" @@ -105,17 +105,17 @@ zcash_protocol.workspace = true zcash_address.workspace = true # Time -chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] } +chrono = { version = "0.4.39", default-features = false, features = ["clock", "std", "serde"] } humantime = "2.1.0" # Error Handling & Formatting static_assertions = "1.1.0" -thiserror = "1.0.64" -tracing = "0.1.39" +thiserror = "2.0.6" +tracing = "0.1.41" # Serialization hex = { version = "0.4.3", features = ["serde"] } -serde = { version = "1.0.211", features = ["serde_derive", "rc"] } +serde = { version = "1.0.215", features = ["serde_derive", "rc"] } serde_with = "3.11.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.132", optional = true } +serde_json = { version = "1.0.133", optional = true } # Production feature async-error and testing feature proptest-impl -tokio = { version = "1.41.0", optional = true } +tokio = { version = "1.42.0", optional = true } # Experimental feature shielded-scan zcash_client_backend = { workspace = true, optional = true } @@ -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.42", optional = true } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43", optional = true } [dev-dependencies] # Benchmarks @@ -157,7 +157,7 @@ color-eyre = "0.6.3" # Enable a feature that makes tinyvec compile much faster. tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } spandoc = "0.2.2" -tracing = "0.1.39" +tracing = "0.1.41" # Make the optional testing dependencies required proptest = "1.4.0" @@ -166,9 +166,9 @@ proptest-derive = "0.5.0" rand = "0.8.5" rand_chacha = "0.3.1" -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.42" } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43" } [[bench]] name = "block" diff --git a/zebra-chain/src/history_tree.rs b/zebra-chain/src/history_tree.rs index 91fa3a17628..d84f92321af 100644 --- a/zebra-chain/src/history_tree.rs +++ b/zebra-chain/src/history_tree.rs @@ -30,7 +30,7 @@ pub enum HistoryTreeError { #[non_exhaustive] InnerError { inner: zcash_history::Error }, - #[error("I/O error")] + #[error("I/O error: {0}")] IOError(#[from] io::Error), } diff --git a/zebra-chain/src/transaction.rs b/zebra-chain/src/transaction.rs index 96b2378e273..1c121130fcc 100644 --- a/zebra-chain/src/transaction.rs +++ b/zebra-chain/src/transaction.rs @@ -324,7 +324,17 @@ impl Transaction { } } - /// Return the version of this transaction. + /// Returns the version of this transaction. + /// + /// Note that the returned version is equal to `effectiveVersion`, described in [ยง 7.1 + /// Transaction Encoding and Consensus]: + /// + /// > `effectiveVersion` [...] is equal to `min(2, version)` when `fOverwintered = 0` and to + /// > `version` otherwise. + /// + /// Zebra handles the `fOverwintered` flag via the [`Self::is_overwintered`] method. + /// + /// [ยง 7.1 Transaction Encoding and Consensus]: pub fn version(&self) -> u32 { match self { Transaction::V1 { .. } => 1, @@ -429,32 +439,6 @@ impl Transaction { } } - /// Modify the expiry height of this transaction. - /// - /// # Panics - /// - /// - if called on a v1 or v2 transaction - #[cfg(any(test, feature = "proptest-impl"))] - pub fn expiry_height_mut(&mut self) -> &mut block::Height { - match self { - Transaction::V1 { .. } | Transaction::V2 { .. } => { - panic!("v1 and v2 transactions are not supported") - } - Transaction::V3 { - ref mut expiry_height, - .. - } - | Transaction::V4 { - ref mut expiry_height, - .. - } - | Transaction::V5 { - ref mut expiry_height, - .. - } => expiry_height, - } - } - /// Get this transaction's network upgrade field, if any. /// This field is serialized as `nConsensusBranchId` ([7.1]). /// @@ -484,18 +468,6 @@ impl Transaction { } } - /// Modify the transparent inputs of this transaction, regardless of version. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn inputs_mut(&mut self) -> &mut Vec { - match self { - Transaction::V1 { ref mut inputs, .. } => inputs, - Transaction::V2 { ref mut inputs, .. } => inputs, - Transaction::V3 { ref mut inputs, .. } => inputs, - Transaction::V4 { ref mut inputs, .. } => inputs, - Transaction::V5 { ref mut inputs, .. } => inputs, - } - } - /// Access the [`transparent::OutPoint`]s spent by this transaction's [`transparent::Input`]s. pub fn spent_outpoints(&self) -> impl Iterator + '_ { self.inputs() @@ -514,28 +486,6 @@ impl Transaction { } } - /// Modify the transparent outputs of this transaction, regardless of version. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn outputs_mut(&mut self) -> &mut Vec { - match self { - Transaction::V1 { - ref mut outputs, .. - } => outputs, - Transaction::V2 { - ref mut outputs, .. - } => outputs, - Transaction::V3 { - ref mut outputs, .. - } => outputs, - Transaction::V4 { - ref mut outputs, .. - } => outputs, - Transaction::V5 { - ref mut outputs, .. - } => outputs, - } - } - /// Returns `true` if this transaction has valid inputs for a coinbase /// transaction, that is, has a single input and it is a coinbase input /// (null prevout). @@ -943,27 +893,6 @@ impl Transaction { } } - /// Modify the [`orchard::ShieldedData`] in this transaction, - /// regardless of version. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn orchard_shielded_data_mut(&mut self) -> Option<&mut orchard::ShieldedData> { - match self { - Transaction::V5 { - orchard_shielded_data: Some(orchard_shielded_data), - .. - } => Some(orchard_shielded_data), - - Transaction::V1 { .. } - | Transaction::V2 { .. } - | Transaction::V3 { .. } - | Transaction::V4 { .. } - | Transaction::V5 { - orchard_shielded_data: None, - .. - } => None, - } - } - /// Iterate over the [`orchard::Action`]s in this transaction, if there are any, /// regardless of version. pub fn orchard_actions(&self) -> impl Iterator { @@ -1035,14 +964,6 @@ impl Transaction { .map_err(ValueBalanceError::Transparent) } - /// Modify the transparent output values of this transaction, regardless of version. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn output_values_mut(&mut self) -> impl Iterator> { - self.outputs_mut() - .iter_mut() - .map(|output| &mut output.value) - } - /// Returns the `vpub_old` fields from `JoinSplit`s in this transaction, /// regardless of version, in the order they appear in the transaction. /// @@ -1090,55 +1011,6 @@ impl Transaction { } } - /// Modify the `vpub_old` fields from `JoinSplit`s in this transaction, - /// regardless of version, in the order they appear in the transaction. - /// - /// See `output_values_to_sprout` for details. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn output_values_to_sprout_mut( - &mut self, - ) -> Box> + '_> { - match self { - // JoinSplits with Bctv14 Proofs - Transaction::V2 { - joinsplit_data: Some(joinsplit_data), - .. - } - | Transaction::V3 { - joinsplit_data: Some(joinsplit_data), - .. - } => Box::new( - joinsplit_data - .joinsplits_mut() - .map(|joinsplit| &mut joinsplit.vpub_old), - ), - // JoinSplits with Groth16 Proofs - Transaction::V4 { - joinsplit_data: Some(joinsplit_data), - .. - } => Box::new( - joinsplit_data - .joinsplits_mut() - .map(|joinsplit| &mut joinsplit.vpub_old), - ), - // No JoinSplits - Transaction::V1 { .. } - | Transaction::V2 { - joinsplit_data: None, - .. - } - | Transaction::V3 { - joinsplit_data: None, - .. - } - | Transaction::V4 { - joinsplit_data: None, - .. - } - | Transaction::V5 { .. } => Box::new(std::iter::empty()), - } - } - /// Returns the `vpub_new` fields from `JoinSplit`s in this transaction, /// regardless of version, in the order they appear in the transaction. /// @@ -1186,55 +1058,6 @@ impl Transaction { } } - /// Modify the `vpub_new` fields from `JoinSplit`s in this transaction, - /// regardless of version, in the order they appear in the transaction. - /// - /// See `input_values_from_sprout` for details. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn input_values_from_sprout_mut( - &mut self, - ) -> Box> + '_> { - match self { - // JoinSplits with Bctv14 Proofs - Transaction::V2 { - joinsplit_data: Some(joinsplit_data), - .. - } - | Transaction::V3 { - joinsplit_data: Some(joinsplit_data), - .. - } => Box::new( - joinsplit_data - .joinsplits_mut() - .map(|joinsplit| &mut joinsplit.vpub_new), - ), - // JoinSplits with Groth Proofs - Transaction::V4 { - joinsplit_data: Some(joinsplit_data), - .. - } => Box::new( - joinsplit_data - .joinsplits_mut() - .map(|joinsplit| &mut joinsplit.vpub_new), - ), - // No JoinSplits - Transaction::V1 { .. } - | Transaction::V2 { - joinsplit_data: None, - .. - } - | Transaction::V3 { - joinsplit_data: None, - .. - } - | Transaction::V4 { - joinsplit_data: None, - .. - } - | Transaction::V5 { .. } => Box::new(std::iter::empty()), - } - } - /// Return a list of sprout value balances, /// the changes in the transaction value pool due to each sprout `JoinSplit`. /// @@ -1331,35 +1154,6 @@ impl Transaction { ValueBalance::from_sapling_amount(sapling_value_balance) } - /// Modify the `value_balance` field from the `sapling::ShieldedData` in this transaction, - /// regardless of version. - /// - /// See `sapling_value_balance` for details. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn sapling_value_balance_mut(&mut self) -> Option<&mut Amount> { - match self { - Transaction::V4 { - sapling_shielded_data: Some(sapling_shielded_data), - .. - } => Some(&mut sapling_shielded_data.value_balance), - Transaction::V5 { - sapling_shielded_data: Some(sapling_shielded_data), - .. - } => Some(&mut sapling_shielded_data.value_balance), - Transaction::V1 { .. } - | Transaction::V2 { .. } - | Transaction::V3 { .. } - | Transaction::V4 { - sapling_shielded_data: None, - .. - } - | Transaction::V5 { - sapling_shielded_data: None, - .. - } => None, - } - } - /// Return the orchard value balance, the change in the transaction value /// pool due to [`orchard::Action`]s. /// @@ -1380,16 +1174,6 @@ impl Transaction { ValueBalance::from_orchard_amount(orchard_value_balance) } - /// Modify the `value_balance` field from the `orchard::ShieldedData` in this transaction, - /// regardless of version. - /// - /// See `orchard_value_balance` for details. - #[cfg(any(test, feature = "proptest-impl"))] - pub fn orchard_value_balance_mut(&mut self) -> Option<&mut Amount> { - self.orchard_shielded_data_mut() - .map(|shielded_data| &mut shielded_data.value_balance) - } - /// Returns the value balances for this transaction using the provided transparent outputs. pub(crate) fn value_balance_from_outputs( &self, @@ -1428,3 +1212,246 @@ impl Transaction { self.value_balance_from_outputs(&outputs_from_utxos(utxos.clone())) } } + +#[cfg(any(test, feature = "proptest-impl"))] +impl Transaction { + /// Updates the [`NetworkUpgrade`] for this transaction. + /// + /// ## Notes + /// + /// - Updating the network upgrade for V1, V2, V3 and V4 transactions is not possible. + pub fn update_network_upgrade(&mut self, nu: NetworkUpgrade) -> Result<(), &str> { + match self { + Transaction::V1 { .. } + | Transaction::V2 { .. } + | Transaction::V3 { .. } + | Transaction::V4 { .. } => Err( + "Updating the network upgrade for V1, V2, V3 and V4 transactions is not possible.", + ), + Transaction::V5 { + ref mut network_upgrade, + .. + } => { + *network_upgrade = nu; + Ok(()) + } + } + } + + /// Modify the expiry height of this transaction. + /// + /// # Panics + /// + /// - if called on a v1 or v2 transaction + pub fn expiry_height_mut(&mut self) -> &mut block::Height { + match self { + Transaction::V1 { .. } | Transaction::V2 { .. } => { + panic!("v1 and v2 transactions are not supported") + } + Transaction::V3 { + ref mut expiry_height, + .. + } + | Transaction::V4 { + ref mut expiry_height, + .. + } + | Transaction::V5 { + ref mut expiry_height, + .. + } => expiry_height, + } + } + + /// Modify the transparent inputs of this transaction, regardless of version. + pub fn inputs_mut(&mut self) -> &mut Vec { + match self { + Transaction::V1 { ref mut inputs, .. } => inputs, + Transaction::V2 { ref mut inputs, .. } => inputs, + Transaction::V3 { ref mut inputs, .. } => inputs, + Transaction::V4 { ref mut inputs, .. } => inputs, + Transaction::V5 { ref mut inputs, .. } => inputs, + } + } + + /// Modify the `value_balance` field from the `orchard::ShieldedData` in this transaction, + /// regardless of version. + /// + /// See `orchard_value_balance` for details. + pub fn orchard_value_balance_mut(&mut self) -> Option<&mut Amount> { + self.orchard_shielded_data_mut() + .map(|shielded_data| &mut shielded_data.value_balance) + } + + /// Modify the `value_balance` field from the `sapling::ShieldedData` in this transaction, + /// regardless of version. + /// + /// See `sapling_value_balance` for details. + pub fn sapling_value_balance_mut(&mut self) -> Option<&mut Amount> { + match self { + Transaction::V4 { + sapling_shielded_data: Some(sapling_shielded_data), + .. + } => Some(&mut sapling_shielded_data.value_balance), + Transaction::V5 { + sapling_shielded_data: Some(sapling_shielded_data), + .. + } => Some(&mut sapling_shielded_data.value_balance), + Transaction::V1 { .. } + | Transaction::V2 { .. } + | Transaction::V3 { .. } + | Transaction::V4 { + sapling_shielded_data: None, + .. + } + | Transaction::V5 { + sapling_shielded_data: None, + .. + } => None, + } + } + + /// Modify the `vpub_new` fields from `JoinSplit`s in this transaction, + /// regardless of version, in the order they appear in the transaction. + /// + /// See `input_values_from_sprout` for details. + pub fn input_values_from_sprout_mut( + &mut self, + ) -> Box> + '_> { + match self { + // JoinSplits with Bctv14 Proofs + Transaction::V2 { + joinsplit_data: Some(joinsplit_data), + .. + } + | Transaction::V3 { + joinsplit_data: Some(joinsplit_data), + .. + } => Box::new( + joinsplit_data + .joinsplits_mut() + .map(|joinsplit| &mut joinsplit.vpub_new), + ), + // JoinSplits with Groth Proofs + Transaction::V4 { + joinsplit_data: Some(joinsplit_data), + .. + } => Box::new( + joinsplit_data + .joinsplits_mut() + .map(|joinsplit| &mut joinsplit.vpub_new), + ), + // No JoinSplits + Transaction::V1 { .. } + | Transaction::V2 { + joinsplit_data: None, + .. + } + | Transaction::V3 { + joinsplit_data: None, + .. + } + | Transaction::V4 { + joinsplit_data: None, + .. + } + | Transaction::V5 { .. } => Box::new(std::iter::empty()), + } + } + + /// Modify the `vpub_old` fields from `JoinSplit`s in this transaction, + /// regardless of version, in the order they appear in the transaction. + /// + /// See `output_values_to_sprout` for details. + pub fn output_values_to_sprout_mut( + &mut self, + ) -> Box> + '_> { + match self { + // JoinSplits with Bctv14 Proofs + Transaction::V2 { + joinsplit_data: Some(joinsplit_data), + .. + } + | Transaction::V3 { + joinsplit_data: Some(joinsplit_data), + .. + } => Box::new( + joinsplit_data + .joinsplits_mut() + .map(|joinsplit| &mut joinsplit.vpub_old), + ), + // JoinSplits with Groth16 Proofs + Transaction::V4 { + joinsplit_data: Some(joinsplit_data), + .. + } => Box::new( + joinsplit_data + .joinsplits_mut() + .map(|joinsplit| &mut joinsplit.vpub_old), + ), + // No JoinSplits + Transaction::V1 { .. } + | Transaction::V2 { + joinsplit_data: None, + .. + } + | Transaction::V3 { + joinsplit_data: None, + .. + } + | Transaction::V4 { + joinsplit_data: None, + .. + } + | Transaction::V5 { .. } => Box::new(std::iter::empty()), + } + } + + /// Modify the transparent output values of this transaction, regardless of version. + pub fn output_values_mut(&mut self) -> impl Iterator> { + self.outputs_mut() + .iter_mut() + .map(|output| &mut output.value) + } + + /// Modify the [`orchard::ShieldedData`] in this transaction, + /// regardless of version. + pub fn orchard_shielded_data_mut(&mut self) -> Option<&mut orchard::ShieldedData> { + match self { + Transaction::V5 { + orchard_shielded_data: Some(orchard_shielded_data), + .. + } => Some(orchard_shielded_data), + + Transaction::V1 { .. } + | Transaction::V2 { .. } + | Transaction::V3 { .. } + | Transaction::V4 { .. } + | Transaction::V5 { + orchard_shielded_data: None, + .. + } => None, + } + } + + /// Modify the transparent outputs of this transaction, regardless of version. + pub fn outputs_mut(&mut self) -> &mut Vec { + match self { + Transaction::V1 { + ref mut outputs, .. + } => outputs, + Transaction::V2 { + ref mut outputs, .. + } => outputs, + Transaction::V3 { + ref mut outputs, .. + } => outputs, + Transaction::V4 { + ref mut outputs, .. + } => outputs, + Transaction::V5 { + ref mut outputs, .. + } => outputs, + } + } +} diff --git a/zebra-consensus/Cargo.toml b/zebra-consensus/Cargo.toml index cf8424d1606..aac5cfc0c06 100644 --- a/zebra-consensus/Cargo.toml +++ b/zebra-consensus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-consensus" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation "] description = "Implementation of Zcash consensus checks" license = "MIT OR Apache-2.0" @@ -43,18 +43,18 @@ jubjub = "0.10.0" rand = "0.8.5" rayon = "1.10.0" -chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } +chrono = { version = "0.4.39", default-features = false, features = ["clock", "std"] } lazy_static = "1.4.0" once_cell = "1.20.2" -serde = { version = "1.0.211", features = ["serde_derive"] } +serde = { version = "1.0.215", features = ["serde_derive"] } futures = "0.3.31" futures-util = "0.3.28" -metrics = "0.24.0" -thiserror = "1.0.64" -tokio = { version = "1.41.0", features = ["time", "sync", "tracing", "rt-multi-thread"] } +metrics = "0.24.1" +thiserror = "2.0.6" +tokio = { version = "1.42.0", features = ["time", "sync", "tracing", "rt-multi-thread"] } tower = { version = "0.4.13", features = ["timeout", "util", "buffer"] } -tracing = "0.1.39" +tracing = "0.1.41" tracing-futures = "0.2.5" sapling-crypto.workspace = true @@ -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.18" } -tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.18" } +tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.19" } +tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.19" } -zebra-script = { path = "../zebra-script", version = "1.0.0-beta.42" } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42" } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.42" } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42" } +zebra-script = { path = "../zebra-script", version = "1.0.0-beta.43" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.43" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43" } # prod feature progress-bar howudoin = { version = "0.1.2", optional = true } @@ -90,10 +90,10 @@ proptest = "1.4.0" proptest-derive = "0.5.0" spandoc = "0.2.2" -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } -tracing-error = "0.2.0" -tracing-subscriber = "0.3.18" +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } +tracing-error = "0.2.1" +tracing-subscriber = "0.3.19" -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42", features = ["proptest-impl"] } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.42" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43" } diff --git a/zebra-consensus/src/block.rs b/zebra-consensus/src/block.rs index fe8499abfba..1c959dd284e 100644 --- a/zebra-consensus/src/block.rs +++ b/zebra-consensus/src/block.rs @@ -75,19 +75,19 @@ pub enum VerifyBlockError { #[error(transparent)] Time(zebra_chain::block::BlockTimeError), - #[error("unable to commit block after semantic verification")] + #[error("unable to commit block after semantic verification: {0}")] // TODO: make this into a concrete type, and add it to is_duplicate_request() (#2908) Commit(#[source] BoxError), #[cfg(feature = "getblocktemplate-rpcs")] - #[error("unable to validate block proposal: failed semantic verification (proof of work is not checked for proposals)")] + #[error("unable to validate block proposal: failed semantic verification (proof of work is not checked for proposals): {0}")] // TODO: make this into a concrete type (see #5732) ValidateProposal(#[source] BoxError), - #[error("invalid transaction")] + #[error("invalid transaction: {0}")] Transaction(#[from] TransactionError), - #[error("invalid block subsidy")] + #[error("invalid block subsidy: {0}")] Subsidy(#[from] SubsidyError), } diff --git a/zebra-consensus/src/checkpoint.rs b/zebra-consensus/src/checkpoint.rs index 039ea6e33e3..36b3a76d57f 100644 --- a/zebra-consensus/src/checkpoint.rs +++ b/zebra-consensus/src/checkpoint.rs @@ -992,9 +992,9 @@ pub enum VerifyCheckpointError { CheckpointList(BoxError), #[error(transparent)] VerifyBlock(VerifyBlockError), - #[error("invalid block subsidy")] + #[error("invalid block subsidy: {0}")] SubsidyError(#[from] SubsidyError), - #[error("invalid amount")] + #[error("invalid amount: {0}")] AmountError(#[from] amount::Error), #[error("too many queued blocks at this height")] QueuedLimit, diff --git a/zebra-consensus/src/checkpoint/main-checkpoints.txt b/zebra-consensus/src/checkpoint/main-checkpoints.txt index efc721d885a..e43aede25c7 100644 --- a/zebra-consensus/src/checkpoint/main-checkpoints.txt +++ b/zebra-consensus/src/checkpoint/main-checkpoints.txt @@ -12344,3 +12344,121 @@ 2691206 00000000015ff7395bab470fe1bc13758db68653bbcddf26f4d967817bcb5f6c 2691606 0000000000b35f7d242f8456123e83718c33af77072ce6cf709bfb34cb59fd3f 2692006 0000000000cc6bed9807a23d703d66735a63d615a494c5131c7f7c9f1f464cdc +2692406 0000000001719294b9f2ab2da8b9053768b624df557374f07c6aaff98d4b46c8 +2692806 000000000130c43396cca8b6417f0901e18cd5a8bf1b3da623a0b61e5abcbce7 +2693206 0000000000c7e0584fe776819a5e55d3bc800f9246adc55bbc3f152260e52820 +2693606 000000000077da042b72562c73c56dcacecd051cc5f1879493124a874f1560b9 +2694006 00000000000654f35f3dfd10dbc58d0a802f51b0e115e7597ea5ac941f8763a8 +2694406 0000000001327f55a0fe270e62387634b2d2d520277819e8f754d220c81e3068 +2694806 00000000013fc817d8c8e775db362ec09f1db5b8e49ef828f777d92fc0a01374 +2695206 00000000005f46bb00499b12074e9f72068f54cd37a29b4b77f48830306e4a50 +2695606 00000000013c4e60f25e9598cb19ae88999fc37c6be9b8efabd63baf603eb705 +2696006 00000000002392197019860ce6454e1c350036deb1173221a63b41ddd697d1ff +2696406 00000000002ba32ef8303fbf0ae0c27b8efc8057326cf1c17a5bc1cb2e1c167f +2696806 000000000172dcf83e463c42e7182cb21ad88f45a05c2c2b215dc320aa64c901 +2697206 0000000000e8a861d3fc8b30cff546a9bf337f89fece6d7a2ae71bb96e9f03ba +2697606 00000000013239c916a0e7c570d74067acd9b3dc5b350a66792993ff482bf4b3 +2698006 000000000012c16a08201040d43d0e6eb48aeca4a813f282302eb373c42804cd +2698406 0000000000d1548f3bae43987b247139e3b75de76246d14b44b21e6ab5bca052 +2698806 000000000146b5c34666c28501b95b72d253f241d7bd5a04d5c8ff01999e359d +2699206 00000000000c0578548ff76fed79afe9f84d97e590650904e62ee59b74db6f2c +2699606 00000000003e82ecd981993140693ea4a9cab188140e3d41626e8dfeccdf1ac0 +2700006 0000000000480d4924ad826fe000987e30c822f116f92d86518b489295b9df56 +2700406 0000000000a09f64f18d3e16588ccd7be4b7cc456af5830bb7645581b69b9fde +2700806 00000000011ce5fce0533f962ac3c1679ef02bf6ce74806e402560803e94a3b0 +2701206 0000000001019499edb3ec84cd89aeb63369261df6c2f5c87916b4e5a33be071 +2701606 0000000000c233d87ad99e5da004c720612056bdf95b88ab80fca69b29ed4677 +2702006 000000000028b54c7a711b408ea9bc83591827f9d8cfe6999beb1cdd3eaea073 +2702406 0000000000971036bc5760e7f18aff82be5b7745eb87f510e6395e88ad545273 +2702806 000000000027ca2a7d39436fb1b77d2ac7287343f947a273110810cea40925dc +2703206 0000000001422dc0ab6fde9670378abc2e2281c8b17d780a408f54b3d64ba535 +2703606 0000000000a5b138ef9ed9081d52b4a388b04945e97eebbd96706b39e6281cda +2704006 000000000188288e78ba15e6c7e09ef918e0fd5828304d503c751bf5a86c4a8e +2704406 0000000000da7d23dd4e750c56d1f1c7932ab07cf07c0105622ff70a422b234f +2704806 0000000000abd25ce416024d8c33fb9e4cc0815e43a74609a40f8847aaf02f86 +2705206 000000000138bd820a28a5191109b825996f52d9c30bf0ff95998205f5d68c67 +2705606 00000000016c7c5d0898e77f9f1bf4e0cdbe5fe94ee55321d2fff3be61195e6d +2706006 0000000000d28a4fe5275aa58b38730b49232d9f5db9b47f6f63f0e64177b083 +2706406 0000000000b8deedeb5f8733df0929bdd7030fb904e960845e6c5d04bafb9841 +2706806 00000000006cf18461d2d4c083b930c115c7f941856acbdbc98ea2c31f60ee2e +2707206 0000000000ae5ec2e20db9281d76047afda9670011e685691abdde3cae3e7fa5 +2707606 0000000000a44f9dc170936b47fc7b73a05e09b6505bbe4248d1f3444474f395 +2708006 00000000000c4bb2c4b279216d4669cc4a874cfa02cfcb49621277fac12d5654 +2708406 0000000000ceb61df7931a951875a5e4073480d58302aa2e4edb8b2eacf1fb45 +2708806 000000000096a4592dd90842479c001d8582f33becac44e1bdd5517490b18215 +2709206 000000000077f8d5905c37fa58894d44fa5103627b2dd19cb4a10143c0863986 +2709606 0000000000a022191870eaad22ef715e6500236c758888f6c07529bdf113a881 +2710006 0000000000f2ea45e0ad6cf78d4ac3dd99f3ab81bf3980fcc88059060d0f268d +2710406 0000000000aeaebdfca9b678fef0d67ec844c78d33f1386f3a8d30af4ee2ea65 +2710806 00000000011730e525ea25329e3e02893cdc1d38d35a52dcc4b765717fd0221f +2711206 00000000002e7fd21932cfd2e96586b71f7cccacf725261eaad61ec786b90b8f +2711606 000000000148c6852a28a12fe446477917a43a920c8344cdabc8eec3b0764d40 +2712006 0000000000746066e4338ae28389d8375fc26c15594dd10c1f7fb12553223cbe +2712406 0000000000cf64f0adeb4bc28a5a8fbf1628e84335a85185771ca804cd96c6cd +2712806 0000000000b80c770d2aa384731b79a71e1954db52d96a3de92342a48a93c8ee +2713206 0000000000e96bc60394746637a86c9d5839e4f9a9e8786fe50313f2b171dab5 +2713606 0000000000c14f2332e959fbc97e5fe4758923ffe7c767e292b47560336f86b5 +2714006 0000000000836341146e09e9906d9dfa380f07faf9b613709795374294c7fe87 +2714406 000000000082b4a0d76e938a33622aceca82f42b3136dc040b2c9d5937695633 +2714806 0000000001043da14f2fa881a8094bbc28b93d14ac7430b58ea36d4cb6b293f8 +2715206 0000000000bc0fee420372d6689c3cfa5ae13717d1f39c22796f2535f1a73a9e +2715606 00000000005a3d84d757000163776e4618423c437f1eab6ce1b2ff6bed7078cd +2716006 00000000014409956b84dde91e429c1be89e3cad8ca0ef2dcccb780b7d6002c6 +2716406 00000000012f4ebcb2c8e3deec9c14394f5e45ecb27cdde7fa759309529a5cca +2716806 000000000167358bb721422b1a88085186970ba1971d5bfdf4740ebe032f5ae9 +2717206 000000000077558bd54cf80e3ab6f0de23bb03a1c445edb050f75f56412477c5 +2717606 00000000002037120b696cc8596e9fc72dbd18d9b408abf7c29565e9e55c54ff +2718006 000000000072f423f72b51da55941c9133539b558ed9b44ce16c2f9baf462ced +2718406 000000000057e13e5699aa6796d2ca239c246605e7613972ccad0c13fefa1581 +2718806 000000000050dd5a261fdb9c635c2a44898a2323644eb5c74f055ab7bef96eae +2719206 00000000009b16918a52fef42ebe424986e239e00f12a46f788b5011fda21a01 +2719606 00000000007e5b53a638f464b402d4b53f1792af7413ef03649c35adcce31255 +2720006 00000000017f5646a8ea5eeec64fc9e52ce39196e98ee99ba718104fdbf3c21d +2720406 0000000000344133ec5c445b15a0ff6d1ece61b5e652445339124aec5d96f76a +2720806 0000000001158b39b245a964dfccec47d729b1c490bdc31588daa676d6ff08bc +2721206 00000000013fc4edf50ed74fc9ad68b4538eece10d39defec750ccbb084f6898 +2721606 0000000001b06cb25d6366c132893aeffb1ad79dcde6483db86e4d326ef288bb +2722006 0000000001207548c359ac039814559bf1e904e119d87216873274007c81694a +2722406 00000000010381376305bc609c15609e47a620cd6daac3479c993923a0da52c8 +2722806 0000000000547bebf1fbdbc32ab4816d9e1f1156bee60000c5e409713818afe5 +2723206 0000000001d918552a17534809df3a3c5225ff2d744c602e8f8e15f073bc0090 +2723606 00000000005c9c3cacb8a20277e75d3dfb07f4aa6e57ed0ad882432b7fac2759 +2724006 0000000000254615bba1b7562cb6a9ec71eb37942896b90cb59094e84fd1b8b5 +2724406 00000000008304748a8e8cbd37bd35925922fef221f2e89b94ffca2f8dc869ba +2724806 0000000000748a0f98d8e9a2142cd3933215bb988fda7252f9142cd841a4ef7e +2725206 000000000100c7908579b0a84e8256800606f22d7bf9360a174710032f64e9ef +2725606 0000000000368a867e4e2e1de339421317a37559fb21aba48b9115728f248680 +2726006 0000000000417a6004bdb7425ce22afae17a36ceb07ea24f3adbeb24bff65588 +2726406 000000000043e19681c7f3615a2a0a4e8b2f9dd55e122a5f7951c2f0afc97296 +2726806 00000000009e59eaac7bf02a11b2cdc43e19e69120248486b8e7e4075b2dd429 +2727206 00000000005e2adf49313bfea70c4156b1d4ae198f2eda562b3db705c32a20fc +2727606 00000000001db4277992d05a65af67a5bcbb1552657089591227a929d9966161 +2728006 0000000000b087e075e1e8dad82c1c8b67bb53e87da160e510b924e2f7988ec7 +2728406 00000000004b1a3ac42a6e78e13b3f7ba977751a859fb5f60968dbe2cf87e2fd +2728806 0000000000b79c00c6bb038b506333d8c2673f5a5d342fdafd937b20269cc8da +2729206 000000000038c2cd1b637bfa6b8b6f3c1696c4a87480d721c225dce9c6793fbb +2729606 0000000000772fe945a800db3e985ed6215abf00f3d69089153db01bb3e78033 +2730006 0000000000ad655ae30555a51f42e8d306bf85f05932419ea32a433e2e2f0033 +2730406 0000000000e623163acadd8dc93aae236c30986b968186580252b62a1f1eda42 +2730806 0000000000c3b50862f9475e78188f26cd067270a732d2defd8447f0b772f41f +2731206 0000000000bd104088a1efce928751bfc5a30360e65fba79f5187aa54a62be8f +2731606 000000000089bbec3013f5dd80b18bcfff6867bd49e95025e4ecb53dc1a1172a +2732006 0000000000df481eece9a5c6ac62a139302a116fb51cf521caa83a0dfdb29cb3 +2732406 00000000004f232180969382def2c69441525316f8cdbd498a74125e40713f0c +2732806 000000000039b11c58d7ace91033e0ea23978923f9015306f6ea78f8ba28ecb0 +2733206 000000000008606d81858a5bab587aaa1c10372c58a49c9b628b0ee475bd9ffc +2733606 000000000069b4e86514b95def4d2dda4bca6c438b6ad6c387b6ed3d77a5e674 +2734006 00000000016ca8b02d5ab7d94541ca77aa049f97d040c97120085594a04d8c9e +2734406 00000000001ed80068b9b9a5a9390cae0ba8ce169c1a2b8bec6dde7da01165b0 +2734806 000000000151e6a3a7a81ec264a759254408177718d632f1106a1b29f14f834d +2735206 0000000001e4d3d4e374a03df338bc49e302f4787fb5c3dfbf193ccdaa5278cc +2735606 000000000050be3b222e0dc27e522eb25fe47602b6bda9b2c7c4dc6b62afb33f +2736006 00000000012c29f508369a766803b7d5cb1f320a19cddd81c740d9a13b299580 +2736406 00000000001f30ea9fabaf68e65215927c721d46cf7bcab73d821f0d0ff6f966 +2736806 000000000122add7a1ea562a2bb993caa8cf74b802c9c1162c1d5387327196d9 +2737206 0000000000041fa435da22c217c284bd09cf6d748d0b6ec2faa346405fee18b2 +2737606 0000000000a2b51c7bd9e62bf2d7bd7735c55c99a903109b535e0ba3c1bc2018 +2738006 0000000001624cac6147f134c18a698b8ed35d20e3db5be4cc7d33250fa024d1 +2738406 0000000000e0fce4549ce421eec68895d377bd63404846e1640b82a19d93164e +2738806 0000000000355369814abacc697c0ac355f938c32cf6b3cdfa47857a71685717 +2739206 000000000090219b6c7c7fcc5890c632ee9322f77c193239208bb74bac90df53 diff --git a/zebra-consensus/src/checkpoint/test-checkpoints.txt b/zebra-consensus/src/checkpoint/test-checkpoints.txt index c1c591b9200..5108ce28405 100644 --- a/zebra-consensus/src/checkpoint/test-checkpoints.txt +++ b/zebra-consensus/src/checkpoint/test-checkpoints.txt @@ -7593,3 +7593,195 @@ 3036800 002aa078e4546a72e4c6290402924c0917c2080a4dd9e0f7e7e851e82bcf562c 3037200 00613812406826a9bfa52508d602c8d14271c4dcf1cee107a9d2b8cff9ef51b5 3037600 00b758e58e0b8f8298a52e0246860ea833e6dc3ffb447d44474662c658b373c0 +3038000 002b275b2353025a6df5394427ed4674f0aef78aafdfa244e8ce6abac02f7dec +3038400 0060e905d468b737ed368651689bb7e4e2825504b25b7072da17b139cd6472b6 +3038800 00255bca8bed78bfed0acce0bc649d45c8b70cc91ee160e2571af7c17e3e5d49 +3039200 000b2b00897971a8025e2863ce37ca833ac6c65d2c9726c84ccf7f8df86bbfc3 +3039600 004dc1a6e654d9341e75cea6e2eff58195de7401cc1b133a6bc61b7561677ad0 +3040000 0025d5483bbed4f4f06cd5d4abbb90e130989d87e588835c31928c3966894534 +3040400 000ffb7239cf37ab16fe809012ab70f932a428dc4965f8faf6bb49ec1b98ced9 +3040800 0043fa33cdaf798be000cc176e960ae5f010597f6881437d0e82ba0f6c39bcb6 +3041200 0012f0dcddd47d78a9d3e19353a0850dfa06a809afe5b5cd489860e949d6b390 +3041600 000be374304e917b4d89a52d6bc8a9710981bf2cf9b2ad2a23eeb7999d4be09f +3042000 00026e6ae0f0dd1ced7cf683e87c814b8455e5ce9b01313a6bd0210114ad1f70 +3042400 00124b369ce53ebc43d2804c5eaf83ab5b15c1cb7a32d122954c8210fc3c80de +3042800 0027ee94859109c8cb2e51f6b99116219ff851db25b2aa1d04b1d57254f4ac00 +3043200 002ce8dfdebc789253fc9c252980c415ca54c1ae2bf96a56060610eadddfd10b +3043600 00233625e84611ca0ec3015365d06e334b9fef2929d3299d56497d12d97f9350 +3044000 0017b85cb414f91afcd15dc5fe636e6ae2da455f37aad631b3815f14528b1f6c +3044400 0089710ff7f5451688ba1ef4754c97d19cf1160268d25f9d5fbe0215b3a0c8d6 +3044800 000c8787710e8b62cbc1e530cff52830246169ab43ddc6a5a81a1c29606087cc +3045200 0041b972c5a63138aa77dfccb896bb1f8f47d68aa709a10f05b89432cfde24dc +3045600 001f73a8c1eda7bbea0786d9a53939d86d97315ebb4105a06d5f94ebb857266d +3046000 0000086d005def50e042df7b4b7aa87b6e0b284eeaee960180fca34494f3be63 +3046400 00338754bf6141086307cc067eacef097b4806e72ade8bcf60b91aadd000700f +3046800 0004c463aeeaf583853d4ea4afcb8e7201cd81c09a23bbe7a883ab4ea1018be9 +3047200 001068978bd221fbe0735b4192f114408a56700f05fb42a2648428e86aae0b2c +3047600 00270f4b4a5254c1d12e2b2c63b8e3e6af8d192fbf06944d6cc43d0743f0401f +3048000 003a9234f6dc8513d269412d4fdfd0dc82f21229adcff4f6e90e9f0eb9df625a +3048400 00774298d7fea2fb11f8e59ba3f5994ea7423619635c2e7d56f59d85f46b3807 +3048800 0063497b0d4eb27db72400c7caec94fabf047e0cd2cdc7b77957af2b985d4305 +3049200 001dffb8de633e7d9d49f495c27bdb9e80944d828c046404b77d67b3b4a35c11 +3049600 00a8f0c1268389b6fd94c91f2bffbf3245ded41069230f859ee46c1649cdfec2 +3050000 00287c032a0faf6ad198621c12a1a39c4f808cd8a86ec5b202800911226e7596 +3050400 00897717c241e74614639a15eaade8a94c53834ee7bb5520d9d237db2899a711 +3050800 000aa00670b75e356d19de9f98472f79087f9203db451e912bbee10d549e334d +3051200 00089364d1fd3bada465cbf752d47e4d5762fc18d7eaff9bf2179d46c4de3a90 +3051600 0000140a83613ba9871b621198fdf1823b4efe65ea92ea302941f0854bc24e8a +3052000 00029c4a8e994635a74e47990709a530a23589def9b62a457a6e6fc9ae506b52 +3052400 003dec3cbb59091b0a7cb89439b54bb8abf98240b998ad8f936ac85ad41050c9 +3052800 002d6c9c31e6981196aab65bc22a3a8e23c591b353b217b0d23b056b6b9f3f03 +3053200 00088878490efafabda8a968bebb5cb3440e4a81b8f9aed0e991c5ce63fc8f74 +3053600 000b9da54d53ea80616f33f789b570652da5af96e7153be8be51298e987c49fe +3054000 001cfe4680b003ce5c9ead4c408584b193be42e6daf67b37949120f6b0ce9aa7 +3054400 009cd5f6a5b5c7a79c5db5b8331bd79c40685d55ee63beb703c298c5420d9261 +3054800 000b6eccbb9f31eaad59d99548e47da914d88cf07c548b8767433debf15d8521 +3055200 00268f197db8b82627bf5fc8ea6b7ac034b63346c71877b795237f62f97c4136 +3055600 00051269be6258ba6771ee4baf14ff858d629997ca4f9aca1982aed220f765d2 +3056000 003706aa5b50e2aa9b3c3cfd9f8596ec442415ff7a84c172c18c8be29e796ae2 +3056400 00231455ba8aacc08362d49a5b6ce10ea6d58e84b00a8429cd10ccd3c3f2c8ac +3056800 000d8c25fa2cc7513f4271c5a9c46553a6aa613792f7910dee342a1e9ca2fa38 +3057200 0061a06b58b986335a9dc8bbe6ca00cb2c6c10f6a353c58f918dcc4a8ce85e2c +3057600 0001451d88c0b797bed1df42013c884696d688e76a59c3cc23508d78ff63877f +3058000 00093fe57c9e88dfb745e3ac9ab599fecda530397831fb1c2cd1d7a7b73bd0e7 +3058400 002c2bbf87de52c0e952e2ed4ed251dd781557318d2ffa52579029247543dbdd +3058800 000be4cd26e21a47bc7e8c63ed52fdf43fac30c4daca0ec81a09d74e80110bf5 +3059200 00b3b55af59ff16a236ef59155d8b3a0629a070f36a929fc375231b3c7fa1b51 +3059600 0008b5cab206c1c031f86d3d4a850c8d9bd08f4922e63b18af8abb25abd18ba2 +3060000 00454b294ded8c84957a04818d2eb80cea14dc211b500566df144e9ce1d908f4 +3060400 007a2d891769b8ed6f622c478364f46aa705dd88ef5457b6567e74e4c13bc193 +3060800 002513a66017c010a03f3506659287cd8e8ff2504ba03cbd04c5817fb49e8a74 +3061200 001aa3722bed76457b12fb1160a1d938ef4667100b86dd127d72e3adac17a35a +3061600 0003c549263084826cdc44b4960e9b1b1fed3205d4e52166766018e3b1454ccf +3062000 00100bb1d4e862fb306a3f9c814206231e3be94d6be32a2de5bb81bab7333792 +3062400 0012c5fd7aedf90cd9724cb721035cbb8f950043b30b4b427e31818d78dc1231 +3062800 00243a998fdc6addef61aa7500935b5c908961902b02212d982ef79034965672 +3063200 000fb809f7485dcb4772d8829307e0eaad61bc9e9d4db96ba4b8a28b373c3188 +3063600 00000cfc63b29fb40ba9af2eb64072c36651376f0fa1117cb90e20a6774b0759 +3064000 000e6c5afbb3e4a9e799e19c638d8b81d5a765691b7513f4a655e7a4371010a5 +3064400 0023dbbf18837786a7e2e5febf3165460150196000531053984f7b664180ca52 +3064800 0000429258a5b5feda9cbf53be3db748625888a5f49b8621b7b752b212e50aad +3065200 0001648f1bbb0dd35b0837d9a1057feb00a60f2168f2741d8ea36d78b74ff323 +3065600 0024aa77cdb10bbd8db78dd3a241960f8e38a93a90a37ef1b19fd55361bc93fa +3066000 001bb179293a5b199f06bcf6559806e81cd66fc943630d9fbbcdc58f81f172ad +3066400 000ddc0731195b15357b33d0b005e7a3e847be357918e2e7c15c9eedfa1e5358 +3066800 00035d966707d7720e2443ca3c9ed3565eb78163a97abf7d9d782be8bd3ab47d +3067200 0035d2a57985db375da1b8f20a977804943c479c0082b1e6bbd1cefa20a90b9f +3067600 0010cdc0be90498944a22f2be25eda0748799547ff49c1f2f75ddcd05bce67af +3068000 0000f5fb08ccf621eb9700c38bce3fa6390283958033dbcdb4fee008c3d523fb +3068400 0000d20805c301427ef1ad3f4bfc8d8d6034a536793af9b2f7437b6799fd3dd8 +3068800 000e1a66398682e4bc3dbe2e8ccbe31e06d4d53bade3e819069b14880a7cebfe +3069200 000f62ddb00d2fe8f51d36e36037e186d169496ac445e938993d511a7283d664 +3069600 000302254d59cd18325e60c0e612fb7fc8d77ff42253359568c0f192df767b13 +3070000 00057e5c43992673287bd6d01430da84d16248a3fd135a711d3dd3775da24345 +3070400 005fafa064e6266676b4f4c3c18296f1a296d2fe2e2b94852ecba8d7fb4a128d +3070800 001933baa29920ee136eab83bc4125fc0d5aa0ba2f0248bf9869fb589f125ae0 +3071200 000363e118285f938c8cfc07d1c3cf87ac0d4f3c94200cf977f2c12f3863bc14 +3071600 0021628326c18a40165b081c65d1789a94afe94eb0f36e2b711b19cf81630a16 +3072000 000f04047cda3a4d9e411f461c99ae3d18ffcc742f4d4356a8cc73a4f7b193e0 +3072400 0049d642a4d10e2467ab28811f9399987d27e5ff70c895b582ea63b88145f9fe +3072800 0013403fc552ee5f5a6ba9e8badde6637284a5445e507c139f9e5ece52627cab +3073200 0014953be26e316925d1a614c6180c92d83eca3981711315778114948df4ee74 +3073600 001072ee9bf464edc8dce5570f7d88bc1d5da7ca3efc8f6b70ed9be10024ed6c +3074000 0003e41ae24f76920f60479acf1daec054d0aa05ccde77e102d517646b2945d9 +3074400 0073f49a1fdd233d611e873f13a8a3e2a49d21955e1dc874c39fbd05b9968a57 +3074800 0003252836bb64c44721ff3bcb2344e3a95070fd06b1736f8e00d46b0bc979c0 +3075200 000da4574692c6079f6c8d9778bfdb3d9903048bd2a70b3126982fd9eb3a3acb +3075600 000d222bd083f9afb8554d13304826bf3cdf18d23a1792023a595ae3a3aff3ab +3076000 0031d8197b93b4de0a00fa083af96f03da6ab8a29d6011d18f903b2d11255a65 +3076400 0001186268fe57286c5179d2d08fd84106411e6046289e3a3dc6ed62839c50d7 +3076800 003b92c5c6535057fd0b1b27bc5f40bf0b61f2ee6c819b311e83b5e23c03734a +3077200 00225ee824d6215bdae39bf287348d6e1e9a006ed3969c7b9e567e5d2688dda1 +3077600 003437d51968b90c3193857ad7d91f24a0ead3f6a2c3f5413d188bf8ca83fdfb +3078000 0017b2825c2cbbdd28d7de69b7acca6a438d0e23645c334f6ab50aedab43c7b1 +3078400 0068b1ff49ef63d7546b9fb4a2ec45636c4ee79202410d68bbe9f69e79795256 +3078800 001a5f6d5c2db65bf3ca0008d7239320cd0433145d471beb1b02c7891ed45f9b +3079200 003b043bc941e75b0b4bc562cd3e3723a89d6b246e8fb2abea51275ee6db7dae +3079600 0009c550566b460f43fecd568e9150f9f0e6c762b87a9203fb36da5f2bb62b4e +3080000 002a90e74aafa829d2aeefe4f8572edddc7f1c121000c21f6f87aa373671687c +3080400 0000640d26b6b09c765d9417687ae4df2919745079caf50cf2d3f069b4dea9d3 +3080800 001ae1bc5d111ddc3dc341430f311f47f32ad4e49587aad4ec195e76ce188c97 +3081200 001c77876de320502e3652e38ba88051ef2c44938b4a5cf052f09c1a8cb283c8 +3081600 0032c9d59ac0906940956d6842cefa7d9406ec8b98f8494352146fa6507643df +3082000 0006bcbd93ca1ff0c90300b16859b831b645f517468fe5ea4904b6d1d3ca2d73 +3082400 0016844ea05418d3f6314ad167ded7b6afd0aa68d82094148dd087a9eb2d8f7b +3082800 0017e6a00b6c3b4505fc10370fd07437050760ff62fc7d5bb98c53d21b8b874b +3083200 0015573f154381dca3314a1357ae588f5c19e07a6ab535b27d8ac7b87ab4f28e +3083600 0014a0275af4558cecc05dbbfe708482faeed2b7eec39ffef5eeed276e8631f7 +3084000 00012ccb75dbbd6458e42c61b8d8dcdcbe33fedc0f23d2738237fbaf678dcfa2 +3084400 00111b2337ba9555a0eb19799d0ac35c7b049fc25a18e352d33cbdb55bb2e8fe +3084800 0010f64a7300b21203af4d703645fafbcd69fc5a89564bb6a77494a46772b695 +3085200 0011387cbab55c2bc978c3c361d3e4d638bc8fcde83924bcf87735ca516ba9c3 +3085600 001f5b47365ac260636f49a43cdade89533d0598a0a68ade57b7a3adf8357cc0 +3086000 003794bcc161a9828e427565b897e606ba7f192db463448a28535f98e8e870d9 +3086400 0013610bc88787c11e097004411a942773725d6cc2e8931b5da4ddedcd58b24c +3086800 0008cf7a82b631c5c3af30c3268a1bde628c46cf7259e25707a4aac99e1d9afd +3087200 001631f4a41753094e4cbdfbae797f5849cfdc5390ef036781d4fc5c86b0d857 +3087600 0020955101b0cdb440516dddf98fa55a838f64eaa727956b7dc13e6faf96eaf4 +3088000 00294284c2319afa1d20a3d49d4d177ebc701430d0665e030e82df042beee9fa +3088400 0000091c84f7cdd7f0bb4c6bbb6dad96983cc7614e595f317683e3c99d4c7886 +3088800 0000083ab66d0981f2a4e18d8140ded717c6b3aba3f3f7661ac6f6c80f4613ef +3089200 0000008e429556fbb566b6e8ad11b4f1de74e46d30d3bb1451667c4065dcd544 +3089600 00001c788f1d29a6872edf4735760339f718bb3c715f3f7143252177079b6c9b +3090000 0000005a823524433c61fd1cbb2fede136319c2a8ff583ec0a7376fb00c10584 +3090400 000024764a8bfd61b38d5a6dc81d2cb8c3882ad78c295789dc6a1f828f61ccc3 +3090800 0000003b0197f74feeae442ade58f4557d7d9b6aa1ae8f7eb03982b4d378ce41 +3091200 00000096f8478b95c02b168809a75566821115107e03fd08c184fbd9adc53aa4 +3091600 000e99c7e07dc5fd96258ab1d390e877d37e3c25a30cd9860c303f5aac081f97 +3092000 00790fdd32786461452cd2fd740b157717ff056fcdc91fa7e19027d16f6289e3 +3092400 00002b63a2f6ce1df3c7cb7485473a6467a890034e4bd4372124f2367c75e187 +3092800 0012cee344d0f0ef65573cf811fce6be9a23c54822d23e2c07f03f973c6abdf5 +3093200 0011756eee83f0545c479e7d7308578c076be9e9b1e54137aea9e20cc59d9068 +3093600 0007c7491fc9085b3f4b9484ad8718574992bf46c2bb081944c2c4ae5472e9b8 +3094000 000317a2a0a89506913115479aab1902cc7c67fdf9bc010ba484382fc6a19e2d +3094400 000b7f776ef1e89b609a459a74c89142fa41f0ed37233876b17d7300d74d7de4 +3094800 0020dfee5ec6734d2191b2f1645e22b6861a3716bc9092e7d11ba8f4376cccb0 +3095200 0002ac288cd2c643fe599f950f400ffea117ec67d7dd0de4616607802ec59b58 +3095600 000d32e4326fe09a3c3f55d2c97d5d41138106a47ba46cf7f89e26b0289820da +3096000 0017ffde279b7d98c25ad7972dea2b729d5d218ef7f7a457bf7c6b5f8fa1cf95 +3096400 0041ce2be54fda2aaa6498af0756223d6573e4929e7f433653c8078b0fe42849 +3096800 002f33fe3c301f15ee4283388ba9bbe559ce29c55920082b767be0769fd3badf +3097200 002eb04d80df1697893fdf5803720baa7da490c21cb279396f233002c4be16e7 +3097600 004051fc27ad8477b33085de1c01ca019a0d6768287bbb5a44a4d3481d7d3c0f +3098000 0014903099d44d1f8050cbace8bca99c004fc592ca94407ef584a15359921e54 +3098400 0026b3c712ac8346f07c4e6cc50818c7c1a0bc1e2f18d148f5cd3a1e4af6d513 +3098800 001e90fa87d94e2173e4113bfe5be4b4002e719160f9541c47015d05c85e7299 +3099200 0074ba5571808059b238f3ea60b22f1e76c229e90e13b8552254e545ce4abbf4 +3099600 0025ae185be2e354433554d914a51682611315b1a9dccdb65b037934a0200e04 +3100000 00472745b17d64bd1830f36128b3c6f8c0c9c519a367f00bd7995af941938e5f +3100400 01132001bef77bd3cc5cbeec0da01a62e4d8040cc58cde90773b3fdf69c9c64b +3100800 000cbf09b04fdf85ac76e5b4bfd8cd1e8f17826825df011e9e62ef690575304e +3101200 0016010211eb89b9da9a29a03f721bba5d30a68c4f7dd59f2eecc69b20fe4643 +3101600 005bbb618224113a7e38cd900c0295dcecda34bdcb0aea8a2ccc11554e931495 +3102000 00146bc3a7c64c732ad305b19d7447896d94a859892b53216ae6d011e643df9f +3102400 0021222c072d8bb21abacaa0b3e5faa9217742f6d14726735aced621377b7fa2 +3102800 000125806f3ee943302bd1485bcd2a1c379fa363696cdb564a77ba6b7d9aef9e +3103200 0014d439e6a76d0471c456511dd7836ee11427531ae0fbfeca8316104a6d4b6a +3103600 00090f38ac393611ee9c04f650c1f0aa90fa826418dd305ac08c9d4b326594ad +3104000 001e003e0acb4d8afc667bb7b8accfae464560f8da99043dead8202e69aba8f2 +3104400 00215614a95083aaf58e024f994f772c1a58151e7a8692d521a0e29df9701d84 +3104800 0025b9017ad682750ee252e88681ffc997955e5e4fa5c3c3e343f39f35553478 +3105200 0035d201930fb8d0e727285931ccba51b7a4c2fdeeab87bf8c4b4879502615f6 +3105600 0013d51e2ddad3d77e66a7261b9256eb78c222e16895bdde659afb216be5eb15 +3106000 003030ab6fde397cf766dc792b64c60237014f3f7915b34a9b480ad145f0f9f6 +3106400 0015945b97fa213c6be7f08f13b7947ef41938e01e0ab3970f0211a1dd420dd7 +3106800 00062e739908037556d312a62005519def252e48e1ccf04bfd55930d17609a25 +3107200 0088f5a5d6512ff4c3d21255a00fd448b52005ca39e5dc44ad185f0d3d1accdd +3107600 00245f610290c4c065920c7a87c39432d490994d3280ea615df99e4313c8d249 +3108000 001d819512ab45b4df52be18041dff056308c8a4f81bf3e30010049feb4d0e2d +3108400 00187f70dd70251e5dcf66e8559d8328e14d74a897864562f463b97bf706e063 +3108800 004ee960bf71f8c884276934caf48b2a3607e0e6f1b0a8695e484e58c1129129 +3109200 000776e0a10b43cea2bc26b8cacb90e44f35dc183f424e3cd06005e70b7fff75 +3109600 0029859b237c55c3a51ffeaf8c35a0deac0557cf56875b3169c7b67414d3eb2b +3110000 001875fb89d1618d412c27476047f4d816a71c30b1f83762bfce00294f7d5742 +3110400 0035399f4116aeee33a271d19b3b0a66c0cec52751061c35cf5d2bc4d919b4a6 +3110800 000ee2a30af50d97313eee197146d2941e4ae2116c4b9e99fe3717d30f0d65ab +3111200 001417ee81ea8400cb690bf5acd733f2a58e36717049f434f45e951e4017c820 +3111600 006ca48f7de3904774c73caf6cf239245a751dc0e4715946fb2439ee9838e2a6 +3112000 00174416297cf8b3ad5ab504bb06338815e9d814fe7bd8164c40005efafab4b1 +3112400 0011545737542de3cf288e07724ba8c8f3b43b0cdf1820bd3056f2e41be77e7d +3112800 0005e09e8d5800fd390619bd8c02599ea5273945f8b574b81a2e299e25bd4760 +3113200 001490d3b27ad73df18c8c0988743360799e0186414ee905de9b565112c843f3 +3113600 0020e6d001c5a143b75e728a77ac192224aed587b6986bfa3ec3a118b32faa25 +3114000 0000e4217cdd650fce03725c64ec76fba633ac45b66ef651d1357927ef5bdc81 +3114400 0089707b70b58f2db28a000c346e66a7367a9b76cac122dfb469e1c6d52cf48a diff --git a/zebra-consensus/src/error.rs b/zebra-consensus/src/error.rs index 8fe14c62d52..ac7e339eb55 100644 --- a/zebra-consensus/src/error.rs +++ b/zebra-consensus/src/error.rs @@ -121,7 +121,7 @@ pub enum TransactionError { transaction_hash: zebra_chain::transaction::Hash, }, - #[error("coinbase transaction failed subsidy validation")] + #[error("coinbase transaction failed subsidy validation: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Subsidy(#[from] SubsidyError), @@ -140,7 +140,7 @@ pub enum TransactionError { #[error("if there are no Spends or Outputs, the value balance MUST be 0.")] BadBalance, - #[error("could not verify a transparent script")] + #[error("could not verify a transparent script: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Script(#[from] zebra_script::Error), @@ -149,29 +149,29 @@ pub enum TransactionError { // TODO: the underlying error is bellman::VerificationError, but it does not implement // Arbitrary as required here. - #[error("spend proof MUST be valid given a primary input formed from the other fields except spendAuthSig")] + #[error("spend proof MUST be valid given a primary input formed from the other fields except spendAuthSig: {0}")] Groth16(String), // TODO: the underlying error is io::Error, but it does not implement Clone as required here. - #[error("Groth16 proof is malformed")] + #[error("Groth16 proof is malformed: {0}")] MalformedGroth16(String), #[error( - "Sprout joinSplitSig MUST represent a valid signature under joinSplitPubKey of dataToBeSigned" + "Sprout joinSplitSig MUST represent a valid signature under joinSplitPubKey of dataToBeSigned: {0}" )] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Ed25519(#[from] zebra_chain::primitives::ed25519::Error), - #[error("Sapling bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash")] + #[error("Sapling bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] RedJubjub(zebra_chain::primitives::redjubjub::Error), - #[error("Orchard bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash")] + #[error("Orchard bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] RedPallas(zebra_chain::primitives::reddsa::Error), // temporary error type until #1186 is fixed - #[error("Downcast from BoxError to redjubjub::Error failed")] + #[error("Downcast from BoxError to redjubjub::Error failed: {0}")] InternalDowncastError(String), #[error("either vpub_old or vpub_new must be zero")] @@ -201,12 +201,12 @@ pub enum TransactionError { #[error("could not find a mempool transaction input UTXO in the best chain")] TransparentInputNotFound, - #[error("could not validate nullifiers and anchors on best chain")] + #[error("could not validate nullifiers and anchors on best chain: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] // This error variant is at least 128 bytes ValidateContextError(Box), - #[error("could not validate mempool transaction lock time on best chain")] + #[error("could not validate mempool transaction lock time on best chain: {0}")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] // TODO: turn this into a typed error ValidateMempoolLockTimeError(String), @@ -236,9 +236,17 @@ pub enum TransactionError { min_spend_height: block::Height, }, - #[error("failed to verify ZIP-317 transaction rules, transaction was not inserted to mempool")] + #[error( + "failed to verify ZIP-317 transaction rules, transaction was not inserted to mempool: {0}" + )] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Zip317(#[from] zebra_chain::transaction::zip317::Error), + + #[error("transaction uses an incorrect consensus branch id")] + WrongConsensusBranchId, + + #[error("wrong tx format: tx version is โ‰ฅ 5, but `nConsensusBranchId` is missing")] + MissingConsensusBranchId, } impl From for TransactionError { diff --git a/zebra-consensus/src/transaction.rs b/zebra-consensus/src/transaction.rs index 02f97fb7778..c3ccb78452c 100644 --- a/zebra-consensus/src/transaction.rs +++ b/zebra-consensus/src/transaction.rs @@ -415,6 +415,7 @@ where // Do quick checks first check::has_inputs_and_outputs(&tx)?; check::has_enough_orchard_flags(&tx)?; + check::consensus_branch_id(&tx, req.height(), &network)?; // Validate the coinbase input consensus rules if req.is_mempool() && tx.is_coinbase() { @@ -584,17 +585,17 @@ where )?; if let Some(mut mempool) = mempool { - if !transaction.transaction.transaction.outputs().is_empty() { - tokio::spawn(async move { - tokio::time::sleep(POLL_MEMPOOL_DELAY).await; - let _ = mempool - .ready() - .await - .expect("mempool poll_ready() method should not return an error") - .call(mempool::Request::CheckForVerifiedTransactions) - .await; - }); - } + tokio::spawn(async move { + // Best-effort poll of the mempool to provide a timely response to + // `sendrawtransaction` RPC calls or `AwaitOutput` mempool calls. + tokio::time::sleep(POLL_MEMPOOL_DELAY).await; + let _ = mempool + .ready() + .await + .expect("mempool poll_ready() method should not return an error") + .call(mempool::Request::CheckForVerifiedTransactions) + .await; + }); } Response::Mempool { transaction, spent_mempool_outpoints } diff --git a/zebra-consensus/src/transaction/check.rs b/zebra-consensus/src/transaction/check.rs index 66e3d0be595..d3ddc460264 100644 --- a/zebra-consensus/src/transaction/check.rs +++ b/zebra-consensus/src/transaction/check.rs @@ -495,3 +495,44 @@ pub fn tx_transparent_coinbase_spends_maturity( Ok(()) } + +/// Checks the `nConsensusBranchId` field. +/// +/// # Consensus +/// +/// ## [7.1.2 Transaction Consensus Rules] +/// +/// > [**NU5** onward] If `effectiveVersion` โ‰ฅ 5, the `nConsensusBranchId` field **MUST** match the +/// > consensus branch ID used for SIGHASH transaction hashes, as specified in [ZIP-244]. +/// +/// ### Notes +/// +/// - When deserializing transactions, Zebra converts the `nConsensusBranchId` into +/// [`NetworkUpgrade`]. +/// +/// - The values returned by [`Transaction::version`] match `effectiveVersion` so we use them in +/// place of `effectiveVersion`. More details in [`Transaction::version`]. +/// +/// [ZIP-244]: +/// [7.1.2 Transaction Consensus Rules]: +pub fn consensus_branch_id( + tx: &Transaction, + height: Height, + network: &Network, +) -> Result<(), TransactionError> { + let current_nu = NetworkUpgrade::current(network, height); + + if current_nu < NetworkUpgrade::Nu5 || tx.version() < 5 { + return Ok(()); + } + + let Some(tx_nu) = tx.network_upgrade() else { + return Err(TransactionError::MissingConsensusBranchId); + }; + + if tx_nu != current_nu { + return Err(TransactionError::WrongConsensusBranchId); + } + + Ok(()) +} diff --git a/zebra-consensus/src/transaction/tests.rs b/zebra-consensus/src/transaction/tests.rs index 56e27c259f8..63035ca5845 100644 --- a/zebra-consensus/src/transaction/tests.rs +++ b/zebra-consensus/src/transaction/tests.rs @@ -9,6 +9,7 @@ use std::{ use chrono::{DateTime, TimeZone, Utc}; use color_eyre::eyre::Report; +use futures::{FutureExt, TryFutureExt}; use halo2::pasta::{group::ff::PrimeField, pallas}; use tower::{buffer::Buffer, service_fn, ServiceExt}; @@ -1174,60 +1175,49 @@ async fn v5_transaction_is_rejected_before_nu5_activation() { } #[test] -fn v5_transaction_is_accepted_after_nu5_activation_mainnet() { - v5_transaction_is_accepted_after_nu5_activation_for_network(Network::Mainnet) -} - -#[test] -fn v5_transaction_is_accepted_after_nu5_activation_testnet() { - v5_transaction_is_accepted_after_nu5_activation_for_network(Network::new_default_testnet()) -} - -fn v5_transaction_is_accepted_after_nu5_activation_for_network(network: Network) { +fn v5_transaction_is_accepted_after_nu5_activation() { let _init_guard = zebra_test::init(); - zebra_test::MULTI_THREADED_RUNTIME.block_on(async { - let nu5 = NetworkUpgrade::Nu5; - let nu5_activation_height = nu5 - .activation_height(&network) - .expect("NU5 activation height is specified"); - let blocks = network.block_iter(); - let state_service = service_fn(|_| async { unreachable!("Service should not be called") }); - let verifier = Verifier::new_for_tests(&network, state_service); + for network in Network::iter() { + zebra_test::MULTI_THREADED_RUNTIME.block_on(async { + let nu5_activation_height = NetworkUpgrade::Nu5 + .activation_height(&network) + .expect("NU5 activation height is specified"); - let mut transaction = fake_v5_transactions_for_network(&network, blocks) - .next_back() - .expect("At least one fake V5 transaction in the test vectors"); - if transaction - .expiry_height() - .expect("V5 must have expiry_height") - < nu5_activation_height - { - let expiry_height = transaction.expiry_height_mut(); - *expiry_height = nu5_activation_height; - } + let state = service_fn(|_| async { unreachable!("Service should not be called") }); - let expected_hash = transaction.unmined_id(); - let expiry_height = transaction - .expiry_height() - .expect("V5 must have expiry_height"); + let mut tx = fake_v5_transactions_for_network(&network, network.block_iter()) + .next_back() + .expect("At least one fake V5 transaction in the test vectors"); - let result = verifier - .oneshot(Request::Block { - transaction_hash: transaction.hash(), - transaction: Arc::new(transaction), - known_utxos: Arc::new(HashMap::new()), - known_outpoint_hashes: Arc::new(HashSet::new()), - height: expiry_height, - time: DateTime::::MAX_UTC, - }) - .await; + if tx.expiry_height().expect("V5 must have expiry_height") < nu5_activation_height { + *tx.expiry_height_mut() = nu5_activation_height; + tx.update_network_upgrade(NetworkUpgrade::Nu5) + .expect("updating the network upgrade for a V5 tx should succeed"); + } - assert_eq!( - result.expect("unexpected error response").tx_id(), - expected_hash - ); - }) + let expected_hash = tx.unmined_id(); + let expiry_height = tx.expiry_height().expect("V5 must have expiry_height"); + + let verification_result = Verifier::new_for_tests(&network, state) + .oneshot(Request::Block { + transaction_hash: tx.hash(), + transaction: Arc::new(tx), + known_utxos: Arc::new(HashMap::new()), + known_outpoint_hashes: Arc::new(HashSet::new()), + height: expiry_height, + time: DateTime::::MAX_UTC, + }) + .await; + + assert_eq!( + verification_result + .expect("successful verification") + .tx_id(), + expected_hash + ); + }); + } } /// Test if V4 transaction with transparent funds is accepted. @@ -2078,7 +2068,13 @@ async fn v5_coinbase_transaction_expiry_height() { *new_transaction.expiry_height_mut() = new_expiry_height; - let result = verifier + // Setting the new expiry height as the block height will activate NU6, so we need to set NU6 + // for the tx as well. + new_transaction + .update_network_upgrade(NetworkUpgrade::Nu6) + .expect("updating the network upgrade for a V5 tx should succeed"); + + let verification_result = verifier .clone() .oneshot(Request::Block { transaction_hash: transaction.hash(), @@ -2091,7 +2087,9 @@ async fn v5_coinbase_transaction_expiry_height() { .await; assert_eq!( - result.expect("unexpected error response").tx_id(), + verification_result + .expect("successful verification") + .tx_id(), new_transaction.unmined_id() ); } @@ -2151,22 +2149,18 @@ async fn v5_transaction_with_too_low_expiry_height() { ); } -/// Tests if a non-coinbase V5 transaction with an expiry height exceeding the -/// maximum is rejected. +/// Tests if a non-coinbase V5 transaction with an expiry height exceeding the maximum is rejected. #[tokio::test] async fn v5_transaction_with_exceeding_expiry_height() { - let state_service = - service_fn(|_| async { unreachable!("State service should not be called") }); - let verifier = Verifier::new_for_tests(&Network::Mainnet, state_service); + let state = service_fn(|_| async { unreachable!("State service should not be called") }); - let block_height = block::Height::MAX; + let height_max = block::Height::MAX; - let fund_height = (block_height - 1).expect("fake source fund block height is too small"); let (input, output, known_utxos) = mock_transparent_transfer( - fund_height, + height_max.previous().expect("valid height"), true, 0, - Amount::try_from(1).expect("invalid value"), + Amount::try_from(1).expect("valid amount"), ); // This expiry height exceeds the maximum defined by the specification. @@ -2180,27 +2174,29 @@ async fn v5_transaction_with_exceeding_expiry_height() { expiry_height, sapling_shielded_data: None, orchard_shielded_data: None, - network_upgrade: NetworkUpgrade::Nu5, + network_upgrade: NetworkUpgrade::Nu6, }; - let result = verifier + let transaction_hash = transaction.hash(); + + let verification_result = Verifier::new_for_tests(&Network::Mainnet, state) .oneshot(Request::Block { transaction_hash: transaction.hash(), transaction: Arc::new(transaction.clone()), known_utxos: Arc::new(known_utxos), known_outpoint_hashes: Arc::new(HashSet::new()), - height: block_height, + height: height_max, time: DateTime::::MAX_UTC, }) .await; assert_eq!( - result, + verification_result, Err(TransactionError::MaximumExpiryHeight { expiry_height, is_coinbase: false, - block_height, - transaction_hash: transaction.hash(), + block_height: height_max, + transaction_hash, }) ); } @@ -2321,61 +2317,51 @@ async fn v5_transaction_with_transparent_transfer_is_rejected_by_the_script() { /// Test if V5 transaction with an internal double spend of transparent funds is rejected. #[tokio::test] async fn v5_transaction_with_conflicting_transparent_spend_is_rejected() { - let network = Network::Mainnet; - let network_upgrade = NetworkUpgrade::Nu5; - - let canopy_activation_height = NetworkUpgrade::Canopy - .activation_height(&network) - .expect("Canopy activation height is specified"); - - let transaction_block_height = - (canopy_activation_height + 10).expect("transaction block height is too large"); - - let fake_source_fund_height = - (transaction_block_height - 1).expect("fake source fund block height is too small"); + for network in Network::iter() { + let canopy_activation_height = NetworkUpgrade::Canopy + .activation_height(&network) + .expect("Canopy activation height is specified"); - // Create a fake transparent transfer that should succeed - let (input, output, known_utxos) = mock_transparent_transfer( - fake_source_fund_height, - true, - 0, - Amount::try_from(1).expect("invalid value"), - ); + let height = (canopy_activation_height + 10).expect("valid height"); - // Create a V4 transaction - let transaction = Transaction::V5 { - inputs: vec![input.clone(), input.clone()], - outputs: vec![output], - lock_time: LockTime::Height(block::Height(0)), - expiry_height: (transaction_block_height + 1).expect("expiry height is too large"), - sapling_shielded_data: None, - orchard_shielded_data: None, - network_upgrade, - }; + // Create a fake transparent transfer that should succeed + let (input, output, known_utxos) = mock_transparent_transfer( + height.previous().expect("valid height"), + true, + 0, + Amount::try_from(1).expect("valid amount"), + ); - let state_service = - service_fn(|_| async { unreachable!("State service should not be called") }); - let verifier = Verifier::new_for_tests(&network, state_service); + let transaction = Transaction::V5 { + inputs: vec![input.clone(), input.clone()], + outputs: vec![output], + lock_time: LockTime::Height(block::Height(0)), + expiry_height: height.next().expect("valid height"), + sapling_shielded_data: None, + orchard_shielded_data: None, + network_upgrade: NetworkUpgrade::Canopy, + }; - let result = verifier - .oneshot(Request::Block { - transaction_hash: transaction.hash(), - transaction: Arc::new(transaction), - known_utxos: Arc::new(known_utxos), - known_outpoint_hashes: Arc::new(HashSet::new()), - height: transaction_block_height, - time: DateTime::::MAX_UTC, - }) - .await; + let state = service_fn(|_| async { unreachable!("State service should not be called") }); - let expected_outpoint = input.outpoint().expect("Input should have an outpoint"); + let verification_result = Verifier::new_for_tests(&network, state) + .oneshot(Request::Block { + transaction_hash: transaction.hash(), + transaction: Arc::new(transaction), + known_utxos: Arc::new(known_utxos), + known_outpoint_hashes: Arc::new(HashSet::new()), + height, + time: DateTime::::MAX_UTC, + }) + .await; - assert_eq!( - result, - Err(TransactionError::DuplicateTransparentSpend( - expected_outpoint - )) - ); + assert_eq!( + verification_result, + Err(TransactionError::DuplicateTransparentSpend( + input.outpoint().expect("Input should have an outpoint") + )) + ); + } } /// Test if signed V4 transaction with a dummy [`sprout::JoinSplit`] is accepted. @@ -2811,6 +2797,167 @@ fn v5_with_duplicate_orchard_action() { }); } +/// Checks that the tx verifier handles consensus branch ids in V5 txs correctly. +#[tokio::test] +async fn v5_consensus_branch_ids() { + let mut state = MockService::build().for_unit_tests(); + + let (input, output, known_utxos) = mock_transparent_transfer( + Height(1), + true, + 0, + Amount::try_from(10001).expect("valid amount"), + ); + + let known_utxos = Arc::new(known_utxos); + + // NU5 is the first network upgrade that supports V5 txs. + let mut network_upgrade = NetworkUpgrade::Nu5; + + let mut tx = Transaction::V5 { + inputs: vec![input], + outputs: vec![output], + lock_time: LockTime::unlocked(), + expiry_height: Height::MAX_EXPIRY_HEIGHT, + sapling_shielded_data: None, + orchard_shielded_data: None, + network_upgrade, + }; + + let outpoint = match tx.inputs()[0] { + transparent::Input::PrevOut { outpoint, .. } => outpoint, + transparent::Input::Coinbase { .. } => panic!("requires a non-coinbase transaction"), + }; + + for network in Network::iter() { + let verifier = Buffer::new(Verifier::new_for_tests(&network, state.clone()), 10); + + while let Some(next_nu) = network_upgrade.next_upgrade() { + // Check an outdated network upgrade. + let height = next_nu.activation_height(&network).expect("height"); + + let block_req = verifier + .clone() + .oneshot(Request::Block { + transaction_hash: tx.hash(), + transaction: Arc::new(tx.clone()), + known_utxos: known_utxos.clone(), + known_outpoint_hashes: Arc::new(HashSet::new()), + // The consensus branch ID of the tx is outdated for this height. + height, + time: DateTime::::MAX_UTC, + }) + .map_err(|err| *err.downcast().expect("`TransactionError` type")); + + let mempool_req = verifier + .clone() + .oneshot(Request::Mempool { + transaction: tx.clone().into(), + // The consensus branch ID of the tx is outdated for this height. + height, + }) + .map_err(|err| *err.downcast().expect("`TransactionError` type")); + + let (block_rsp, mempool_rsp) = futures::join!(block_req, mempool_req); + + assert_eq!(block_rsp, Err(TransactionError::WrongConsensusBranchId)); + assert_eq!(mempool_rsp, Err(TransactionError::WrongConsensusBranchId)); + + // Check the currently supported network upgrade. + let height = network_upgrade.activation_height(&network).expect("height"); + + let block_req = verifier + .clone() + .oneshot(Request::Block { + transaction_hash: tx.hash(), + transaction: Arc::new(tx.clone()), + known_utxos: known_utxos.clone(), + known_outpoint_hashes: Arc::new(HashSet::new()), + // The consensus branch ID of the tx is supported by this height. + height, + time: DateTime::::MAX_UTC, + }) + .map_ok(|rsp| rsp.tx_id()) + .map_err(|e| format!("{e}")); + + let mempool_req = verifier + .clone() + .oneshot(Request::Mempool { + transaction: tx.clone().into(), + // The consensus branch ID of the tx is supported by this height. + height, + }) + .map_ok(|rsp| rsp.tx_id()) + .map_err(|e| format!("{e}")); + + let state_req = async { + state + .expect_request(zebra_state::Request::UnspentBestChainUtxo(outpoint)) + .map(|r| { + r.respond(zebra_state::Response::UnspentBestChainUtxo( + known_utxos.get(&outpoint).map(|utxo| utxo.utxo.clone()), + )) + }) + .await; + + state + .expect_request_that(|req| { + matches!( + req, + zebra_state::Request::CheckBestChainTipNullifiersAndAnchors(_) + ) + }) + .map(|r| { + r.respond(zebra_state::Response::ValidBestChainTipNullifiersAndAnchors) + }) + .await; + }; + + let (block_rsp, mempool_rsp, _) = futures::join!(block_req, mempool_req, state_req); + let txid = tx.unmined_id(); + + assert_eq!(block_rsp, Ok(txid)); + assert_eq!(mempool_rsp, Ok(txid)); + + // Check a network upgrade that Zebra doesn't support yet. + tx.update_network_upgrade(next_nu) + .expect("V5 txs support updating NUs"); + + let height = network_upgrade.activation_height(&network).expect("height"); + + let block_req = verifier + .clone() + .oneshot(Request::Block { + transaction_hash: tx.hash(), + transaction: Arc::new(tx.clone()), + known_utxos: known_utxos.clone(), + known_outpoint_hashes: Arc::new(HashSet::new()), + // The consensus branch ID of the tx is not supported by this height. + height, + time: DateTime::::MAX_UTC, + }) + .map_err(|err| *err.downcast().expect("`TransactionError` type")); + + let mempool_req = verifier + .clone() + .oneshot(Request::Mempool { + transaction: tx.clone().into(), + // The consensus branch ID of the tx is not supported by this height. + height, + }) + .map_err(|err| *err.downcast().expect("`TransactionError` type")); + + let (block_rsp, mempool_rsp) = futures::join!(block_req, mempool_req); + + assert_eq!(block_rsp, Err(TransactionError::WrongConsensusBranchId)); + assert_eq!(mempool_rsp, Err(TransactionError::WrongConsensusBranchId)); + + // Shift the network upgrade for the next loop iteration. + network_upgrade = next_nu; + } + } +} + // Utility functions /// Create a mock transparent transfer to be included in a transaction. diff --git a/zebra-grpc/Cargo.toml b/zebra-grpc/Cargo.toml index 4f825686d52..cf01365553f 100644 --- a/zebra-grpc/Cargo.toml +++ b/zebra-grpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-grpc" -version = "0.1.0-alpha.9" +version = "0.1.0-alpha.10" authors = ["Zcash Foundation "] description = "Zebra gRPC interface" license = "MIT OR Apache-2.0" @@ -19,23 +19,23 @@ categories = ["cryptography::cryptocurrencies"] futures-util = "0.3.28" tonic = "0.12.3" tonic-reflection = "0.12.3" -prost = "0.13.3" -serde = { version = "1.0.211", features = ["serde_derive"] } -tokio = { version = "1.41.0", features = ["macros", "rt-multi-thread"] } -tokio-stream = "0.1.16" +prost = "0.13.4" +serde = { version = "1.0.215", features = ["serde_derive"] } +tokio = { version = "1.42.0", features = ["macros", "rt-multi-thread"] } +tokio-stream = "0.1.17" tower = { version = "0.4.13", features = ["util", "buffer", "timeout"] } color-eyre = "0.6.3" zcash_primitives.workspace = true -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.42", features = ["shielded-scan"] } -zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.42" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.43", features = ["shielded-scan"] } +zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.43" } [build-dependencies] tonic-build = "0.12.3" [dev-dependencies] -insta = { version = "1.40.0", features = ["redactions", "json", "ron"] } +insta = { version = "1.41.1", features = ["redactions", "json", "ron"] } zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] } zebra-state = { path = "../zebra-state" } diff --git a/zebra-network/Cargo.toml b/zebra-network/Cargo.toml index e4967cc66f2..86d373fa8d9 100644 --- a/zebra-network/Cargo.toml +++ b/zebra-network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-network" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation ", "Tower Maintainers "] description = "Networking code for Zebra" # # Legal @@ -42,12 +42,12 @@ proptest-impl = ["proptest", "proptest-derive", "zebra-chain/proptest-impl"] [dependencies] bitflags = "2.5.0" byteorder = "1.5.0" -bytes = "1.8.0" -chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } +bytes = "1.9.0" +chrono = { version = "0.4.39", default-features = false, features = ["clock", "std"] } dirs = "5.0.1" hex = "0.4.3" humantime-serde = "1.1.1" -indexmap = { version = "2.6.0", features = ["serde"] } +indexmap = { version = "2.7.0", features = ["serde"] } itertools = "0.13.0" lazy_static = "1.4.0" num-integer = "0.1.46" @@ -56,20 +56,20 @@ pin-project = "1.1.6" rand = "0.8.5" rayon = "1.10.0" regex = "1.11.0" -serde = { version = "1.0.211", features = ["serde_derive"] } -tempfile = "3.13.0" -thiserror = "1.0.64" +serde = { version = "1.0.215", features = ["serde_derive"] } +tempfile = "3.14.0" +thiserror = "2.0.6" futures = "0.3.31" -tokio = { version = "1.41.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"] } +tokio = { version = "1.42.0", features = ["fs", "io-util", "net", "time", "tracing", "macros", "rt-multi-thread"] } +tokio-stream = { version = "0.1.17", features = ["sync", "time"] } +tokio-util = { version = "0.7.13", features = ["codec"] } tower = { version = "0.4.13", features = ["retry", "discover", "load", "load-shed", "timeout", "util", "buffer"] } -metrics = "0.24.0" +metrics = "0.24.1" tracing-futures = "0.2.5" -tracing-error = { version = "0.2.0", features = ["traced-error"] } -tracing = "0.1.39" +tracing-error = { version = "0.2.1", features = ["traced-error"] } +tracing = "0.1.41" # prod feature progress-bar howudoin = { version = "0.1.2", optional = true } @@ -83,14 +83,14 @@ 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.42", features = ["async-error"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = ["async-error"] } [dev-dependencies] proptest = "1.4.0" proptest-derive = "0.5.0" static_assertions = "1.1.0" -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } toml = "0.8.19" zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] } diff --git a/zebra-network/src/peer/error.rs b/zebra-network/src/peer/error.rs index c40c34b1d1d..d85e0e143ba 100644 --- a/zebra-network/src/peer/error.rs +++ b/zebra-network/src/peer/error.rs @@ -251,10 +251,10 @@ pub enum HandshakeError { #[error("Peer closed connection")] ConnectionClosed, /// An error occurred while performing an IO operation. - #[error("Underlying IO error")] + #[error("Underlying IO error: {0}")] Io(#[from] std::io::Error), /// A serialization error occurred while reading or writing a message. - #[error("Serialization error")] + #[error("Serialization error: {0}")] Serialization(#[from] SerializationError), /// The remote peer offered a version older than our minimum version. #[error("Peer offered obsolete version: {0:?}")] diff --git a/zebra-node-services/Cargo.toml b/zebra-node-services/Cargo.toml index cba315f1efa..d9fcbba5bdd 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.42" +version = "1.0.0-beta.43" 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.42" } +zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.43" } # Optional dependencies @@ -45,15 +45,15 @@ zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.42" } 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.211", optional = true } -serde_json = { version = "1.0.132", optional = true } -tokio = { version = "1.41.0", features = ["time", "sync"] } +reqwest = { version = "0.12.9", default-features = false, features = ["rustls-tls"], optional = true } +serde = { version = "1.0.215", optional = true } +serde_json = { version = "1.0.133", optional = true } +tokio = { version = "1.42.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.211" -serde_json = "1.0.132" +reqwest = { version = "0.12.9", default-features = false, features = ["rustls-tls"] } +serde = "1.0.215" +serde_json = "1.0.133" diff --git a/zebra-node-services/src/mempool.rs b/zebra-node-services/src/mempool.rs index 784c3ba607e..6c035e6dc44 100644 --- a/zebra-node-services/src/mempool.rs +++ b/zebra-node-services/src/mempool.rs @@ -13,12 +13,9 @@ use zebra_chain::{ use crate::BoxError; mod gossip; - mod transaction_dependencies; -pub use transaction_dependencies::TransactionDependencies; - -pub use self::gossip::Gossip; +pub use self::{gossip::Gossip, transaction_dependencies::TransactionDependencies}; /// A mempool service request. /// diff --git a/zebra-rpc/Cargo.toml b/zebra-rpc/Cargo.toml index 85be248bc76..56b7f3c60f0 100644 --- a/zebra-rpc/Cargo.toml +++ b/zebra-rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-rpc" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation "] description = "A Zebra JSON Remote Procedure Call (JSON-RPC) interface" license = "MIT OR Apache-2.0" @@ -53,7 +53,7 @@ proptest-impl = [ ] [dependencies] -chrono = { version = "0.4.38", default-features = false, features = [ +chrono = { version = "0.4.39", default-features = false, features = [ "clock", "std", ] } @@ -64,8 +64,8 @@ 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.132", features = ["preserve_order"] } -indexmap = { version = "2.6.0", features = ["serde"] } +serde_json = { version = "1.0.133", features = ["preserve_order"] } +indexmap = { version = "2.7.0", features = ["serde"] } # RPC endpoint basic auth base64 = "0.22.1" @@ -74,7 +74,7 @@ rand = "0.8.5" # Error handling color-eyre = "0.6.3" -tokio = { version = "1.41.0", features = [ +tokio = { version = "1.42.0", features = [ "time", "rt-multi-thread", "macros", @@ -85,13 +85,13 @@ tower = "0.4.13" # indexer-rpcs dependencies 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 } +prost = { version = "0.13.4", optional = true } +tokio-stream = { version = "0.1.17", optional = true } -tracing = "0.1.39" +tracing = "0.1.41" hex = { version = "0.4.3", features = ["serde"] } -serde = { version = "1.0.211", features = ["serde_derive"] } +serde = { version = "1.0.215", features = ["serde_derive"] } # For the `stop` RPC method. nix = { version = "0.29.0", features = ["signal"] } @@ -104,39 +104,39 @@ 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.42", features = [ +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = [ "json-conversion", ] } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.42" } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.42" } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.42", features = [ +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.43" } +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.43" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.43", features = [ "rpc-client", ] } -zebra-script = { path = "../zebra-script", version = "1.0.0-beta.42" } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42" } +zebra-script = { path = "../zebra-script", version = "1.0.0-beta.43" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43" } [build-dependencies] tonic-build = { version = "0.12.3", optional = true } [dev-dependencies] -insta = { version = "1.40.0", features = ["redactions", "json", "ron"] } +insta = { version = "1.41.1", features = ["redactions", "json", "ron"] } proptest = "1.4.0" -thiserror = "1.0.64" -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } +thiserror = "2.0.6" +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42", features = [ +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = [ "proptest-impl", ] } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.42", features = [ +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.43", features = [ "proptest-impl", ] } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.42", features = [ +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.43", features = [ "proptest-impl", ] } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42", features = [ +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43", features = [ "proptest-impl", ] } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.42" } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.43" } diff --git a/zebra-scan/Cargo.toml b/zebra-scan/Cargo.toml index c939700727e..17bd29baed7 100644 --- a/zebra-scan/Cargo.toml +++ b/zebra-scan/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-scan" -version = "0.1.0-alpha.11" +version = "0.1.0-alpha.12" authors = ["Zcash Foundation "] description = "Shielded transaction scanner for the Zcash blockchain" license = "MIT OR Apache-2.0" @@ -61,13 +61,13 @@ results-reader = [ [dependencies] color-eyre = "0.6.3" -indexmap = { version = "2.6.0", features = ["serde"] } +indexmap = { version = "2.7.0", features = ["serde"] } itertools = "0.13.0" semver = "1.0.23" -serde = { version = "1.0.211", features = ["serde_derive"] } -tokio = { version = "1.41.0", features = ["time"] } +serde = { version = "1.0.215", features = ["serde_derive"] } +tokio = { version = "1.42.0", features = ["time"] } tower = "0.4.13" -tracing = "0.1.39" +tracing = "0.1.41" futures = "0.3.31" # ECC dependencies. @@ -77,13 +77,13 @@ zcash_primitives.workspace = true zcash_address.workspace = true sapling-crypto.workspace = true -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42", features = ["shielded-scan"] } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42", features = ["shielded-scan"] } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.42", features = ["shielded-scan"] } -zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.9" } -zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.42" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = ["shielded-scan"] } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43", features = ["shielded-scan"] } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.43", features = ["shielded-scan"] } +zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.10" } +zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.43" } -chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] } +chrono = { version = "0.4.39", default-features = false, features = ["clock", "std", "serde"] } # test feature proptest-impl proptest = { version = "1.4.0", optional = true } @@ -96,22 +96,22 @@ 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.42", optional = true } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.43", optional = true } # zebra-scanner binary dependencies -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } structopt = "0.3.26" lazy_static = "1.4.0" -serde_json = "1.0.132" +serde_json = "1.0.133" jsonrpc = { version = "0.18.0", optional = true } hex = { version = "0.4.3", optional = true } -zebrad = { path = "../zebrad", version = "2.0.1" } +zebrad = { path = "../zebrad", version = "2.1.0" } [dev-dependencies] -insta = { version = "1.40.0", features = ["ron", "redactions"] } -tokio = { version = "1.41.0", features = ["test-util"] } +insta = { version = "1.41.1", features = ["ron", "redactions"] } +tokio = { version = "1.42.0", features = ["test-util"] } proptest = "1.4.0" proptest-derive = "0.5.0" @@ -120,11 +120,11 @@ ff = "0.13.0" group = "0.13.0" jubjub = "0.10.0" rand = "0.8.5" -tempfile = "3.13.0" +tempfile = "3.14.0" zcash_note_encryption = "0.4.0" toml = "0.8.19" tonic = "0.12.3" -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.42" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.43" } diff --git a/zebra-script/Cargo.toml b/zebra-script/Cargo.toml index 1f3050ca53a..e0d3094ef98 100644 --- a/zebra-script/Cargo.toml +++ b/zebra-script/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-script" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" 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.42" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43" } -thiserror = "1.0.64" +thiserror = "2.0.6" [dev-dependencies] hex = "0.4.3" lazy_static = "1.4.0" -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.42" } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.43" } diff --git a/zebra-state/Cargo.toml b/zebra-state/Cargo.toml index 55f4f2e1556..8ca769f6910 100644 --- a/zebra-state/Cargo.toml +++ b/zebra-state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-state" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation "] description = "State contextual verification and storage code for Zebra" license = "MIT OR Apache-2.0" @@ -47,43 +47,43 @@ elasticsearch = [ [dependencies] bincode = "1.3.3" -chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } +chrono = { version = "0.4.39", default-features = false, features = ["clock", "std"] } dirs = "5.0.1" futures = "0.3.31" 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.6.0" +indexmap = "2.7.0" itertools = "0.13.0" lazy_static = "1.4.0" -metrics = "0.24.0" +metrics = "0.24.1" mset = "0.1.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.211", features = ["serde_derive"] } -tempfile = "3.13.0" -thiserror = "1.0.64" +serde = { version = "1.0.215", features = ["serde_derive"] } +tempfile = "3.14.0" +thiserror = "2.0.6" rayon = "1.10.0" -tokio = { version = "1.41.0", features = ["rt-multi-thread", "sync", "tracing"] } +tokio = { version = "1.42.0", features = ["rt-multi-thread", "sync", "tracing"] } tower = { version = "0.4.13", features = ["buffer", "util"] } -tracing = "0.1.39" +tracing = "0.1.41" # 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.132", package = "serde_json", optional = true } +elasticsearch = { version = "8.16.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true } +serde_json = { version = "1.0.133", package = "serde_json", optional = true } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42", features = ["async-error"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", 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.42", optional = true } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43", optional = true } proptest = { version = "1.4.0", optional = true } proptest-derive = { version = "0.5.0", optional = true } @@ -97,7 +97,7 @@ once_cell = "1.20.2" spandoc = "0.2.2" hex = { version = "0.4.3", features = ["serde"] } -insta = { version = "1.40.0", features = ["ron", "redactions"] } +insta = { version = "1.41.1", 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.41.0", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.42" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.43" } diff --git a/zebra-state/src/error.rs b/zebra-state/src/error.rs index cf495311efb..632591f4cb3 100644 --- a/zebra-state/src/error.rs +++ b/zebra-state/src/error.rs @@ -220,13 +220,13 @@ pub enum ValidateContextError { height: Option, }, - #[error("error updating a note commitment tree")] + #[error("error updating a note commitment tree: {0}")] NoteCommitmentTreeError(#[from] zebra_chain::parallel::tree::NoteCommitmentTreeError), - #[error("error building the history tree")] + #[error("error building the history tree: {0}")] HistoryTreeError(#[from] Arc), - #[error("block contains an invalid commitment")] + #[error("block contains an invalid commitment: {0}")] InvalidBlockCommitment(#[from] block::CommitmentError), #[error( diff --git a/zebra-test/Cargo.toml b/zebra-test/Cargo.toml index 86daa264305..db111c88f35 100644 --- a/zebra-test/Cargo.toml +++ b/zebra-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-test" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation "] description = "Test harnesses and test vectors for Zebra" license = "MIT OR Apache-2.0" @@ -16,16 +16,16 @@ categories = ["command-line-utilities", "cryptography::cryptocurrencies"] [dependencies] hex = "0.4.3" -indexmap = "2.6.0" +indexmap = "2.7.0" lazy_static = "1.4.0" -insta = "1.40.0" +insta = "1.41.1" itertools = "0.13.0" proptest = "1.4.0" once_cell = "1.20.2" rand = "0.8.5" regex = "1.11.0" -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } tower = { version = "0.4.13", features = ["util"] } futures = "0.3.31" @@ -37,11 +37,11 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } humantime = "2.1.0" owo-colors = "4.1.0" spandoc = "0.2.2" -thiserror = "1.0.64" +thiserror = "2.0.6" -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } -tracing-error = "0.2.0" -tracing = "0.1.39" +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } +tracing-error = "0.2.1" +tracing = "0.1.41" [dev-dependencies] -tempfile = "3.13.0" +tempfile = "3.14.0" diff --git a/zebra-utils/Cargo.toml b/zebra-utils/Cargo.toml index e8f81cb088e..2dc0a382a04 100644 --- a/zebra-utils/Cargo.toml +++ b/zebra-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zebra-utils" -version = "1.0.0-beta.42" +version = "1.0.0-beta.43" authors = ["Zcash Foundation "] description = "Developer tools for Zebra maintenance and testing" license = "MIT OR Apache-2.0" @@ -89,16 +89,16 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] } structopt = "0.3.26" hex = "0.4.3" -serde_json = "1.0.132" -tracing-error = "0.2.0" -tracing-subscriber = "0.3.18" -thiserror = "1.0.64" +serde_json = "1.0.133" +tracing-error = "0.2.1" +tracing-subscriber = "0.3.19" +thiserror = "2.0.6" -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.42" } -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.43" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43" } # These crates are needed for the block-template-to-proposal binary -zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.42", optional = true } +zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.43", optional = true } # These crates are needed for the zebra-checkpoints binary itertools = { version = "0.13.0", optional = true } @@ -106,10 +106,10 @@ itertools = { version = "0.13.0", optional = true } # These crates are needed for the search-issue-refs binary 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 } +reqwest = { version = "0.12.9", default-features = false, features = ["rustls-tls"], optional = true } # These crates are needed for the zebra-checkpoints and search-issue-refs binaries -tokio = { version = "1.41.0", features = ["full"], optional = true } +tokio = { version = "1.42.0", features = ["full"], optional = true } jsonrpc = { version = "0.18.0", optional = true } @@ -122,6 +122,6 @@ rand = "0.8.5" 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.211", features = ["serde_derive"], optional = true } -indexmap = "2.6.0" +serde = { version = "1.0.215", features = ["serde_derive"], optional = true } +indexmap = "2.7.0" diff --git a/zebrad/Cargo.toml b/zebrad/Cargo.toml index 768f68dfcb3..cb3e417d0cf 100644 --- a/zebrad/Cargo.toml +++ b/zebrad/Cargo.toml @@ -1,7 +1,7 @@ [package] # Crate metadata name = "zebrad" -version = "2.0.1" +version = "2.1.0" authors = ["Zcash Foundation "] description = "The Zcash Foundation's independent, consensus-compatible implementation of a Zcash node" license = "MIT OR Apache-2.0" @@ -157,30 +157,30 @@ test_sync_past_mandatory_checkpoint_mainnet = [] test_sync_past_mandatory_checkpoint_testnet = [] [dependencies] -zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.42" } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.42" } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.42" } -zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.42", features = ["rpc-client"] } -zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.42" } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42" } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43" } +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.43" } +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.43" } +zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.43", features = ["rpc-client"] } +zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.43" } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43" } # Required for crates.io publishing, but it's only used in tests -zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.42", optional = true } +zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.43", optional = true } abscissa_core = "0.7.0" -clap = { version = "4.5.20", features = ["cargo"] } -chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] } +clap = { version = "4.5.23", features = ["cargo"] } +chrono = { version = "0.4.39", default-features = false, features = ["clock", "std"] } humantime-serde = "1.1.1" -indexmap = "2.6.0" +indexmap = "2.7.0" lazy_static = "1.4.0" semver = "1.0.23" -serde = { version = "1.0.211", features = ["serde_derive"] } +serde = { version = "1.0.215", features = ["serde_derive"] } toml = "0.8.19" futures = "0.3.31" rayon = "1.10.0" -tokio = { version = "1.41.0", features = ["time", "rt-multi-thread", "macros", "tracing", "signal"] } -tokio-stream = { version = "0.1.16", features = ["time"] } +tokio = { version = "1.42.0", features = ["time", "rt-multi-thread", "macros", "tracing", "signal"] } +tokio-stream = { version = "0.1.17", features = ["time"] } tower = { version = "0.4.13", features = ["hedge", "limit"] } pin-project = "1.1.6" @@ -189,15 +189,15 @@ 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.64" +thiserror = "2.0.6" -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } tracing-appender = "0.2.3" -tracing-error = "0.2.0" +tracing-error = "0.2.1" tracing-futures = "0.2.5" -tracing = "0.1.39" +tracing = "0.1.41" -metrics = "0.24.0" +metrics = "0.24.1" dirs = "5.0.1" atty = "0.2.14" @@ -206,23 +206,23 @@ num-integer = "0.1.46" rand = "0.8.5" # prod feature internal-miner -thread-priority = { version = "1.0.0", optional = true } +thread-priority = { version = "1.2.0", optional = true } # prod feature sentry -sentry = { version = "0.32.2", default-features = false, features = ["backtrace", "contexts", "reqwest", "rustls", "tracing"], optional = true } +sentry = { version = "0.35.0", default-features = false, features = ["backtrace", "contexts", "reqwest", "rustls", "tracing"], optional = true } # prod feature flamegraph tracing-flame = { version = "0.2.0", optional = true } -inferno = { version = "0.11.21", default-features = false, optional = true } +inferno = { version = "0.12.0", default-features = false, optional = true } # prod feature journald tracing-journald = { version = "0.3.0", optional = true } # prod feature filter-reload -hyper = { version = "1.5.0", features = ["http1", "http2", "server"], optional = true } +hyper = { version = "1.5.1", features = ["http1", "http2", "server"], optional = true } http-body-util = { version = "0.1.2", optional = true } hyper-util = { version = "0.1.9", optional = true } -bytes = { version = "1.8.0", optional = true } +bytes = { version = "1.9.0", optional = true } # prod feature prometheus metrics-exporter-prometheus = { version = "0.16.0", default-features = false, features = ["http-listener"], optional = true } @@ -235,7 +235,7 @@ log = "0.4.22" # prod feature progress-bar howudoin = { version = "0.1.2", features = ["term-line"], optional = true } -indicatif = { version = "0.17.8", optional = true } +indicatif = { version = "0.17.9", optional = true } # test feature proptest-impl proptest = { version = "1.4.0", optional = true } @@ -257,20 +257,20 @@ hex-literal = "0.4.1" jsonrpc-core = "18.0.0" once_cell = "1.20.2" regex = "1.11.0" -insta = { version = "1.40.0", features = ["json"] } +insta = { version = "1.41.1", features = ["json"] } # zebra-rpc needs the preserve_order feature, it also makes test results more stable -serde_json = { version = "1.0.132", features = ["preserve_order"] } -tempfile = "3.13.0" +serde_json = { version = "1.0.133", features = ["preserve_order"] } +tempfile = "3.14.0" -hyper = { version = "1.5.0", features = ["http1", "http2", "server"]} +hyper = { version = "1.5.1", features = ["http1", "http2", "server"]} tracing-test = { version = "0.2.4", features = ["no-env-filter"] } -tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] } -tokio-stream = "0.1.16" +tokio = { version = "1.42.0", features = ["full", "tracing", "test-util"] } +tokio-stream = "0.1.17" # test feature lightwalletd-grpc-tests -prost = "0.13.3" +prost = "0.13.4" tonic = "0.12.3" proptest = "1.4.0" @@ -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.42", features = ["proptest-impl"] } -zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.42", features = ["proptest-impl"] } -zebra-network = { path = "../zebra-network", version = "1.0.0-beta.42", features = ["proptest-impl"] } -zebra-state = { path = "../zebra-state", version = "1.0.0-beta.42", features = ["proptest-impl"] } +zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-network = { path = "../zebra-network", version = "1.0.0-beta.43", features = ["proptest-impl"] } +zebra-state = { path = "../zebra-state", version = "1.0.0-beta.43", features = ["proptest-impl"] } -zebra-test = { path = "../zebra-test", version = "1.0.0-beta.42" } -zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.9" } +zebra-test = { path = "../zebra-test", version = "1.0.0-beta.43" } +zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.10" } # 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.9" } # 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.42" } +zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.43" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] } diff --git a/zebrad/src/components/mempool.rs b/zebrad/src/components/mempool.rs index bc5796df615..0d76b778d87 100644 --- a/zebrad/src/components/mempool.rs +++ b/zebrad/src/components/mempool.rs @@ -28,7 +28,6 @@ use std::{ use futures::{future::FutureExt, stream::Stream}; use tokio::sync::{broadcast, oneshot}; -use tokio_stream::StreamExt; use tower::{buffer::Buffer, timeout::Timeout, util::BoxService, Service}; use zebra_chain::{ @@ -43,7 +42,7 @@ use zebra_node_services::mempool::{Gossip, Request, Response}; use zebra_state as zs; use zebra_state::{ChainTipChange, TipAction}; -use crate::components::{mempool::crawler::RATE_LIMIT_DELAY, sync::SyncStatus}; +use crate::components::sync::SyncStatus; pub mod config; mod crawler; @@ -586,11 +585,9 @@ impl Service for Mempool { let best_tip_height = self.latest_chain_tip.best_tip_height(); // Clean up completed download tasks and add to mempool if successful. - while let Poll::Ready(Some(r)) = - pin!(tx_downloads.timeout(RATE_LIMIT_DELAY)).poll_next(cx) - { - match r { - Ok(Ok((tx, spent_mempool_outpoints, expected_tip_height))) => { + while let Poll::Ready(Some(result)) = pin!(&mut *tx_downloads).poll_next(cx) { + match result { + Ok(Ok((tx, spent_mempool_outpoints, expected_tip_height, rsp_tx))) => { // # Correctness: // // It's okay to use tip height here instead of the tip hash since @@ -609,18 +606,25 @@ impl Service for Mempool { // Save transaction ids that we will send to peers send_to_peers_ids.insert(inserted_id); } + + // Send the result to responder channel if one was provided. + if let Some(rsp_tx) = rsp_tx { + let _ = rsp_tx + .send(insert_result.map(|_| ()).map_err(|err| err.into())); + } } else { 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(), None); + .download_if_needed_and_verify(tx.transaction.into(), rsp_tx); } } Ok(Err((tx_id, error))) => { tracing::debug!(?tx_id, ?error, "mempool transaction failed to verify"); metrics::counter!("mempool.failed.verify.tasks.total", "reason" => error.to_string()).increment(1); + storage.reject_if_needed(tx_id, error); } Err(_elapsed) => { diff --git a/zebrad/src/components/mempool/downloads.rs b/zebrad/src/components/mempool/downloads.rs index 45fd44a7c05..68d29aadcaf 100644 --- a/zebrad/src/components/mempool/downloads.rs +++ b/zebrad/src/components/mempool/downloads.rs @@ -54,7 +54,10 @@ use zebra_network as zn; use zebra_node_services::mempool::Gossip; use zebra_state::{self as zs, CloneError}; -use crate::components::sync::{BLOCK_DOWNLOAD_TIMEOUT, BLOCK_VERIFY_TIMEOUT}; +use crate::components::{ + mempool::crawler::RATE_LIMIT_DELAY, + sync::{BLOCK_DOWNLOAD_TIMEOUT, BLOCK_VERIFY_TIMEOUT}, +}; use super::MempoolError; @@ -112,16 +115,16 @@ pub enum TransactionDownloadVerifyError { #[error("transaction is already in state")] InState, - #[error("error in state service")] + #[error("error in state service: {0}")] StateError(#[source] CloneError), - #[error("error downloading transaction")] + #[error("error downloading transaction: {0}")] DownloadFailed(#[source] CloneError), #[error("transaction download / verification was cancelled")] Cancelled, - #[error("transaction did not pass consensus validation")] + #[error("transaction did not pass consensus validation: {0}")] Invalid(#[from] zebra_consensus::error::TransactionError), } @@ -154,12 +157,16 @@ where pending: FuturesUnordered< JoinHandle< Result< - ( - VerifiedUnminedTx, - Vec, - Option, - ), - (TransactionDownloadVerifyError, UnminedTxId), + Result< + ( + VerifiedUnminedTx, + Vec, + Option, + Option>>, + ), + (TransactionDownloadVerifyError, UnminedTxId), + >, + tokio::time::error::Elapsed, >, >, >, @@ -179,12 +186,16 @@ where ZS::Future: Send, { type Item = Result< - ( - VerifiedUnminedTx, - Vec, - Option, - ), - (UnminedTxId, TransactionDownloadVerifyError), + Result< + ( + VerifiedUnminedTx, + Vec, + Option, + Option>>, + ), + (UnminedTxId, TransactionDownloadVerifyError), + >, + tokio::time::error::Elapsed, >; fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { @@ -198,20 +209,26 @@ where // task is scheduled for wakeup when the next task becomes ready. // // TODO: this would be cleaner with poll_map (#2693) - if let Some(join_result) = ready!(this.pending.poll_next(cx)) { - match join_result.expect("transaction download and verify tasks must not panic") { - Ok((tx, spent_mempool_outpoints, tip_height)) => { + let item = if let Some(join_result) = ready!(this.pending.poll_next(cx)) { + let result = join_result.expect("transaction download and verify tasks must not panic"); + let result = match result { + Ok(Ok((tx, spent_mempool_outpoints, tip_height, rsp_tx))) => { this.cancel_handles.remove(&tx.transaction.id); - Poll::Ready(Some(Ok((tx, spent_mempool_outpoints, tip_height)))) + Ok(Ok((tx, spent_mempool_outpoints, tip_height, rsp_tx))) } - Err((e, hash)) => { + Ok(Err((e, hash))) => { this.cancel_handles.remove(&hash); - Poll::Ready(Some(Err((hash, e)))) + Ok(Err((hash, e))) } - } + Err(elapsed) => Err(elapsed), + }; + + Some(result) } else { - Poll::Ready(None) - } + None + }; + + Poll::Ready(item) } fn size_hint(&self) -> (usize, Option) { @@ -255,7 +272,7 @@ where pub fn download_if_needed_and_verify( &mut self, gossiped_tx: Gossip, - rsp_tx: Option>>, + mut rsp_tx: Option>>, ) -> Result<(), MempoolError> { let txid = gossiped_tx.id(); @@ -381,36 +398,53 @@ where // Tack the hash onto the error so we can remove the cancel handle // on failure as well as on success. .map_err(move |e| (e, txid)) - .inspect(move |result| { - // Hide the transaction data to avoid filling the logs - let result = result.as_ref().map(|_tx| txid); - debug!("mempool transaction result: {result:?}"); - }) + .inspect(move |result| { + // Hide the transaction data to avoid filling the logs + let result = result.as_ref().map(|_tx| txid); + debug!("mempool transaction result: {result:?}"); + }) .in_current_span(); let task = tokio::spawn(async move { + let fut = tokio::time::timeout(RATE_LIMIT_DELAY, fut); + // Prefer the cancel handle if both are ready. let result = tokio::select! { biased; _ = &mut cancel_rx => { trace!("task cancelled prior to completion"); metrics::counter!("mempool.cancelled.verify.tasks.total").increment(1); - Err((TransactionDownloadVerifyError::Cancelled, txid)) + if let Some(rsp_tx) = rsp_tx.take() { + let _ = rsp_tx.send(Err("verification cancelled".into())); + } + + Ok(Err((TransactionDownloadVerifyError::Cancelled, txid))) } - verification = fut => verification, + verification = fut => { + verification + .inspect_err(|_elapsed| { + if let Some(rsp_tx) = rsp_tx.take() { + let _ = rsp_tx.send(Err("timeout waiting for verification result".into())); + } + }) + .map(|inner_result| { + match inner_result { + Ok((transaction, spent_mempool_outpoints, tip_height)) => Ok((transaction, spent_mempool_outpoints, tip_height, rsp_tx)), + Err((tx_verifier_error, tx_id)) => { + if let Some(rsp_tx) = rsp_tx.take() { + let error_msg = format!( + "failed to validate tx: {tx_id}, error: {tx_verifier_error}" + ); + let _ = rsp_tx.send(Err(error_msg.into())); + }; + + Err((tx_verifier_error, tx_id)) + } + } + }) + }, }; - // Send the result to responder channel if one was provided. - // TODO: Wait until transactions are added to the verified set before sending an Ok to `rsp_tx`. - if let Some(rsp_tx) = rsp_tx { - let _ = rsp_tx.send( - result - .as_ref() - .map(|_| ()) - .map_err(|(err, _)| err.clone().into()), - ); - } - result }); diff --git a/zebrad/src/components/mempool/error.rs b/zebrad/src/components/mempool/error.rs index c70ca56cbc6..d27c78b6da3 100644 --- a/zebrad/src/components/mempool/error.rs +++ b/zebrad/src/components/mempool/error.rs @@ -23,7 +23,9 @@ pub enum MempoolError { /// /// Note that the mempool caches this error. See [`super::storage::Storage`] /// for more details. - #[error("the transaction will be rejected from the mempool until the next chain tip block")] + #[error( + "the transaction will be rejected from the mempool until the next chain tip block: {0}" + )] StorageExactTip(#[from] ExactTipRejectionError), /// Transaction rejected based on its effects (spends, outputs, transaction @@ -33,7 +35,7 @@ pub enum MempoolError { /// /// Note that the mempool caches this error. See [`super::storage::Storage`] /// for more details. - #[error("any transaction with the same effects will be rejected from the mempool until the next chain tip block")] + #[error("any transaction with the same effects will be rejected from the mempool until the next chain tip block: {0}")] StorageEffectsTip(#[from] SameEffectsTipRejectionError), /// Transaction rejected based on its effects (spends, outputs, transaction @@ -44,7 +46,7 @@ pub enum MempoolError { /// /// Note that the mempool caches this error. See [`super::storage::Storage`] /// for more details. - #[error("any transaction with the same effects will be rejected from the mempool until a chain reset")] + #[error("any transaction with the same effects will be rejected from the mempool until a chain reset: {0}")] StorageEffectsChain(#[from] SameEffectsChainRejectionError), /// Transaction rejected because the mempool already contains another diff --git a/zebrad/src/components/mempool/storage.rs b/zebrad/src/components/mempool/storage.rs index ef3733b128e..cee0845ba2b 100644 --- a/zebrad/src/components/mempool/storage.rs +++ b/zebrad/src/components/mempool/storage.rs @@ -55,7 +55,7 @@ pub(crate) const MAX_EVICTION_MEMORY_ENTRIES: usize = 40_000; #[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] #[allow(dead_code)] pub enum ExactTipRejectionError { - #[error("transaction did not pass consensus validation")] + #[error("transaction did not pass consensus validation: {0}")] FailedVerification(#[from] zebra_consensus::error::TransactionError), } diff --git a/zebrad/src/components/mempool/tests/vector.rs b/zebrad/src/components/mempool/tests/vector.rs index 1b87097aaf1..9dd3557de9c 100644 --- a/zebrad/src/components/mempool/tests/vector.rs +++ b/zebrad/src/components/mempool/tests/vector.rs @@ -978,22 +978,22 @@ async fn mempool_responds_to_await_output() -> Result<(), Report> { let result_rx = results.remove(0).expect("should pass initial checks"); assert!(results.is_empty(), "should have 1 result for 1 queued tx"); - tokio::time::timeout(Duration::from_secs(10), result_rx) - .await - .expect("should not time out") - .expect("mempool tx verification result channel should not be closed") - .expect("mocked verification should be successful"); - - // Wait for next steps in mempool's Downloads to finish - // TODO: Move this and the `ready().await` below above waiting for the mempool verification result above after - // waiting to respond with a transaction's verification result until after it's been inserted into the mempool. + // Wait for post-verification steps in mempool's Downloads tokio::time::sleep(Duration::from_secs(1)).await; + // Note: Buffered services shouldn't be polled without being called. + // See `mempool::Request::CheckForVerifiedTransactions` for more details. mempool .ready() .await .expect("polling mempool should succeed"); + tokio::time::timeout(Duration::from_secs(10), result_rx) + .await + .expect("should not time out") + .expect("mempool tx verification result channel should not be closed") + .expect("mocked verification should be successful"); + assert_eq!( mempool.storage().transaction_count(), 1, diff --git a/zebrad/src/components/sync/end_of_support.rs b/zebrad/src/components/sync/end_of_support.rs index 36586678bdf..284c266fb6c 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_699_000; +pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_742_000; /// The maximum number of days after `ESTIMATED_RELEASE_HEIGHT` where a Zebra server will run /// without halting. diff --git a/zebrad/tests/common/lightwalletd/send_transaction_test.rs b/zebrad/tests/common/lightwalletd/send_transaction_test.rs index bee6cf78356..6ac031e491b 100644 --- a/zebrad/tests/common/lightwalletd/send_transaction_test.rs +++ b/zebrad/tests/common/lightwalletd/send_transaction_test.rs @@ -16,15 +16,18 @@ //! were obtained. This is to ensure that zebra does not reject the transactions because they have //! already been seen in a block. -use std::{cmp::min, sync::Arc, time::Duration}; +use std::{cmp::min, collections::HashSet, sync::Arc}; +use tower::BoxError; -use color_eyre::eyre::Result; +use color_eyre::eyre::{eyre, Result}; use zebra_chain::{ - parameters::Network::{self, *}, + block::Block, + parameters::Network::*, serialization::ZcashSerialize, transaction::{self, Transaction}, }; +use zebra_node_services::rpc_client::RpcRequestClient; use zebra_rpc::queue::CHANNEL_AND_QUEUE_CAPACITY; use zebrad::components::mempool::downloads::MAX_INBOUND_CONCURRENCY; @@ -34,10 +37,13 @@ use crate::common::{ lightwalletd::{ can_spawn_lightwalletd_for_rpc, spawn_lightwalletd_for_rpc, sync::wait_for_zebrad_and_lightwalletd_sync, - wallet_grpc::{self, connect_to_lightwalletd, Empty, Exclude}, + wallet_grpc::{ + self, compact_tx_streamer_client::CompactTxStreamerClient, connect_to_lightwalletd, + Empty, Exclude, + }, }, - sync::LARGE_CHECKPOINT_TIMEOUT, - test_type::TestType::{self, *}, + regtest::MiningRpcMethods, + test_type::TestType::*, }; /// The maximum number of transactions we want to send in the test. @@ -85,11 +91,19 @@ pub async fn run() -> Result<()> { "running gRPC send transaction test using lightwalletd & zebrad", ); - let transactions = - load_transactions_from_future_blocks(network.clone(), test_type, test_name).await?; + let mut count = 0; + let blocks: Vec = + get_future_blocks(&network, test_type, test_name, MAX_NUM_FUTURE_BLOCKS) + .await? + .into_iter() + .take_while(|block| { + count += block.transactions.len() - 1; + count <= max_sent_transactions() + }) + .collect(); tracing::info!( - transaction_count = ?transactions.len(), + blocks_count = ?blocks.len(), partial_sync_path = ?zebrad_state_path, "got transactions to send, spawning isolated zebrad...", ); @@ -113,6 +127,8 @@ pub async fn run() -> Result<()> { let zebra_rpc_address = zebra_rpc_address.expect("lightwalletd test must have RPC port"); + let zebrad_rpc_client = RpcRequestClient::new(zebra_rpc_address); + tracing::info!( ?test_type, ?zebra_rpc_address, @@ -134,7 +150,7 @@ pub async fn run() -> Result<()> { "spawned lightwalletd connected to zebrad, waiting for them both to sync...", ); - let (_lightwalletd, mut zebrad) = wait_for_zebrad_and_lightwalletd_sync( + let (_lightwalletd, _zebrad) = wait_for_zebrad_and_lightwalletd_sync( lightwalletd, lightwalletd_rpc_port, zebrad, @@ -164,6 +180,53 @@ pub async fn run() -> Result<()> { .await? .into_inner(); + let mut transaction_hashes = HashSet::new(); + let mut has_tx_with_shielded_elements = false; + let mut counter = 0; + + for block in blocks { + let (has_shielded_elements, count) = send_transactions_from_block( + &mut rpc_client, + &zebrad_rpc_client, + block.clone(), + &mut transaction_hashes, + ) + .await?; + + has_tx_with_shielded_elements |= has_shielded_elements; + counter += count; + + tracing::info!( + height = ?block.coinbase_height(), + "submitting block at height" + ); + + let submit_block_response = zebrad_rpc_client.submit_block(block).await; + tracing::info!(?submit_block_response, "submitted block"); + } + + // GetMempoolTx: make sure at least one of the transactions were inserted into the mempool. + assert!( + !has_tx_with_shielded_elements || counter >= 1, + "failed to read v4+ transactions with shielded elements \ + from future blocks in mempool via lightwalletd" + ); + + Ok(()) +} + +/// Sends non-coinbase transactions from a block to the mempool, verifies that the transactions +/// can be found in the mempool via lightwalletd, and commits the block to Zebra's chainstate. +/// +/// Returns the zebrad test child that's handling the RPC requests. + +#[tracing::instrument(skip_all)] +async fn send_transactions_from_block( + rpc_client: &mut CompactTxStreamerClient, + zebrad_rpc_client: &RpcRequestClient, + block: Block, + transaction_hashes: &mut HashSet, +) -> Result<(bool, usize)> { // Lightwalletd won't call `get_raw_mempool` again until 2 seconds after the last call: // // @@ -171,8 +234,17 @@ pub async fn run() -> Result<()> { let sleep_until_lwd_last_mempool_refresh = tokio::time::sleep(std::time::Duration::from_secs(4)); - let transaction_hashes: Vec = - transactions.iter().map(|tx| tx.hash()).collect(); + let transactions: Vec<_> = block + .transactions + .iter() + .filter(|tx| !tx.is_coinbase()) + .collect(); + + if transactions.is_empty() { + return Ok((false, 0)); + } + + transaction_hashes.extend(transactions.iter().map(|tx| tx.hash())); tracing::info!( transaction_count = ?transactions.len(), @@ -181,7 +253,7 @@ pub async fn run() -> Result<()> { ); let mut has_tx_with_shielded_elements = false; - for transaction in transactions { + for &transaction in &transactions { let transaction_hash = transaction.hash(); // See @@ -195,20 +267,24 @@ pub async fn run() -> Result<()> { tracing::info!(?transaction_hash, "sending transaction..."); - let request = prepare_send_transaction_request(transaction); + let request = prepare_send_transaction_request(transaction.clone()); - let response = rpc_client.send_transaction(request).await?.into_inner(); + match rpc_client.send_transaction(request).await { + Ok(response) => assert_eq!(response.into_inner(), expected_response), + Err(err) => { + tracing::warn!(?err, "failed to send transaction"); + let send_tx_rsp = zebrad_rpc_client + .send_transaction(transaction) + .await + .map_err(|e| eyre!(e)); - assert_eq!(response, expected_response); + tracing::warn!(?send_tx_rsp, "failed to send tx twice"); + } + }; } - // Check if some transaction is sent to mempool, - // Fails if there are only coinbase transactions in the first 50 future blocks - tracing::info!("waiting for mempool to verify some transactions..."); - zebrad.expect_stdout_line_matches("sending mempool transaction broadcast")?; // Wait for more transactions to verify, `GetMempoolTx` only returns txs where tx.HasShieldedElements() // - tokio::time::sleep(std::time::Duration::from_secs(2)).await; sleep_until_lwd_last_mempool_refresh.await; tracing::info!("calling GetMempoolTx gRPC to fetch transactions..."); @@ -217,25 +293,6 @@ pub async fn run() -> Result<()> { .await? .into_inner(); - // Sometimes lightwalletd doesn't check the mempool, and waits for the next block instead. - // If that happens, we skip the rest of the test. - tracing::info!("checking if lightwalletd has queried the mempool..."); - - // We need a short timeout here, because sometimes this message is not logged. - zebrad = zebrad.with_timeout(Duration::from_secs(60)); - let tx_log = - zebrad.expect_stdout_line_matches("answered mempool request .*req.*=.*TransactionIds"); - // Reset the failed timeout and give the rest of the test enough time to finish. - #[allow(unused_assignments)] - { - zebrad = zebrad.with_timeout(LARGE_CHECKPOINT_TIMEOUT); - } - - if tx_log.is_err() { - tracing::info!("lightwalletd didn't query the mempool, skipping mempool contents checks"); - return Ok(()); - } - tracing::info!("checking the mempool contains some of the sent transactions..."); let mut counter = 0; while let Some(tx) = transactions_stream.message().await? { @@ -251,16 +308,6 @@ pub async fn run() -> Result<()> { counter += 1; } - // GetMempoolTx: make sure at least one of the transactions were inserted into the mempool. - // - // TODO: Update `load_transactions_from_future_blocks()` to return block height offsets and, - // only check if a transaction from the first block has shielded elements - assert!( - !has_tx_with_shielded_elements || counter >= 1, - "failed to read v4+ transactions with shielded elements from future blocks in mempool via lightwalletd" - ); - - // TODO: GetMempoolStream: make sure at least one of the transactions were inserted into the mempool. tracing::info!("calling GetMempoolStream gRPC to fetch transactions..."); let mut transaction_stream = rpc_client.get_mempool_stream(Empty {}).await?.into_inner(); @@ -270,32 +317,7 @@ pub async fn run() -> Result<()> { _counter += 1; } - Ok(()) -} - -/// Loads transactions from a few block(s) after the chain tip of the cached state. -/// -/// Returns a list of non-coinbase transactions from blocks that have not been finalized to disk -/// in the `ZEBRA_CACHED_STATE_DIR`. -/// -/// ## Panics -/// -/// If the provided `test_type` doesn't need an rpc server and cached state -#[tracing::instrument] -async fn load_transactions_from_future_blocks( - network: Network, - test_type: TestType, - test_name: &str, -) -> Result>> { - let transactions = get_future_blocks(&network, test_type, test_name, MAX_NUM_FUTURE_BLOCKS) - .await? - .into_iter() - .flat_map(|block| block.transactions) - .filter(|transaction| !transaction.is_coinbase()) - .take(max_sent_transactions()) - .collect(); - - Ok(transactions) + Ok((has_tx_with_shielded_elements, counter)) } /// Prepare a request to send to lightwalletd that contains a transaction to be sent. @@ -307,3 +329,21 @@ fn prepare_send_transaction_request(transaction: Arc) -> wallet_grp height: 0, } } + +trait SendTransactionMethod { + async fn send_transaction( + &self, + transaction: &Arc, + ) -> Result; +} + +impl SendTransactionMethod for RpcRequestClient { + async fn send_transaction( + &self, + transaction: &Arc, + ) -> Result { + let tx_data = hex::encode(transaction.zcash_serialize_to_vec()?); + self.json_result_from_call("sendrawtransaction", format!(r#"["{tx_data}"]"#)) + .await + } +} diff --git a/zebrad/tests/common/lightwalletd/sync.rs b/zebrad/tests/common/lightwalletd/sync.rs index 8dce05a9150..3a55aedb5c2 100644 --- a/zebrad/tests/common/lightwalletd/sync.rs +++ b/zebrad/tests/common/lightwalletd/sync.rs @@ -32,7 +32,7 @@ pub fn wait_for_zebrad_and_lightwalletd_sync< wait_for_zebrad_mempool: bool, wait_for_zebrad_tip: bool, ) -> Result<(TestChild, TestChild

)> { - let is_zebrad_finished = AtomicBool::new(false); + let is_zebrad_finished = AtomicBool::new(!wait_for_zebrad_tip); let is_lightwalletd_finished = AtomicBool::new(false); let is_zebrad_finished = &is_zebrad_finished; diff --git a/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs b/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs index 702bb740142..a26ada3f9c3 100644 --- a/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs +++ b/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs @@ -37,11 +37,14 @@ use color_eyre::eyre::Result; use hex_literal::hex; use zebra_chain::{ - block::Block, - parameters::Network, - parameters::NetworkUpgrade::{Nu5, Sapling}, + block::{Block, Height}, + parameters::{ + Network, + NetworkUpgrade::{Nu5, Sapling}, + }, serialization::ZcashDeserializeInto, }; +use zebra_consensus::funding_stream_address; use zebra_state::state_database_format_version_in_code; use crate::common::{ @@ -291,60 +294,89 @@ pub async fn run() -> Result<()> { // For the provided address in the first 10 blocks there are 10 transactions in the mainnet assert_eq!(10, counter); - // Call `GetTaddressBalance` with the ZF funding stream address - let balance = rpc_client - .get_taddress_balance(AddressList { - addresses: vec!["t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1".to_string()], - }) - .await? - .into_inner(); - - // With ZFND or Major Grants funding stream address, the balance will always be greater than zero, - // because new coins are created in each block - assert!(balance.value_zat > 0); - - // Call `GetTaddressBalanceStream` with the ZF funding stream address as a stream argument - let zf_stream_address = Address { - address: "t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1".to_string(), - }; - - let balance_zf = rpc_client - .get_taddress_balance_stream(tokio_stream::iter(vec![zf_stream_address.clone()])) - .await? - .into_inner(); - - // With ZFND funding stream address, the balance will always be greater than zero, - // because new coins are created in each block - assert!(balance_zf.value_zat > 0); - - // Call `GetTaddressBalanceStream` with the MG funding stream address as a stream argument - let mg_stream_address = Address { - address: "t3XyYW8yBFRuMnfvm5KLGFbEVz25kckZXym".to_string(), - }; - - let balance_mg = rpc_client - .get_taddress_balance_stream(tokio_stream::iter(vec![mg_stream_address.clone()])) - .await? - .into_inner(); + let lwd_tip_height: Height = u32::try_from(block_tip.height) + .expect("should be below max block height") + .try_into() + .expect("should be below max block height"); + + let mut all_stream_addresses = Vec::new(); + let mut all_balance_streams = Vec::new(); + for &fs_receiver in network.funding_streams(lwd_tip_height).recipients().keys() { + let Some(fs_address) = funding_stream_address(lwd_tip_height, &network, fs_receiver) else { + // Skip if the lightwalletd tip height is above the funding stream end height. + continue; + }; + + tracing::info!(?fs_address, "getting balance for active fs address"); + + // Call `GetTaddressBalance` with the active funding stream address. + let balance = rpc_client + .get_taddress_balance(AddressList { + addresses: vec![fs_address.to_string()], + }) + .await? + .into_inner(); + + // Call `GetTaddressBalanceStream` with the active funding stream address as a stream argument. + let stream_address = Address { + address: fs_address.to_string(), + }; + + let balance_stream = rpc_client + .get_taddress_balance_stream(tokio_stream::iter(vec![stream_address.clone()])) + .await? + .into_inner(); + + // With any active funding stream address, the balance will always be greater than zero for blocks + // below the funding stream end height because new coins are created in each block. + assert!(balance.value_zat > 0); + assert!(balance_stream.value_zat > 0); + + all_stream_addresses.push(stream_address); + all_balance_streams.push(balance_stream.value_zat); + + // Call `GetAddressUtxos` with the active funding stream address that will always have utxos + let utxos = rpc_client + .get_address_utxos(GetAddressUtxosArg { + addresses: vec![fs_address.to_string()], + start_height: 1, + max_entries: 1, + }) + .await? + .into_inner(); + + // As we requested one entry we should get a response of length 1 + assert_eq!(utxos.address_utxos.len(), 1); + + // Call `GetAddressUtxosStream` with the active funding stream address that will always have utxos + let mut utxos_zf = rpc_client + .get_address_utxos_stream(GetAddressUtxosArg { + addresses: vec![fs_address.to_string()], + start_height: 1, + max_entries: 2, + }) + .await? + .into_inner(); + + let mut counter = 0; + while let Some(_utxos) = utxos_zf.message().await? { + counter += 1; + } + // As we are in a "in sync" chain we know there are more than 2 utxos for this address (coinbase maturity rule) + // but we will receive the max of 2 from the stream response because we used a limit of 2 `max_entries`. + assert_eq!(2, counter); + } - // With Major Grants funding stream address, the balance will always be greater than zero, - // because new coins are created in each block - assert!(balance_mg.value_zat > 0); + if let Some(expected_total_balance) = all_balance_streams.into_iter().reduce(|a, b| a + b) { + // Call `GetTaddressBalanceStream` for all active funding stream addresses as a stream argument. + let total_balance = rpc_client + .get_taddress_balance_stream(tokio_stream::iter(all_stream_addresses)) + .await? + .into_inner(); - // Call `GetTaddressBalanceStream` with both, the ZFND and the MG funding stream addresses as a stream argument - let balance_both = rpc_client - .get_taddress_balance_stream(tokio_stream::iter(vec![ - zf_stream_address, - mg_stream_address, - ])) - .await? - .into_inner(); - - // The result is the sum of the values in both addresses - assert_eq!( - balance_both.value_zat, - balance_zf.value_zat + balance_mg.value_zat - ); + // The result should be the sum of the values in all active funding stream addresses. + assert_eq!(total_balance.value_zat, expected_total_balance); + } let sapling_treestate_init_height = sapling_activation_height + 1; @@ -374,37 +406,6 @@ pub async fn run() -> Result<()> { *zebra_test::vectors::SAPLING_TREESTATE_MAINNET_419201_STRING ); - // Call `GetAddressUtxos` with the ZF funding stream address that will always have utxos - let utxos = rpc_client - .get_address_utxos(GetAddressUtxosArg { - addresses: vec!["t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1".to_string()], - start_height: 1, - max_entries: 1, - }) - .await? - .into_inner(); - - // As we requested one entry we should get a response of length 1 - assert_eq!(utxos.address_utxos.len(), 1); - - // Call `GetAddressUtxosStream` with the ZF funding stream address that will always have utxos - let mut utxos_zf = rpc_client - .get_address_utxos_stream(GetAddressUtxosArg { - addresses: vec!["t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1".to_string()], - start_height: 1, - max_entries: 2, - }) - .await? - .into_inner(); - - let mut counter = 0; - while let Some(_utxos) = utxos_zf.message().await? { - counter += 1; - } - // As we are in a "in sync" chain we know there are more than 2 utxos for this address - // but we will receive the max of 2 from the stream response because we used a limit of 2 `max_entries`. - assert_eq!(2, counter); - // Call `GetLightdInfo` let lightd_info = rpc_client.get_lightd_info(Empty {}).await?.into_inner();