Merge branch 'main' into run-minor-db-upgrades-before-major-upgrades

This commit is contained in:
Pili Guerra 2024-09-02 12:56:18 +01:00 committed by GitHub
commit 51cc63d5fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
95 changed files with 2488 additions and 1307 deletions

View File

@ -228,7 +228,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'
@ -329,7 +329,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'

View File

@ -46,7 +46,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'
@ -113,7 +113,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'

View File

@ -44,7 +44,7 @@ jobs:
- name: Rust files
id: changed-files-rust
uses: tj-actions/changed-files@v44.5.2
uses: tj-actions/changed-files@v45.0.0
with:
files: |
**/*.rs
@ -56,7 +56,7 @@ jobs:
- name: Workflow files
id: changed-files-workflows
uses: tj-actions/changed-files@v44.5.2
uses: tj-actions/changed-files@v45.0.0
with:
files: |
.github/workflows/*.yml
@ -167,7 +167,7 @@ jobs:
needs: changed-files
steps:
- uses: actions/checkout@v4.1.7
- uses: codespell-project/actions-codespell@v2.0
- uses: codespell-project/actions-codespell@v2.1
with:
only_warn: 1

View File

@ -106,7 +106,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_FIREBASE_SA }}'
@ -164,7 +164,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_FIREBASE_SA }}'

View File

@ -52,7 +52,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'

View File

@ -124,7 +124,7 @@ jobs:
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_ARTIFACTS_SA }}'
@ -159,7 +159,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.6.0
uses: docker/build-push-action@v6.7.0
with:
target: ${{ inputs.dockerfile_target }}
context: .
@ -172,6 +172,10 @@ jobs:
FEATURES=${{ env.FEATURES }}
TEST_FEATURES=${{ env.TEST_FEATURES }}
push: true
# It's recommended to build images with max-level provenance attestations
# https://docs.docker.com/build/ci/github-actions/attestations/
provenance: mode=max
sbom: true
# Don't read from the cache if the caller disabled it.
# https://docs.docker.com/engine/reference/commandline/buildx_build/#options
no-cache: ${{ inputs.no_cache }}

View File

@ -150,7 +150,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'
@ -449,7 +449,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'
@ -726,7 +726,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'

View File

@ -45,7 +45,7 @@ jobs:
# Setup gcloud CLI
- name: Authenticate to Google Cloud
id: auth
uses: google-github-actions/auth@v2.1.4
uses: google-github-actions/auth@v2.1.5
with:
workload_identity_provider: '${{ vars.GCP_WIF }}'
service_account: '${{ vars.GCP_DEPLOYMENTS_SA }}'

View File

@ -5,6 +5,59 @@ 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 1.9.0](https://github.com/ZcashFoundation/zebra/releases/tag/v1.9.0) - 2024-08-02
This release includes deployment of NU6 on Testnet, configurable funding streams on custom Testnets, and updates Zebra's end-of-support (EoS)
from 16 weeks to 10 weeks so that it will panic before the expected activation height of NU6 on Mainnet.
It also replaces the `shielded-scan` compilation feature with a new `zebra-scanner` binary, adds a `TrustedChainSync` module
for replicating Zebra's best chain state, and a gRPC server in `zebra-rpc` as steps towards zcashd deprecation.
#### Recovering after finalizing a block from a chain fork
Zebra doesn't enforce an end-of-support height on Testnet, and previous versions of Zebra could mine or follow a chain fork that does not
activate NU6 on Testnet at height 2976000. Once a block from a fork is finalized in Zebra's state cache, updating to a version of Zebra that
does expect NU6 activation at that height will result in Zebra getting stuck, as it cannot rollback its finalized state. This can be resolved
by syncing Zebra from scratch, or by using the `copy-state` command to create a new state cache up to height 2975999. To use the `copy-state`
command, first make a copy Zebra's Testnet configuration with a different cache directory path, for example, if Zebra's configuration is at the
default path, by running `cp ~/.config/zebrad.toml ./zebrad-copy-target.toml`, then opening the new configuration file and editing the
`cache_dir` path in the `state` section. Once there's a copy of Zebra's configuration with the new state cache directory path, run:
`zebrad copy-state --target-config-path "./zebrad-copy-target.toml" --max-source-height "2975999"`, and then update the original
Zebra configuration to use the new state cache directory.
### Added
- A `zebra-scanner` binary replacing the `shielded-scan` compilation feature in `zebrad` ([#8608](https://github.com/ZcashFoundation/zebra/pull/8608))
- Adds a `TrustedChainSync` module for keeping up with Zebra's non-finalized best chain from a separate process ([#8596](https://github.com/ZcashFoundation/zebra/pull/8596))
- Add a tonic server in zebra-rpc with a `chain_tip_change()` method that notifies clients when Zebra's best chain tip changes ([#8674](https://github.com/ZcashFoundation/zebra/pull/8674))
- NU6 network upgrade variant, minimum protocol version, and Testnet activation height ([#8693](https://github.com/ZcashFoundation/zebra/pull/8693), [8733](https://github.com/ZcashFoundation/zebra/pull/8733), [#8804](https://github.com/ZcashFoundation/zebra/pull/8804))
- Configurable NU6 activation height on Regtest ([#8700](https://github.com/ZcashFoundation/zebra/pull/8700))
- Configurable Testnet funding streams ([#8718](https://github.com/ZcashFoundation/zebra/pull/8718))
- Post-NU6 funding streams, including a lockbox funding stream ([#8694](https://github.com/ZcashFoundation/zebra/pull/8694))
- Add value pool balances to `getblockchaininfo` RPC method response ([#8769](https://github.com/ZcashFoundation/zebra/pull/8769))
- Add NU6 lockbox funding stream information to `getblocksubsidy` RPC method response ([#8742](https://github.com/ZcashFoundation/zebra/pull/8742))
### Changed
- Reduce the end-of-support halt time from 16 weeks to 10 weeks ([#8734](https://github.com/ZcashFoundation/zebra/pull/8734))
- Bump the current protocol version from 170100 to 170110 ([#8804](https://github.com/ZcashFoundation/zebra/pull/8804))
- Track the balance of the deferred chain value pool ([#8732](https://github.com/ZcashFoundation/zebra/pull/8732), [#8729](https://github.com/ZcashFoundation/zebra/pull/8729))
- Require that coinbase transactions balance exactly after NU6 activation ([#8727](https://github.com/ZcashFoundation/zebra/pull/8727))
- Support in-place disk format upgrades for major database version bumps ([#8748](https://github.com/ZcashFoundation/zebra/pull/8748))
### Fixed
- Return full network upgrade activation list in `getblockchaininfo` method ([#8699](https://github.com/ZcashFoundation/zebra/pull/8699))
- Update documentation for the new `zebra-scanner` binary ([#8675](https://github.com/ZcashFoundation/zebra/pull/8675))
- Update documentation for using Zebra with lightwalletd ([#8714](https://github.com/ZcashFoundation/zebra/pull/8714))
- Reduce debug output for Network on Regtest and default Testnet ([#8760](https://github.com/ZcashFoundation/zebra/pull/8760))
### Contributors
Thank you to everyone who contributed to this release, we couldn't make Zebra without you:
@arya2, @conradoplg, @dependabot[bot], @oxarbitrage, @therealyingtong and @upbqdn
## [Zebra 1.8.0](https://github.com/ZcashFoundation/zebra/releases/tag/v1.8.0) - 2024-07-02
- Zebra now uses a default unpaid actions limit of 0, dropping transactions with

View File

@ -428,20 +428,6 @@ dependencies = [
"which",
]
[[package]]
name = "bip0039"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef0f0152ec5cf17f49a5866afaa3439816207fd4f0a224c0211ffaf5e278426"
dependencies = [
"hmac",
"pbkdf2",
"rand 0.8.5",
"sha2",
"unicode-normalization",
"zeroize",
]
[[package]]
name = "bip32"
version = "0.5.2"
@ -553,9 +539,9 @@ dependencies = [
[[package]]
name = "bridgetree"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbfcb6c5a091e80cb3d3b0c1a7f126af4631cd5065b1f9929b139f1be8f3fb62"
checksum = "f62227647af796dd9f1637da0392676a2e200973b817b082fc9be89bf93ddd74"
dependencies = [
"incrementalmerkletree",
]
@ -901,8 +887,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ed14aa9c9f927213c6e4f3ef75faaad3406134efe84ba2cb7983431d5f0931"
dependencies = [
"futures-core",
"prost 0.13.1",
"prost-types 0.13.1",
"prost",
"prost-types",
"tonic",
"tracing-core",
]
@ -920,8 +906,8 @@ dependencies = [
"hdrhistogram",
"humantime",
"hyper-util",
"prost 0.13.1",
"prost-types 0.13.1",
"prost",
"prost-types",
"serde",
"serde_json",
"thread_local",
@ -1331,7 +1317,7 @@ dependencies = [
[[package]]
name = "equihash"
version = "0.2.0"
source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"blake2b_simd",
"byteorder",
@ -1375,7 +1361,7 @@ dependencies = [
[[package]]
name = "f4jumble"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"blake2b_simd",
]
@ -2106,9 +2092,9 @@ dependencies = [
[[package]]
name = "incrementalmerkletree"
version = "0.5.1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1872810fb725b06b8c153dde9e86f3ec26747b9b60096da7a869883b549cbe"
checksum = "75346da3bd8e3d8891d02508245ed2df34447ca6637e343829f8d08986e9cde2"
dependencies = [
"either",
]
@ -2785,9 +2771,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "orchard"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0462569fc8b0d1b158e4d640571867a4e4319225ebee2ab6647e60c70af19ae3"
checksum = "4dc7bde644aeb980be296cd908c6650894dc8541deb56f9f5294c52ed7ca568f"
dependencies = [
"aes",
"bitvec",
@ -2808,6 +2794,7 @@ dependencies = [
"serde",
"subtle",
"tracing",
"visibility",
"zcash_note_encryption",
"zcash_spec",
"zip32",
@ -2935,17 +2922,6 @@ dependencies = [
"windows-targets 0.52.5",
]
[[package]]
name = "password-hash"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8"
dependencies = [
"base64ct",
"rand_core 0.6.4",
"subtle",
]
[[package]]
name = "pasta_curves"
version = "0.5.1"
@ -2961,16 +2937,6 @@ dependencies = [
"subtle",
]
[[package]]
name = "pbkdf2"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7"
dependencies = [
"digest",
"password-hash",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -3240,16 +3206,6 @@ dependencies = [
"syn 2.0.72",
]
[[package]]
name = "prost"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
dependencies = [
"bytes",
"prost-derive 0.12.6",
]
[[package]]
name = "prost"
version = "0.13.1"
@ -3257,28 +3213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc"
dependencies = [
"bytes",
"prost-derive 0.13.1",
]
[[package]]
name = "prost-build"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
dependencies = [
"bytes",
"heck 0.5.0",
"itertools 0.12.1",
"log",
"multimap",
"once_cell",
"petgraph",
"prettyplease",
"prost 0.12.6",
"prost-types 0.12.6",
"regex",
"syn 2.0.72",
"tempfile",
"prost-derive",
]
[[package]]
@ -3295,26 +3230,13 @@ dependencies = [
"once_cell",
"petgraph",
"prettyplease",
"prost 0.13.1",
"prost-types 0.13.1",
"prost",
"prost-types",
"regex",
"syn 2.0.72",
"tempfile",
]
[[package]]
name = "prost-derive"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
dependencies = [
"anyhow",
"itertools 0.12.1",
"proc-macro2",
"quote",
"syn 2.0.72",
]
[[package]]
name = "prost-derive"
version = "0.13.1"
@ -3328,22 +3250,13 @@ dependencies = [
"syn 2.0.72",
]
[[package]]
name = "prost-types"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
dependencies = [
"prost 0.12.6",
]
[[package]]
name = "prost-types"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2"
dependencies = [
"prost 0.13.1",
"prost",
]
[[package]]
@ -3848,9 +3761,9 @@ dependencies = [
[[package]]
name = "sapling-crypto"
version = "0.1.3"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02f4270033afcb0c74c5c7d59c73cfd1040367f67f224fe7ed9a919ae618f1b7"
checksum = "15e379398fffad84e49f9a45a05635fc004f66086e65942dbf4eb95332c26d2a"
dependencies = [
"aes",
"bellman",
@ -4192,9 +4105,9 @@ dependencies = [
[[package]]
name = "shardtree"
version = "0.3.1"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cdd24424ce0b381646737fedddc33c4dcf7dcd2d545056b53f7982097bef5"
checksum = "78222845cd8bbe5eb95687407648ff17693a35de5e8abaa39a4681fb21e033f9"
dependencies = [
"bitflags 2.6.0",
"either",
@ -4736,7 +4649,7 @@ dependencies = [
"hyper-util",
"percent-encoding",
"pin-project",
"prost 0.13.1",
"prost",
"socket2",
"tokio",
"tokio-stream",
@ -4746,19 +4659,6 @@ dependencies = [
"tracing",
]
[[package]]
name = "tonic-build"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889"
dependencies = [
"prettyplease",
"proc-macro2",
"prost-build 0.12.6",
"quote",
"syn 2.0.72",
]
[[package]]
name = "tonic-build"
version = "0.12.1"
@ -4767,7 +4667,7 @@ checksum = "568392c5a2bd0020723e3f387891176aabafe36fd9fcd074ad309dfa0c8eb964"
dependencies = [
"prettyplease",
"proc-macro2",
"prost-build 0.13.1",
"prost-build",
"quote",
"syn 2.0.72",
]
@ -4778,8 +4678,8 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b742c83ad673e9ab5b4ce0981f7b9e8932be9d60e8682cbf9120494764dbc173"
dependencies = [
"prost 0.13.1",
"prost-types 0.13.1",
"prost",
"prost-types",
"tokio",
"tokio-stream",
"tonic",
@ -4808,7 +4708,7 @@ dependencies = [
[[package]]
name = "tower-batch-control"
version = "0.2.41-beta.14"
version = "0.2.41-beta.15"
dependencies = [
"color-eyre",
"ed25519-zebra",
@ -4831,7 +4731,7 @@ dependencies = [
[[package]]
name = "tower-fallback"
version = "0.2.41-beta.14"
version = "0.2.41-beta.15"
dependencies = [
"futures-core",
"pin-project",
@ -5212,6 +5112,17 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "visibility"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.72",
]
[[package]]
name = "void"
version = "1.0.2"
@ -5648,34 +5559,47 @@ checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
[[package]]
name = "zcash_address"
version = "0.3.2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "827c17a1f7e3a69f0d44e991ff610c7a842228afdc9dc2325ffdd1a67fee01e9"
checksum = "a6d26f21381dc220836dd8d2a9a10dbe85928a26232b011bc6a42b611789b743"
dependencies = [
"bech32",
"bs58",
"f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.2.0",
]
[[package]]
name = "zcash_address"
version = "0.3.2"
source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14bccd6cefb76f87b6d15a9e7b02b6c0515648c6de8e806c4e2d6f0f6ae640c5"
dependencies = [
"bech32",
"bs58",
"f4jumble 0.1.0 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_encoding 0.2.0 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_protocol 0.1.1 (git+https://github.com/zcash/librustzcash/?branch=main)",
"f4jumble 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zcash_address"
version = "0.5.0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"bech32",
"bs58",
"f4jumble 0.1.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)",
"zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)",
]
[[package]]
name = "zcash_client_backend"
version = "0.12.1"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0364e69c446fcf96a1f73f342c6c3fa697ea65ae7eeeae7d76ca847b9c442e40"
checksum = "80e3a0f3e5d7f299d8b7ef3237697630989c31ab1b162824c99c1cd8bc83715e"
dependencies = [
"base64 0.21.7",
"bech32",
@ -5690,7 +5614,7 @@ dependencies = [
"nom",
"nonempty",
"percent-encoding",
"prost 0.12.6",
"prost",
"rand_core 0.6.4",
"rayon",
"sapling-crypto",
@ -5698,23 +5622,63 @@ dependencies = [
"shardtree",
"subtle",
"time",
"tonic-build 0.10.2",
"tonic-build",
"tracing",
"which",
"zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_keys",
"zcash_address 0.4.0",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_keys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_note_encryption",
"zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.16.0",
"zcash_protocol 0.2.0",
"zip32",
"zip321 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zcash_client_backend"
version = "0.13.0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"base64 0.21.7",
"bech32",
"bls12_381",
"bs58",
"crossbeam-channel",
"document-features",
"group",
"hex",
"incrementalmerkletree",
"memuse",
"nom",
"nonempty",
"percent-encoding",
"prost",
"rand_core 0.6.4",
"rayon",
"sapling-crypto",
"secrecy",
"shardtree",
"subtle",
"time",
"tonic-build",
"tracing",
"which",
"zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)",
"zcash_keys 0.3.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_note_encryption",
"zcash_primitives 0.17.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)",
"zip32",
"zip321 0.1.0 (git+https://github.com/zcash/librustzcash/)",
]
[[package]]
name = "zcash_encoding"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f03391b81727875efa6ac0661a20883022b6fba92365dc121c48fa9b00c5aac0"
checksum = "052d8230202f0a018cd9b5d1b56b94cd25e18eccc2d8665073bcea8261ab87fc"
dependencies = [
"byteorder",
"nonempty",
@ -5722,8 +5686,8 @@ dependencies = [
[[package]]
name = "zcash_encoding"
version = "0.2.0"
source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0"
version = "0.2.1"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"byteorder",
"nonempty",
@ -5742,9 +5706,9 @@ dependencies = [
[[package]]
name = "zcash_keys"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "663489ffb4e51bc4436ff8796832612a9ff3c6516f1c620b5a840cb5dcd7b866"
checksum = "712faf4070107ab0b2828d0eda6aeaf4c3cb02564109832d95b97ad3467c95a5"
dependencies = [
"bech32",
"blake2b_simd",
@ -5759,10 +5723,35 @@ dependencies = [
"secrecy",
"subtle",
"tracing",
"zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_address 0.4.0",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.16.0",
"zcash_protocol 0.2.0",
"zip32",
]
[[package]]
name = "zcash_keys"
version = "0.3.0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"bech32",
"blake2b_simd",
"bls12_381",
"bs58",
"document-features",
"group",
"memuse",
"nonempty",
"rand_core 0.6.4",
"sapling-crypto",
"secrecy",
"subtle",
"tracing",
"zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)",
"zcash_primitives 0.17.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)",
"zip32",
]
@ -5781,13 +5770,13 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.15.1"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ccee58d0f9e8da312a999a4c0cd3d001ff3b37af6fb1318c89e6a3076f4da"
checksum = "5f044bc9cf2887ec408196fbafb44749e5581f57cc18d8da7aabaeb60cc40c64"
dependencies = [
"aes",
"bip0039",
"blake2b_simd",
"bs58",
"byteorder",
"document-features",
"equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -5807,18 +5796,19 @@ dependencies = [
"sha2",
"subtle",
"tracing",
"zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_address 0.4.0",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_note_encryption",
"zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.2.0",
"zcash_spec",
"zip32",
]
[[package]]
name = "zcash_primitives"
version = "0.15.1"
source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d87ab6a55591a8cf1866749fdc739ae1bbd06e6cec07ab0bbe5d57ee3390eb2"
dependencies = [
"aes",
"bip32",
@ -5826,7 +5816,7 @@ dependencies = [
"bs58",
"byteorder",
"document-features",
"equihash 0.2.0 (git+https://github.com/zcash/librustzcash/?branch=main)",
"equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ff",
"fpe",
"group",
@ -5845,19 +5835,54 @@ dependencies = [
"sha2",
"subtle",
"tracing",
"zcash_address 0.3.2 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_encoding 0.2.0 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_note_encryption",
"zcash_protocol 0.1.1 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_spec",
"zip32",
]
[[package]]
name = "zcash_primitives"
version = "0.17.0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"aes",
"blake2b_simd",
"bs58",
"byteorder",
"document-features",
"equihash 0.2.0 (git+https://github.com/zcash/librustzcash/)",
"ff",
"fpe",
"group",
"hex",
"incrementalmerkletree",
"jubjub",
"memuse",
"nonempty",
"orchard",
"rand 0.8.5",
"rand_core 0.6.4",
"redjubjub",
"sapling-crypto",
"sha2",
"subtle",
"tracing",
"zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_encoding 0.2.1 (git+https://github.com/zcash/librustzcash/)",
"zcash_note_encryption",
"zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_spec",
"zip32",
]
[[package]]
name = "zcash_proofs"
version = "0.15.0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5163a1110f4265cc5f2fdf87ac4497fd1e014b6ce0760ca8d16d8e3853a5c0f7"
checksum = "5b9fc0032b3d90f000f50dba7a996ad6556b7dba5b5145f93ab67b6eb74d3a48"
dependencies = [
"bellman",
"blake2b_simd",
@ -5873,14 +5898,14 @@ dependencies = [
"sapling-crypto",
"tracing",
"xdg",
"zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zcash_protocol"
version = "0.1.1"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f8189d4a304e8aa3aef3b75e89f3874bb0dc84b1cd623316a84e79e06cddabc"
checksum = "f35eac659fdbba614333d119217c5963c0d7cea43aee33176c4f2f95e5460d8d"
dependencies = [
"document-features",
"memuse",
@ -5888,8 +5913,18 @@ dependencies = [
[[package]]
name = "zcash_protocol"
version = "0.1.1"
source = "git+https://github.com/zcash/librustzcash/?branch=main#5a4a3e06dcd2cf5bdf79a7cd48709b58693c65f0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1ff002bd41ba76b42d42a02ee11de06790b7fdbc904bdea4486b9a93b2a5e4"
dependencies = [
"document-features",
"memuse",
]
[[package]]
name = "zcash_protocol"
version = "0.3.0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"document-features",
"memuse",
@ -5916,7 +5951,7 @@ dependencies = [
[[package]]
name = "zebra-chain"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"bitflags 2.6.0",
"bitflags-serde-legacy",
@ -5929,6 +5964,7 @@ dependencies = [
"chrono",
"color-eyre",
"criterion",
"dirs",
"ed25519-zebra",
"equihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures",
@ -5961,25 +5997,26 @@ dependencies = [
"sha2",
"spandoc",
"static_assertions",
"tempfile",
"thiserror",
"tinyvec",
"tokio",
"tracing",
"uint",
"x25519-dalek",
"zcash_address 0.3.2 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_client_backend",
"zcash_encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_client_backend 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_encoding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_history",
"zcash_note_encryption",
"zcash_primitives 0.15.1 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_protocol 0.1.1 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zebra-test",
]
[[package]]
name = "zebra-consensus"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"bellman",
"blake2b_simd",
@ -6025,20 +6062,20 @@ dependencies = [
[[package]]
name = "zebra-grpc"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
dependencies = [
"color-eyre",
"futures-util",
"insta",
"prost 0.13.1",
"prost",
"serde",
"tokio",
"tokio-stream",
"tonic",
"tonic-build 0.12.1",
"tonic-build",
"tonic-reflection",
"tower",
"zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zebra-chain",
"zebra-node-services",
"zebra-state",
@ -6047,7 +6084,7 @@ dependencies = [
[[package]]
name = "zebra-network"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"bitflags 2.6.0",
"byteorder",
@ -6088,7 +6125,7 @@ dependencies = [
[[package]]
name = "zebra-node-services"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"color-eyre",
"jsonrpc-core",
@ -6101,7 +6138,7 @@ dependencies = [
[[package]]
name = "zebra-rpc"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"chrono",
"futures",
@ -6112,7 +6149,7 @@ dependencies = [
"jsonrpc-derive",
"jsonrpc-http-server",
"proptest",
"prost 0.13.1",
"prost",
"rand 0.8.5",
"serde",
"serde_json",
@ -6120,12 +6157,12 @@ dependencies = [
"tokio",
"tokio-stream",
"tonic",
"tonic-build 0.12.1",
"tonic-build",
"tonic-reflection",
"tower",
"tracing",
"zcash_address 0.3.2 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_primitives 0.15.1 (git+https://github.com/zcash/librustzcash/?branch=main)",
"zcash_address 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zebra-chain",
"zebra-consensus",
"zebra-network",
@ -6137,7 +6174,7 @@ dependencies = [
[[package]]
name = "zebra-scan"
version = "0.1.0-alpha.7"
version = "0.1.0-alpha.8"
dependencies = [
"bls12_381",
"chrono",
@ -6167,11 +6204,11 @@ dependencies = [
"tower",
"tracing",
"tracing-subscriber",
"zcash_address 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_client_backend",
"zcash_keys",
"zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_client_backend 0.13.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_keys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_note_encryption",
"zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.17.0 (git+https://github.com/zcash/librustzcash/)",
"zebra-chain",
"zebra-grpc",
"zebra-node-services",
@ -6183,7 +6220,7 @@ dependencies = [
[[package]]
name = "zebra-script"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"hex",
"lazy_static",
@ -6195,7 +6232,7 @@ dependencies = [
[[package]]
name = "zebra-state"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"bincode",
"chrono",
@ -6240,7 +6277,7 @@ dependencies = [
[[package]]
name = "zebra-test"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"color-eyre",
"futures",
@ -6268,10 +6305,11 @@ dependencies = [
[[package]]
name = "zebra-utils"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
dependencies = [
"color-eyre",
"hex",
"indexmap 2.3.0",
"itertools 0.13.0",
"jsonrpc",
"quote",
@ -6288,9 +6326,9 @@ dependencies = [
"tokio",
"tracing-error",
"tracing-subscriber",
"zcash_client_backend",
"zcash_primitives 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_client_backend 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_primitives 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_protocol 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zebra-chain",
"zebra-node-services",
"zebra-rpc",
@ -6298,7 +6336,7 @@ dependencies = [
[[package]]
name = "zebrad"
version = "1.8.0"
version = "1.9.0"
dependencies = [
"abscissa_core",
"atty",
@ -6330,7 +6368,7 @@ dependencies = [
"pin-project",
"proptest",
"proptest-derive",
"prost 0.13.1",
"prost",
"rand 0.8.5",
"rayon",
"regex",
@ -6346,7 +6384,7 @@ dependencies = [
"tokio-stream",
"toml 0.8.19",
"tonic",
"tonic-build 0.12.1",
"tonic-build",
"tower",
"tracing",
"tracing-appender",
@ -6418,3 +6456,28 @@ dependencies = [
"memuse",
"subtle",
]
[[package]]
name = "zip321"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dc85f862f7be64fb0d46f9eb5b82ad54e58cde314fa979d5bae591bc0143693"
dependencies = [
"base64 0.21.7",
"nom",
"percent-encoding",
"zcash_address 0.4.0",
"zcash_protocol 0.2.0",
]
[[package]]
name = "zip321"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash/#a1047adf0b6f324dad415db34762dc26f8367ce4"
dependencies = [
"base64 0.21.7",
"nom",
"percent-encoding",
"zcash_address 0.5.0 (git+https://github.com/zcash/librustzcash/)",
"zcash_protocol 0.3.0 (git+https://github.com/zcash/librustzcash/)",
]

View File

@ -21,6 +21,19 @@ resolver = "2"
# `cargo release` settings
[workspace.dependencies]
incrementalmerkletree = "0.6.0"
orchard = "0.9.0"
sapling-crypto = "0.2.0"
zcash_address = "0.5.0"
zcash_client_backend = "0.13.0"
zcash_encoding = "0.2.1"
zcash_history = "0.4.0"
zcash_keys = "0.3.0"
zcash_primitives = "0.17.0"
zcash_proofs = "0.17.0"
zcash_protocol = "0.3.0"
[workspace.metadata.release]
# We always do releases from the main branch

View File

@ -29,7 +29,10 @@ miner_address = 't27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v'
[network]
network = "Testnet"
[network.testnet_parameters.activation_heights]
# No peers
initial_testnet_peers = []
[network.testnet_parameters]
network_name = "ConfiguredTestnet_1"
# The Testnet network magic is not reserved, but it's not recommended
# for use with incompatible Testnet parameters like those in this config.
@ -69,7 +72,10 @@ miner_address = 't27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v'
[network]
network = "Testnet"
[network.testnet_parameters.activation_heights]
# No peers
initial_testnet_peers = []
[network.testnet_parameters]
# The Mainnet, Testnet, and Regtest network names are reserved.
network_name = "ConfiguredTestnet_2"

View File

@ -37,7 +37,7 @@ docker run -d --platform linux/amd64 \
### Build it locally
```shell
git clone --depth 1 --branch v1.8.0 https://github.com/ZcashFoundation/zebra.git
git clone --depth 1 --branch v1.9.0 https://github.com/ZcashFoundation/zebra.git
docker build --file docker/Dockerfile --target runtime --tag zebra:local .
docker run --detach zebra:local
```

View File

@ -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 v1.8.0
git checkout v1.9.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 v1.8.0 zebrad
cargo install --git https://github.com/ZcashFoundation/zebra --tag v1.9.0 zebrad
```
### Compiling on ARM

View File

@ -58,9 +58,6 @@ skip-tree = [
# wait for `color-eyre` to upgrade
{ name = "owo-colors", version = "=3.5.0" },
# wait for hdwallet to upgrade
{ name = "ring", version = "=0.16.20" },
# wait for structopt upgrade (or upgrade to clap 4)
{ name = "clap", version = "=2.34.0" },
@ -74,13 +71,6 @@ skip-tree = [
# also wait for ron to update insta, and wait for tonic update.
{ name = "base64", version = "=0.13.1" },
# wait for console-subscriber to update tonic.
{ name = "tonic", version = "=0.11.0" },
{ name = "tonic-build", version = "=0.10.2" },
{ name = "axum", version = "=0.6.20" },
{ name = "axum-core", version = "=0.3.4" },
{ name = "hyper-timeout", version = "=0.4.1" },
# wait for elasticsearch to update base64, darling, rustc_version, serde_with
{ name = "elasticsearch", version = "=8.5.0-alpha.1" },
@ -98,10 +88,15 @@ skip-tree = [
{ name = "equihash", version = "=0.2.0" },
{ name = "f4jumble", version = "=0.1.0" },
{ name = "secp256k1", version = "=0.26.0" },
{ name = "zcash_address", version = "=0.3.2" },
{ name = "zcash_encoding", version = "=0.2.0" },
{ name = "zcash_primitives", version = "=0.15.1" },
{ name = "zcash_protocol", version = "=0.1.1" },
{ name = "zcash_address", version = "=0.5.0" },
{ name = "zcash_client_backend", version = "=0.13.0" },
# wait for structopt-derive to update heck
{ name = "heck", version = "=0.3.3" },
# wait for librocksdb-sys to update bindgen to one that uses newer itertools
{ name = "itertools", version = "=0.12.1" }
]
# This section is considered when running `cargo deny check sources`.

View File

@ -19,10 +19,14 @@ ARG FEATURES="default-release-binaries"
ARG TEST_FEATURES="lightwalletd-grpc-tests zebra-checkpoints"
ARG EXPERIMENTAL_FEATURES=""
ARG APP_HOME="/opt/zebrad"
# This stage implements cargo-chef for docker layer caching
FROM rust:bookworm as chef
RUN cargo install cargo-chef --locked
WORKDIR /opt/zebrad
ARG APP_HOME
ENV APP_HOME=${APP_HOME}
WORKDIR ${APP_HOME}
# Analyze the current project to determine the minimum subset of files
# (Cargo.lock and Cargo.toml manifests) required to build it and cache dependencies
@ -38,7 +42,7 @@ RUN cargo chef prepare --recipe-path recipe.json
# We set defaults for the arguments, in case the build does not include this information.
FROM chef AS deps
SHELL ["/bin/bash", "-xo", "pipefail", "-c"]
COPY --from=planner /opt/zebrad/recipe.json recipe.json
COPY --from=planner ${APP_HOME}/recipe.json recipe.json
# Install zebra build deps and Dockerfile deps
RUN apt-get -qq update && \
@ -90,7 +94,7 @@ ARG SHORT_SHA
# https://github.com/ZcashFoundation/zebra/blob/9ebd56092bcdfc1a09062e15a0574c94af37f389/zebrad/src/application.rs#L179-L182
ENV SHORT_SHA=${SHORT_SHA:-}
ENV CARGO_HOME="/opt/zebrad/.cargo/"
ENV CARGO_HOME="${APP_HOME}/.cargo/"
# In this stage we build tests (without running then)
#
@ -128,17 +132,16 @@ RUN cargo chef cook --tests --release --features "${ENTRYPOINT_FEATURES}" --work
# Undo the source file changes made by cargo-chef.
# rsync invalidates the cargo cache for the changed files only, by updating their timestamps.
# This makes sure the fake empty binaries created by cargo-chef are rebuilt.
COPY --from=planner /opt/zebrad zebra-original
COPY --from=planner ${APP_HOME} zebra-original
RUN rsync --recursive --checksum --itemize-changes --verbose zebra-original/ .
RUN rm -r zebra-original
# Build Zebra test binaries, but don't run them
RUN cargo test --locked --release --features "${ENTRYPOINT_FEATURES}" --workspace --no-run
RUN cp /opt/zebrad/target/release/zebrad /usr/local/bin
RUN cp /opt/zebrad/target/release/zebra-checkpoints /usr/local/bin
RUN cp ${APP_HOME}/target/release/zebrad /usr/local/bin
RUN cp ${APP_HOME}/target/release/zebra-checkpoints /usr/local/bin
COPY ./docker/entrypoint.sh /
RUN chmod u+x /entrypoint.sh
COPY ./docker/entrypoint.sh /etc/zebrad/entrypoint.sh
# Entrypoint environment variables
ENV ENTRYPOINT_FEATURES=${ENTRYPOINT_FEATURES}
@ -147,7 +150,7 @@ ARG EXPERIMENTAL_FEATURES="shielded-scan journald prometheus filter-reload"
ENV ENTRYPOINT_FEATURES_EXPERIMENTAL="${ENTRYPOINT_FEATURES} ${EXPERIMENTAL_FEATURES}"
# By default, runs the entrypoint tests specified by the environmental variables (if any are set)
ENTRYPOINT [ "/entrypoint.sh" ]
ENTRYPOINT [ "/etc/zebrad/entrypoint.sh" ]
# In this stage we build a release (generate the zebrad binary)
#
@ -167,29 +170,54 @@ ARG FEATURES
RUN cargo chef cook --release --features "${FEATURES}" --package zebrad --bin zebrad --recipe-path recipe.json
# Undo the source file changes made by cargo-chef, so the fake empty zebrad binary is rebuilt.
COPY --from=planner /opt/zebrad zebra-original
COPY --from=planner ${APP_HOME} zebra-original
RUN rsync --recursive --checksum --itemize-changes --verbose zebra-original/ .
RUN rm -r zebra-original
# Build zebrad
RUN cargo build --locked --release --features "${FEATURES}" --package zebrad --bin zebrad
COPY ./docker/entrypoint.sh /
RUN chmod u+x /entrypoint.sh
COPY ./docker/entrypoint.sh ./
# This stage is only used when deploying nodes or when only the resulting zebrad binary is needed
#
# To save space, this step starts from scratch using debian, and only adds the resulting
# binary from the `release` stage
FROM debian:bookworm-slim AS runtime
COPY --from=release /opt/zebrad/target/release/zebrad /usr/local/bin
COPY --from=release /entrypoint.sh /
# Set the default path for the zebrad binary
ARG APP_HOME
ENV APP_HOME=${APP_HOME}
WORKDIR ${APP_HOME}
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
rocksdb-tools
rocksdb-tools \
gosu \
&& \
rm -rf /var/lib/apt/lists/* /tmp/*
# Create a non-privileged user that the app will run under.
# Running as root inside the container is running as root in the Docker host
# If an attacker manages to break out of the container, they will have root access to the host
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG USER=zebra
ENV USER=${USER}
ARG UID=10001
ENV UID=${UID}
ARG GID=10001
ENV GID=${GID}
RUN addgroup --system --gid ${GID} ${USER} \
&& adduser \
--system \
--disabled-login \
--shell /bin/bash \
--uid "${UID}" \
--gid "${GID}" \
${USER}
# Config settings for zebrad
ARG FEATURES
@ -199,10 +227,16 @@ ENV FEATURES=${FEATURES}
ENV ZEBRA_CONF_DIR=${ZEBRA_CONF_DIR:-/etc/zebrad}
ENV ZEBRA_CONF_FILE=${ZEBRA_CONF_FILE:-zebrad.toml}
RUN mkdir -p ${ZEBRA_CONF_DIR} && chown ${UID}:${UID} ${ZEBRA_CONF_DIR} \
&& chown ${UID}:${UID} ${APP_HOME}
COPY --from=release ${APP_HOME}/target/release/zebrad /usr/local/bin
COPY --from=release ${APP_HOME}/entrypoint.sh /etc/zebrad
# Expose configured ports
EXPOSE 8233 18233
# Update the config file based on the Docker run variables,
# and launch zebrad with it
ENTRYPOINT [ "/entrypoint.sh" ]
ENTRYPOINT [ "/etc/zebrad/entrypoint.sh" ]
CMD ["zebrad"]

View File

@ -362,6 +362,10 @@ case "$1" in
fi
;;
*)
exec "$@"
if command -v gosu >/dev/null 2>&1; then
exec gosu "$USER" "$@"
else
exec "$@"
fi
;;
esac
esac

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "tower-batch-control"
version = "0.2.41-beta.14"
version = "0.2.41-beta.15"
authors = ["Zcash Foundation <zebra@zfnd.org>", "Tower Maintainers <team@tower-rs.com>"]
description = "Tower middleware for batch request processing"
# # Legal
@ -43,10 +43,10 @@ rand = "0.8.5"
tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] }
tokio-test = "0.4.4"
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.14" }
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.15" }
tower-test = "0.4.0"
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.38" }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }

View File

@ -1,6 +1,6 @@
[package]
name = "tower-fallback"
version = "0.2.41-beta.14"
version = "0.2.41-beta.15"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "A Tower service combinator that sends requests to a first service, then retries processing on a second fallback service if the first service errors."
license = "MIT OR Apache-2.0"
@ -24,4 +24,4 @@ tracing = "0.1.39"
[dev-dependencies]
tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.38" }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" }

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-chain"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Core Zcash data structures"
license = "MIT OR Apache-2.0"
@ -68,7 +68,7 @@ bitflags = "2.5.0"
bitflags-serde-legacy = "0.1.1"
blake2b_simd = "1.0.2"
blake2s_simd = "1.0.2"
bridgetree = "0.4.0"
bridgetree = "0.5.0"
bs58 = { version = "0.5.1", features = ["check"] }
byteorder = "1.5.0"
@ -78,9 +78,11 @@ byteorder = "1.5.0"
equihash = "0.2.0"
group = "0.13.0"
incrementalmerkletree = "0.5.1"
incrementalmerkletree.workspace = true
jubjub = "0.10.0"
lazy_static = "1.4.0"
tempfile = "3.11.0"
dirs = "5.0.1"
num-integer = "0.1.46"
primitive-types = "0.12.2"
rand_core = "0.6.4"
@ -93,17 +95,14 @@ x25519-dalek = { version = "2.0.1", features = ["serde"] }
# ECC deps
halo2 = { package = "halo2_proofs", version = "0.3.0" }
orchard = "0.8.0"
zcash_encoding = "0.2.0"
zcash_history = "0.4.0"
orchard.workspace = true
zcash_encoding.workspace = true
zcash_history.workspace = true
zcash_note_encryption = "0.4.0"
# TODO: Revert to a release once librustzcash is released (#8749).
zcash_primitives = { git = "https://github.com/zcash/librustzcash/", branch = "main", features = ["transparent-inputs"] }
sapling = { package = "sapling-crypto", version = "0.1" }
# TODO: Revert to a release once librustzcash is released (#8749).
zcash_protocol = { git = "https://github.com/zcash/librustzcash/", branch = "main"}
# TODO: Revert to a release once librustzcash is released (#8749).
zcash_address = { git = "https://github.com/zcash/librustzcash/", branch = "main"}
zcash_primitives = { workspace = true, features = ["transparent-inputs"] }
sapling-crypto.workspace = true
zcash_protocol.workspace = true
zcash_address.workspace = true
# Time
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
@ -137,7 +136,7 @@ serde_json = { version = "1.0.122", optional = true }
tokio = { version = "1.39.2", optional = true }
# Experimental feature shielded-scan
zcash_client_backend = { version = "0.12.1", optional = true }
zcash_client_backend = { workspace = true, optional = true }
# Optional testing dependencies
proptest = { version = "1.4.0", optional = true }
@ -146,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.38", optional = true }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39", optional = true }
[dev-dependencies]
# Benchmarks
@ -169,7 +168,7 @@ rand_chacha = "0.3.1"
tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.38" }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" }
[[bench]]
name = "block"

View File

@ -14,7 +14,7 @@ pub mod mock;
#[cfg(test)]
mod tests;
use network_chain_tip_height_estimator::NetworkChainTipHeightEstimator;
pub use network_chain_tip_height_estimator::NetworkChainTipHeightEstimator;
/// An interface for querying the chain tip.
///

71
zebra-chain/src/common.rs Normal file
View File

@ -0,0 +1,71 @@
//! Common functions used in Zebra.
use std::{
ffi::OsString,
fs,
io::{self, Write},
path::PathBuf,
};
use tempfile::PersistError;
/// Returns Zebra's default cache directory path.
pub fn default_cache_dir() -> PathBuf {
dirs::cache_dir()
.unwrap_or_else(|| std::env::current_dir().unwrap().join("cache"))
.join("zebra")
}
/// Accepts a target file path and a byte-slice.
///
/// Atomically writes the byte-slice to a file to avoid corrupting the file if Zebra
/// panics, crashes, or exits while the file is being written, or if multiple Zebra instances
/// try to read and write the same file.
///
/// Returns the provided file path if successful.
///
/// # Concurrency
///
/// This function blocks on filesystem operations and should be called in a blocking task
/// when calling from an async environment.
///
/// # Panics
///
/// If the provided `file_path` is a directory path.
pub fn atomic_write(
file_path: PathBuf,
data: &[u8],
) -> io::Result<Result<PathBuf, PersistError<fs::File>>> {
// Get the file's parent directory, or use Zebra's default cache directory
let file_dir = file_path
.parent()
.map(|p| p.to_owned())
.unwrap_or_else(default_cache_dir);
// Create the directory if needed.
fs::create_dir_all(&file_dir)?;
// Give the temporary file a similar name to the permanent file,
// but hide it in directory listings.
let mut tmp_file_prefix: OsString = ".tmp.".into();
tmp_file_prefix.push(
file_path
.file_name()
.expect("file path must have a file name"),
);
// Create the temporary file in the same directory as the permanent file,
// so atomic filesystem operations are possible.
let mut tmp_file = tempfile::Builder::new()
.prefix(&tmp_file_prefix)
.tempfile_in(file_dir)?;
tmp_file.write_all(data)?;
// Atomically write the temp file to `file_path`.
let persist_result = tmp_file
.persist(&file_path)
// Drops the temp file and returns the file path.
.map(|_| file_path);
Ok(persist_result)
}

View File

@ -22,6 +22,7 @@ pub mod amount;
pub mod block;
pub mod chain_sync_status;
pub mod chain_tip;
pub mod common;
pub mod diagnostic;
pub mod error;
pub mod fmt;

View File

@ -41,7 +41,7 @@ impl From<Network> for NetworkKind {
}
/// An enum describing the possible network choices.
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
#[derive(Clone, Default, Eq, PartialEq, Serialize)]
#[serde(into = "NetworkKind")]
pub enum Network {
/// The production mainnet.
@ -121,6 +121,22 @@ impl fmt::Display for Network {
}
}
impl std::fmt::Debug for Network {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Mainnet => write!(f, "{self}"),
Self::Testnet(params) if params.is_regtest() => f
.debug_struct("Regtest")
.field("activation_heights", params.activation_heights())
.finish(),
Self::Testnet(params) if params.is_default_testnet() => {
write!(f, "{self}")
}
Self::Testnet(params) => f.debug_tuple("ConfiguredTestnet").field(params).finish(),
}
}
}
impl Network {
/// Creates a new [`Network::Testnet`] with the default Testnet [`testnet::Parameters`].
pub fn new_default_testnet() -> Self {

View File

@ -69,23 +69,33 @@ pub enum FundingStreamReceiver {
impl FundingStreamReceiver {
/// Returns a human-readable name and a specification URL for the receiver, as described in
/// [ZIP-1014] and [`zcashd`].
/// [ZIP-1014] and [`zcashd`] before NU6. After NU6, the specification is in the [ZIP-lockbox].
///
/// [ZIP-1014]: https://zips.z.cash/zip-1014#abstract
/// [`zcashd`]: https://github.com/zcash/zcash/blob/3f09cfa00a3c90336580a127e0096d99e25a38d6/src/consensus/funding.cpp#L13-L32
// TODO: Update method documentation with a reference to https://zips.z.cash/draft-nuttycom-funding-allocation once its
// status is updated to 'Proposed'.
pub fn info(&self) -> (&'static str, &'static str) {
(
match self {
FundingStreamReceiver::Ecc => "Electric Coin Company",
FundingStreamReceiver::ZcashFoundation => "Zcash Foundation",
FundingStreamReceiver::MajorGrants => "Major Grants",
// TODO: Find out what this should be called and update the funding stream name
FundingStreamReceiver::Deferred => "Lockbox",
},
FUNDING_STREAM_SPECIFICATION,
)
/// [ZIP-lockbox]: https://zips.z.cash/draft-nuttycom-funding-allocation#alternative-2-hybrid-deferred-dev-fund-transitioning-to-a-non-direct-funding-model
pub fn info(&self, is_nu6: bool) -> (&'static str, &'static str) {
if is_nu6 {
(
match self {
FundingStreamReceiver::Ecc => "Electric Coin Company",
FundingStreamReceiver::ZcashFoundation => "Zcash Foundation",
FundingStreamReceiver::MajorGrants => "Zcash Community Grants NU6",
FundingStreamReceiver::Deferred => "Lockbox NU6",
},
LOCKBOX_SPECIFICATION,
)
} else {
(
match self {
FundingStreamReceiver::Ecc => "Electric Coin Company",
FundingStreamReceiver::ZcashFoundation => "Zcash Foundation",
FundingStreamReceiver::MajorGrants => "Major Grants",
FundingStreamReceiver::Deferred => "Lockbox NU6",
},
FUNDING_STREAM_SPECIFICATION,
)
}
}
}
@ -94,12 +104,16 @@ impl FundingStreamReceiver {
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100;
// TODO: Update the link for post-NU6 funding streams.
/// The specification for all current funding stream receivers, a URL that links to [ZIP-214].
/// The specification for pre-NU6 funding stream receivers, a URL that links to [ZIP-214].
///
/// [ZIP-214]: https://zips.z.cash/zip-0214
pub const FUNDING_STREAM_SPECIFICATION: &str = "https://zips.z.cash/zip-0214";
/// The specification for post-NU6 funding stream and lockbox receivers, a URL that links to [ZIP-lockbox].
///
/// [ZIP-lockbox]: https://zips.z.cash/draft-nuttycom-funding-allocation#alternative-2-hybrid-deferred-dev-fund-transitioning-to-a-non-direct-funding-model
pub const LOCKBOX_SPECIFICATION: &str = "https://zips.z.cash/draft-nuttycom-funding-allocation#alternative-2-hybrid-deferred-dev-fund-transitioning-to-a-non-direct-funding-model";
/// Funding stream recipients and height ranges.
#[derive(Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct FundingStreams {
@ -278,7 +292,7 @@ const POST_NU6_FUNDING_STREAM_START_HEIGHT_MAINNET: u32 = 2_726_400;
/// The start height of post-NU6 funding streams on Testnet
// TODO: Add a reference to lockbox stream ZIP, this is currently based on https://zips.z.cash/draft-nuttycom-funding-allocation
const POST_NU6_FUNDING_STREAM_START_HEIGHT_TESTNET: u32 = 2_942_000;
const POST_NU6_FUNDING_STREAM_START_HEIGHT_TESTNET: u32 = 2_976_000;
/// The number of blocks contained in the post-NU6 funding streams height ranges on Mainnet or Testnet.
const POST_NU6_FUNDING_STREAM_NUM_BLOCKS: u32 = 420_000;

View File

@ -125,8 +125,7 @@ pub(super) const TESTNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)]
(block::Height(903_800), Heartwood),
(block::Height(1_028_500), Canopy),
(block::Height(1_842_420), Nu5),
// TODO: Add NU6
// (block::Height(2_942_000), Nu6),
(block::Height(2_976_000), Nu6),
];
/// Fake testnet network upgrade activation heights, used in tests.

View File

@ -17,7 +17,7 @@ pub enum Address {
network: NetworkKind,
/// Sapling address
address: sapling::PaymentAddress,
address: sapling_crypto::PaymentAddress,
},
/// Unified address
@ -32,7 +32,7 @@ pub enum Address {
orchard: Option<orchard::Address>,
/// Sapling address
sapling: Option<sapling::PaymentAddress>,
sapling: Option<sapling_crypto::PaymentAddress>,
/// Transparent address
transparent: Option<transparent::Address>,
@ -68,7 +68,7 @@ impl zcash_address::TryFromAddress for Address {
data: [u8; 43],
) -> Result<Self, zcash_address::ConversionError<Self::Error>> {
let network = network.into();
sapling::PaymentAddress::from_bytes(&data)
sapling_crypto::PaymentAddress::from_bytes(&data)
.map(|address| Self::Sapling { address, network })
.ok_or_else(|| BoxError::from("not a valid sapling address").into())
}
@ -97,7 +97,7 @@ impl zcash_address::TryFromAddress for Address {
}
}
unified::Receiver::Sapling(data) => {
sapling = sapling::PaymentAddress::from_bytes(&data);
sapling = sapling_crypto::PaymentAddress::from_bytes(&data);
// ZIP 316: Consumers MUST reject Unified Addresses/Viewing Keys in
// which any constituent Item does not meet the validation
// requirements of its encoding.

View File

@ -1,6 +1,6 @@
//! Defines types and implements methods for parsing Sapling viewing keys and converting them to `zebra-chain` types
use sapling::keys::{FullViewingKey as SaplingFvk, SaplingIvk};
use sapling_crypto::keys::{FullViewingKey as SaplingFvk, SaplingIvk};
use zcash_client_backend::{
encoding::decode_extended_full_viewing_key,
keys::sapling::DiversifiableFullViewingKey as SaplingDfvk,

View File

@ -25,19 +25,19 @@ pub fn decrypts_successfully(transaction: &Transaction, network: &Network, heigh
)
.expect("zcash_primitives and Zebra transaction formats must be compatible");
let null_sapling_ovk = sapling::keys::OutgoingViewingKey([0u8; 32]);
let null_sapling_ovk = sapling_crypto::keys::OutgoingViewingKey([0u8; 32]);
// Note that, since this function is used to validate coinbase transactions, we can ignore
// the "grace period" mentioned in ZIP-212.
let zip_212_enforcement = if network_upgrade >= NetworkUpgrade::Canopy {
sapling::note_encryption::Zip212Enforcement::On
sapling_crypto::note_encryption::Zip212Enforcement::On
} else {
sapling::note_encryption::Zip212Enforcement::Off
sapling_crypto::note_encryption::Zip212Enforcement::Off
};
if let Some(bundle) = alt_tx.sapling_bundle() {
for output in bundle.shielded_outputs().iter() {
let recovery = sapling::note_encryption::try_sapling_output_recovery(
let recovery = sapling_crypto::note_encryption::try_sapling_output_recovery(
&null_sapling_ovk,
output,
zip_212_enforcement,

View File

@ -84,31 +84,40 @@ impl<'a>
struct IdentityMap;
impl zp_tx::components::sapling::MapAuth<sapling::bundle::Authorized, sapling::bundle::Authorized>
for IdentityMap
impl
zp_tx::components::sapling::MapAuth<
sapling_crypto::bundle::Authorized,
sapling_crypto::bundle::Authorized,
> for IdentityMap
{
fn map_spend_proof(
&mut self,
p: <sapling::bundle::Authorized as sapling::bundle::Authorization>::SpendProof,
) -> <sapling::bundle::Authorized as sapling::bundle::Authorization>::SpendProof {
p: <sapling_crypto::bundle::Authorized as sapling_crypto::bundle::Authorization>::SpendProof,
) -> <sapling_crypto::bundle::Authorized as sapling_crypto::bundle::Authorization>::SpendProof
{
p
}
fn map_output_proof(
&mut self,
p: <sapling::bundle::Authorized as sapling::bundle::Authorization>::OutputProof,
) -> <sapling::bundle::Authorized as sapling::bundle::Authorization>::OutputProof {
p: <sapling_crypto::bundle::Authorized as sapling_crypto::bundle::Authorization>::OutputProof,
) -> <sapling_crypto::bundle::Authorized as sapling_crypto::bundle::Authorization>::OutputProof
{
p
}
fn map_auth_sig(
&mut self,
s: <sapling::bundle::Authorized as sapling::bundle::Authorization>::AuthSig,
) -> <sapling::bundle::Authorized as sapling::bundle::Authorization>::AuthSig {
s: <sapling_crypto::bundle::Authorized as sapling_crypto::bundle::Authorization>::AuthSig,
) -> <sapling_crypto::bundle::Authorized as sapling_crypto::bundle::Authorization>::AuthSig
{
s
}
fn map_authorization(&mut self, a: sapling::bundle::Authorized) -> sapling::bundle::Authorized {
fn map_authorization(
&mut self,
a: sapling_crypto::bundle::Authorized,
) -> sapling_crypto::bundle::Authorized {
a
}
}
@ -135,7 +144,7 @@ struct PrecomputedAuth<'a> {
impl<'a> zp_tx::Authorization for PrecomputedAuth<'a> {
type TransparentAuth = TransparentAuth<'a>;
type SaplingAuth = sapling::bundle::Authorized;
type SaplingAuth = sapling_crypto::bundle::Authorized;
type OrchardAuth = orchard::bundle::Authorized;
}

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-consensus"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Implementation of Zcash consensus checks"
license = "MIT OR Apache-2.0"
@ -57,19 +57,19 @@ tower = { version = "0.4.13", features = ["timeout", "util", "buffer"] }
tracing = "0.1.39"
tracing-futures = "0.2.5"
sapling = { package = "sapling-crypto", version = "0.1" }
orchard = "0.8.0"
sapling-crypto.workspace = true
orchard.workspace = true
zcash_proofs = { version = "0.15.0", features = ["multicore" ] }
zcash_proofs = { workspace = true, features = ["multicore" ] }
wagyu-zcash-parameters = "0.2.0"
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.14" }
tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.14" }
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.15" }
tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.15" }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.38" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.38" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38" }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.39" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" }
# prod feature progress-bar
howudoin = { version = "0.1.2", optional = true }
@ -94,6 +94,6 @@ tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] }
tracing-error = "0.2.0"
tracing-subscriber = "0.3.18"
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.38" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" }

View File

@ -12003,3 +12003,177 @@
2554806 00000000016705413d89359fda1bbd5ce6f00a1b240dd5ccc6c351612f13f384
2555206 00000000006deca2d2e148123205b01669e8b6fa7e8b28f57f7f85a0f5c960a6
2555606 0000000000ea2725768e667ae4cd5b04242b8b5cc6496424f4bb35f81bb6dd76
2556006 000000000047510e7d7cb07beb6ad4a4bd83a615fc7a478bb3825b15332bc9bd
2556406 00000000015b21f4eb730501003e9daa0a98dbf56c4dc3da2502c6ac26b94c2b
2556806 0000000000d812e01e5ddb870cc4523d8401fa555efa653ee9248bb5b494a62e
2557206 000000000195537e950f6fda73e029ee4dc107fd368fcd7da598b0d0ca0138bb
2557606 0000000001765e529944fa91d5d055860420a17ae1e98bb630799bc50ffc72f2
2558006 00000000007a0bb239cbbfd12018653ff2f277feee900f40589f5901ea20f938
2558406 000000000077206532c343f65b65cd6843bf4a78222627bb6f660178c2db6bbe
2558806 0000000001d2e2a8650dfab2a0ed241f768a26663e8013991ae428a20d359337
2559206 00000000018aa28a1355134f21da7636d43c268ea0d66e6a748546e0299f4089
2559606 000000000211667b2a47f5176e5ef95f172b1df8bb456fe3da51b30b3e3999d5
2560006 0000000001a91e3907c5614420b5df79ed0c2ba71336109d292160fc8487c52e
2560406 00000000005770a5389a8bea95c509c41a05c48f00d9f7ba568137dff315524a
2560806 0000000000916b043f75125f104d30727d5906726c1dc2c0a74682adc5316410
2561206 00000000023008f24d4e285b8a761bade4def4eb0abf6a9cd049d92ee178f855
2561606 0000000000cd710e9e6587a2c2387987bee5366cc87b5d37f014732d7a9ffdd7
2562006 0000000000cf179db6d24a2cf9bb274bfb1ba33d570761b0ed3411a722c5649d
2562406 00000000016da4ef0a959ed31f7ae3c10c6c42526d10ab3110b7633bfbd00215
2562806 0000000001ef4ef1800106006f6da60720cbdd1e107656aa60d0c9cde3fae0e9
2563206 0000000001b128c91d16f28869c6791747752aa73380fb515b646968cbab60a8
2563606 0000000000541a9a127937e783e1b62cbe3b5fcdeaf8d1f85a6f115ac3881eb8
2564006 000000000196628e0b80be76ee3c3d24a093910117ea2fb327ce7843d29f03aa
2564406 00000000006ca8aa23a33b8f18da6d596dd5afc9086669070f8decbf65df3796
2564806 000000000199d65e7c6eea0559c44890a54641b0d9e16a25b2b8ca62feaa1684
2565206 00000000012e0a1d7de833222fea66e0327726ce7dd36a8f99070b4420343bb5
2565606 000000000272607bb502258fb726d30bbf1511a8485d7d60a27be1e4665e8f12
2566006 00000000016931e0e4c2bc9bbd6b99495e6025d4032e3e3924a1b6de5cd43339
2566406 00000000015073f614abe93a6c6c6e05e4b7adcb9db849aa733e1a1be3053235
2566806 00000000019d3ba1caaa9b97449016e272f9a77ef10ef687cdd071d55081f16f
2567206 0000000000c42493635befd101ec8c62bf062793eea52fb10e2aa60da25d15cf
2567606 000000000157e37fc4cbcb272082b458bf28441f467b5c082526f2d73f38f626
2568006 0000000001735160af2a7e95bc71e778edb44aec0ba6af47197efa93e8af8fc2
2568406 0000000000784e87c479d8c2a22e2389763de85a4e9987b038e79e34f9569d9a
2568806 0000000000186de15449a02d8fd01e8234a18a41fd7a58da04f9e4692dfdaff3
2569206 0000000000e864da6e198bbfc9b5a832c3e221037945f0bce593ed190e5e707c
2569606 0000000001333eb5365d3d8495a0b74a84990fc1dba400e0bda094396758591f
2570006 0000000000a2429e0bb110449a893dd56d0bf614abf1c3a569fb6a9780cdafb7
2570406 00000000024565125a7ba36b2620e71fd082f2cdf6bb11ec5ee16f08c29b6264
2570806 0000000001f49c56ba49c33d3010fe79f6a7b6cd79a2483d5c4c791b4722fa9d
2571206 0000000000db5ae649dfd341b4f45825915ec995cf08b0a6ce9702b6d0ce52c7
2571606 00000000022d787127e69dddbe808d61344e986cc89ae616b56ae7579941d8c8
2572006 0000000001e04170d182c11c8859ae4fca9f81a1f375fd32f35af376530bc857
2572406 00000000014b75fea1aad4cdafc640bb9fc54b0536a7e007171739f83345f016
2572806 00000000006fe5cec0bb38840965e56ae3d70c03c098d77754e2532ac1b87cc9
2573206 0000000000a6fcd59c798a6257966ff80125701d14167991cd10142a47bb5fde
2573606 0000000000fae67986e605e11ab03ca95aa5d11a73774df329971325816dcfa7
2574006 0000000001ec509b09987424a078e786dba7ec8bcb9de822b03593940aec491b
2574406 0000000001c7606146d50559493f818b31ad0ca09190c9baae6694da0e2634fa
2574806 00000000005c63b5c7a625266e3f27f4e9c404e2219c8b92bffb4e73bfdcc0cc
2575206 00000000006a9855a5d3de316568ad710d1b6b70f6c55757ad9d3b71eee94bc7
2575606 000000000298a22da35364c0ee3df566d5fa9ccf16fb3b163fd46d6cbee9dfb7
2576006 000000000002702215681bef5f6a960e7ba79b2f287ad48248f837be2f31d10e
2576406 0000000001f5e4c2b385d3630b055b0d287ab4e841ff00042da94849fd60564b
2576806 000000000191e611af854dcf0b6ebfa5c3159271a4a94651b4363593cfca33ed
2577206 0000000002155d31b583b34b894a7be491a8186300d9d2121f66c814e0e93ed1
2577606 000000000054309e0b93811cc29a4f101390c4d22952ff353303b245183b7a6e
2578006 000000000143c1fc0de21b04acebc86591c2877909ec868e50248bd3f001c6ab
2578406 0000000000dd9293af11fc84a607a9c570e1331b879735b45757d7e8d580b488
2578806 00000000015a2bd76829590fe23e8be857a3695e0f2bd2b80ff144484b974f35
2579206 000000000274abf40d8b7252ab543a843e62a013d434d48652082f71f4c74d52
2579606 00000000021a597eff61514fac998591a99a3b176cd81bfe19e16989408d0f44
2580006 0000000000677125aa3b700abab625a90eec06da77006759115a027740306317
2580406 000000000066c0b1ac89749ea6bf34f596b9fdbaf7c6b40b19acee62c95fe7c3
2580806 0000000000115800ac97dd7a797737f7deae1c8c02c9dcd7c5cb1eee9b4f1424
2581206 0000000001869a9a674255aeca82801de76db5d7486c93e406a0bfc5e1cea876
2581606 00000000011f2aa0cac6cd316d61c5ced8ccfd2731ac70ac84b3eb0b56fd281c
2582006 000000000019344b1f3d0ff23359cf95a0ee38fe972ad1d125b72d39989f5633
2582406 0000000001c286c9afb815abb38e20dd30d668a3f1fc9fd1eff8bd95a4d9d1c2
2582806 00000000017bf8b414e3609ad384c2fe3e3391486bf60b5542195b1765fd1d6b
2583206 0000000001f2aa4cbb7e74bafa3716369acc5334117745efe4b90c95bed04eb5
2583606 0000000001d4445fe5120eb1dc67f16d7eb083172b462f93325d24816bc71923
2584006 000000000186e58af046355631bc148c37bb0ba81b4a0e15071f75bdc62728d5
2584406 000000000173f5341c8cf916ea61754e34797a474ddc95ee4ea9884b6d858cdb
2584806 00000000004e6ba1bfbd171a404629e39ff37d145004f4f441f288abeed3376d
2585206 0000000000feea225c57f84ddc2fee78917329d38d77f2137d43b28438d2c041
2585606 00000000017565ebf067008b7130a06ed66b9e68b705f19cc0e97a38e29781d2
2586006 0000000001cdd77eccbde504a214906b298d3e4a3754dc88ad0a750bd4c6c481
2586406 00000000006044fc637351331794a167a8ec6fd64385bf9c4209735b7e1608fb
2586806 00000000014b3a50923500109df4e99b4e41e154e34b0411f897ef4a70e2ad77
2587206 0000000000142e39073661568fa39d5f5fd18336b8d5a80283c0f2b546091f9e
2587606 000000000234f4c6afdef7e5fa4750960d1daa6a450015073a294956fa743766
2588006 000000000067a2b25afd742dcfd647c152a99e2104c2fd6bdd83517a8fdbf3da
2588406 000000000187192af13249e9c935b36fb8a88c9b949db96918dbdb33835269fc
2588806 00000000005d90be6ad7bf3934f8a415080512b0b2cc0045f9c3dc2d6dcbcdeb
2589206 00000000002f7df49c3f9f266240a2dab7ed6e98fb5d565442718af20c04222a
2589606 00000000017d1baedf0507e9f52b215b1d73dbe57fdd7b1a35b211e545b41bcf
2590006 0000000000b97f0bd8e83a9e5b708ecf204b91ff2325cd20b013bc6f02644701
2590406 000000000044f0e8df41dbe5085d0077a0bfdec95c831b5f5b6af0234ffe29b9
2590806 00000000013abf3f2adbedc36b789f928f2c74d18c6e8adf06c97cb677f14604
2591206 000000000179ce68445647c97a424eb6da5c5720323cddf4862a59b1a43ea1ac
2591606 00000000011aa4824411350e09aec1a088d8a011a599fd64be8e6b322112e7d1
2592006 00000000009c5654283430066d751c9d8502d4eb832ace2e43dff7c684ad076a
2592406 0000000000fb2b2b2294951b64cf1d18418d3aa9837e76e3721e91b1a47188cb
2592806 0000000001f46a8c7bf8b8dc9dbe12508da45519661c5ee0971b69a9e8ca1920
2593206 0000000000affb807c307b105a4fcee33b13b74cfcaf7081c1d117b33ee8030e
2593606 0000000001b692d02d5a5008399d4291e0b5d050bc2fc693265769eb7878e2ff
2594006 0000000000561541970cd1ec5024b93580f3be27893ca15585874daf3dd1f0f7
2594406 000000000173a227b35b331ff5a9f877bf7e1d18758c90c37baa530a28a9f7d9
2594806 0000000002155d8008f425d750445d223fe180fdaa80fd40950d58791e58160a
2595206 0000000001dc600336a001d7e70056d17eebfc32be78c906e8c490eee0b45eb7
2595606 0000000001baef516feabbc2208bfcff9db382d4e3d4137cb7cfbc5c418a42e7
2596006 00000000019b899a51b1ddfdd1b26b7acb3ebbb2a0824c3bfe2fa3dada1023e1
2596406 0000000000b3dcc069a465cca2abbbf65301bf38801e9bc95f5b78c48c2c6ae1
2596806 00000000015c3914712639d7f9a9889e7d2e30361adb8175e0ceb51cdd681572
2597206 00000000002320a84b900ce88677f3fe59c83bc1763606d03d1ebe6d2855e463
2597606 000000000272aa75293cc26882e5c5ba40cec06d99ae5b678a0a3252c4babb3f
2598006 000000000044f5f21d64c9090d432e447b52cd9fba6400cd56efcb287ecac367
2598406 0000000000eb27d3ed855fd4d6069849a1c3014dee117ecb4dee7625ad71e02b
2598806 0000000000b7a2b91d2d0929558803f4e458b9f7ba6479521a78323409be3e6b
2599206 0000000001a2c91f6d7966a4b2321a144ad4385511d6d4d8f5ff055392e2f797
2599606 0000000000633495c9daa43226059f4af43e3be3cfc576281f75fb016c6df6d8
2600006 000000000030c03e51ef5825a77973d0eccd996f78103a2d207a8298080eb131
2600406 0000000001c1519359cfac66f287809573c1d9fa4e277583415ba042d6ddf9d5
2600806 000000000148c4b04a3a465f46bb08e13c4606f1b936e9ba24395e686ecea3a5
2601206 000000000122cec31e85e32bfe8b79b1e04d09f5f712715eed91da9660083955
2601606 000000000148f7b483dfbc188005466ddb0d65b8ec7eaf74c425d7b240458d4a
2602006 00000000014fe5f8aa4db10d032ad90d0a25d71c0f4ba415beb932cecc7c21e2
2602406 000000000127dbadd2631ad6bec7d7b9c3d7f8ee884d980b91f36d8b814acc9f
2602806 0000000001487e70aaddad412bf3d70ed60fb18c4b9eaf2497b01f7cdf5f086d
2603206 00000000015e96c47df427948e5969d789dac2d685f5a0c71fa114ba60bc0453
2603606 0000000001dc00de19f00ad6a3d2d3bab49a6fbbd11efac6a35e609b6c8d0c4b
2604006 0000000000db122c58ebed2ed8c534aff155845f1e2c4f3aa298f5f3f7ec4dc1
2604406 0000000000970923a0594518f07e8278d5d66f3b9ba44eae665c20ded7478c37
2604806 0000000001de81f421cd242411e1c7a7c1f14228a48748f4ce6936660e2c7e22
2605206 0000000000c2432428b4d7014e400fcfd974e5c6ff56ca9d3eff05868b0620d0
2605606 00000000005626fae38ad7a689349a3802206fe2348fa2f1cdc1f9f44ea0e097
2606006 0000000000ece0f9651c83b1c1a3a41adf098158abaa5e9119221dc16d0f2a8d
2606406 0000000001f2fc83def6d4ea7695bff2b19c965cfe2238f4e54f95c9d14b80dd
2606806 0000000001d377420782d222435e1597d3d5d31b9748481359de9954910f0692
2607206 0000000000b1ad584a3e79cdede18b299fc1b0670d610691c389b82a8593a7bd
2607606 0000000001766a78e70e60730eac06b83e38f8d3b6613ad1ef2cb8d9e1d44e52
2608006 000000000044d146c83d1b617d575bf67702bfbabaf88d4d0672d6c99e0121dc
2608406 00000000014498a6c0ecaf47fa2333d8d07cfc191385de7dfeb0bb0564cda465
2608806 000000000038deb19a8f2ba01890d120fa101fcd7a97c026ef06c0b71020d9d0
2609206 0000000000833755db525c6a9a0cd7687584d34c485ee920c6e341b7e732601c
2609606 0000000000dd6907126037e8b36dd68edc55dc0fa8b84b720468896f2b69bf20
2610006 00000000000ad390d032aa87d7951e1d303c906c87888887980b1b71e7d4b902
2610406 0000000000709c32b978ed86ddac1f33ddbadfdb29a759fa6dfb4999a5451987
2610806 000000000014d3508e2e8e69dfefc5d4e1ee566391e4a6f488ffb5e9ba5e2b31
2611206 00000000020da1eba14537ed0d5b3d36f3c817cd502c86ac256352c00fec2fe4
2611606 00000000005a01941c571a0f8f85caaefdc7607478bb26b13d4a9c5669af40f2
2612006 0000000000f926ee91c5f2bdecbafd8ab6263b6b4c0fc7b550d6d4318a6bac16
2612406 000000000032197eb9022dd14f99b9d8af98ca637843b751e8ed6f68d3198e99
2612806 0000000000f13e3e00b5c0a2261ab6a2f44ceef9b525d2de9be7b8c8f5afe800
2613206 00000000007f39c4d1a05f20ad9a4e1a9540ac5cd0383adf214d2de857a84dda
2613606 0000000000ddc69035b2989c937c1a92ab76d30b27086586c2ea2c986cd9ceb1
2614006 000000000029aa1adb9ec4f112dd347987641131d9279b5ddab7615fd8f57a03
2614406 00000000011298cb3f3dbe0528d9e93796d72168384b1e6034c949a193a51411
2614806 000000000163b9208d79f6cd36141424fcb6a9ea7590052845a51be79956c024
2615206 0000000001c34e49ce889a83d4c850d5a2dcaa7f62b0a707f0138c75e0aa9188
2615606 0000000001786b9f91842f119a9f0e56004405613f2d5f14e7bd15254634d72e
2616006 000000000033badff5a3aa7080bb5f6141e18ac8b0d46e6832c86929b9bd0235
2616406 0000000000b4f4350bb84e3edf11fd0c5c851186b974492e0874d8ed7965f33c
2616806 00000000018c22644f1f4397a739d09648262583f7abb42354b16811ade7b531
2617206 000000000114304e77b54eafc3673d9b64437b45dffe43ecf5bfda5e8395fe54
2617606 0000000001d38509d3589516030934eb349d7af1ab021ed48cdfab17248c66bd
2618006 0000000001a0a5a6abd1e1945109c658ed459541a2a2ede4cebb1ae08b01570b
2618406 000000000079eae586cfd59450d550658baae250ade4ae7d2b7be9473de305e5
2618806 0000000000cb2cc6d7a27fee3724f9b60b40742a0b9969844401a9e868582487
2619206 00000000011807b4374bd26d8f9e4a1ec24cddab4dcb9579f7d2a7d4732be39a
2619606 0000000001b0931affede8ca7e2d66d9982542187a1931d8ab7da037b4bf1267
2620006 00000000005b621e471193e2fa64d64f514cb6d62f3ccecc687748834aeff72e
2620406 000000000025375333bac4a59c4fd76557cac23e76e6ed4f20e1e5c267561ab2
2620806 000000000047c4b9f611309ef80c5eeb8762049874a0ef6a5d05cd006eb41974
2621206 00000000002cf32fa89b270bb11014dddc8f27cf4a0e3ce8ca7e2304fd915dd6
2621606 0000000001394fc4c445cfe8ae7dc38ea9d9d04af8f240f2f25dba2354a6b5a7
2622006 0000000001d75084068aa3c8f7818e9a9e8e979a7290a95157263278e303424a
2622406 0000000001244aa2424807f43926d157862d48add8a21f6e7ecf1ec332fc6ab0
2622806 000000000059dd31cca67bf0a520ee0d0bd15e8447badb8db2fcff8133911d08
2623206 000000000118c15229aa1595638cc2128765d8a31eedf7832f6877a9d436ea4f
2623606 0000000000ec3a853c84a4d18f0b6be84029dc1dd27e14b1a4ea709ca675be2f
2624006 0000000001b9f3f4fe7b3fad85439b4190d329482461c12a89c4633fce4043e1
2624406 0000000000d8c3a66ac5a0a8c3938f27537b734c7f35a5b6c4c9f3e9ef029cd8
2624806 00000000014e4268c9a2190fd52e4da77f6a887b966846d8f25aa6948a64d7a8
2625206 0000000000e70fb2297446280d68e7263e155c548ce47c9eafa2ebb55ec35a98

View File

@ -7234,3 +7234,203 @@
2893200 0055c8d1074a89c97abccb41bf82ba2307dac8871c4665e2e3827cff9f6ca6c7
2893600 0012c459769cc0a5326a1fe80b9bd4eb497554961f6d52267807dccaeb3214a1
2894000 00291716835bebdcddcadaa93a697c8e074ea7eebb5970fc4488606b700fd741
2894400 0013897f50a933792b0c855978103e6709098868b1dbdea0ece528420723d4b0
2894800 002798d892824e7dd4728d2caea11fcd2e88b85348bf082011c2d0dc9047446e
2895200 002ed87e8a3f73a2e2b04042a7cc65ae321e34e45ce62a2254d4339a0032e5a7
2895600 0019993d82ebfdda3186d099981732e3b3da344f71771477cf1c246fc5cddd54
2896000 003ac77668cb97a2794a1c84bcf964e1067f819bf681f0581632fa408722bca2
2896400 000eba3d5e5b116704a813d19a57ae212f9ddd601cd6eb30c1031018ce144267
2896800 002f830dacab1f3c3e043480e5a0e6af8b12c18cf03c60f19007ea4428506c16
2897200 00428e11ae9befe7d1f6d4140fd69c942c144591522867cedfec0c46c1932ad0
2897600 0027bd9ccd20dd135947787968d46e377e141f707fc7f94fb6aaf6fd5207bdbe
2898000 001129a757a12c6da8ee0b29397909f51086feb6d6ae4c02212d6e7481321401
2898400 002b100300ed661961257e54f86965bdf37baf0907ed8007b26120490f087edd
2898800 0050864a63e5c1baf9179637c5b854683af54000593a15e006cf0e4791c0d6d9
2899200 0000640fe7237f6ec1dfef20fd3432df7ba30bebf3b6c8da3c1166c13e5a62c5
2899600 006fa2e7de0d2773e9bfcab9c259e02b13a52c02d4f7aa3b203263fb7249ddd1
2900000 00459b0663c62a7b471c2238cffd787c3b04948269838965c5dc755c23976eaf
2900400 0019c23d9433fe13cc5f3d0f3e8855383fb4729e167d95cdfe81ee53eb64a787
2900800 0040388e36a35d2fd69adb7f7fa4179efae8b84c610a87d1d058c0aeda4595de
2901200 00183dd7f51cc28bff750e15380d0dc29503308a32f07cc97bd416eaefc0c69e
2901600 000fffade2acc3a798409854d24ed14db457b2a61ebf0cb35b92e86956e47710
2902000 0022a8cb97063111eb5951939e8d417bd2e74d85eba41bb724481f4a57f3f448
2902400 002ea985732088f854e1110e620fdac236c239d3f14df7d7a01bef11444b0cbe
2902800 0005f5c5c207f16a963c0cd69ec98258427cf227bcba712bc78f56c08a820bfd
2903200 0017abe145a5f4942a7523af68ac2851d9bae91cb004a7d7b6245d755123dbae
2903600 0021bdeb591e8554ed9f81986e2d222404d1f79859f9f1716d0df5ff69e67193
2904000 00239392b05b9e1aa3cd3db1e8ff4c77831fe7b61c08736530d2b892fee6cd14
2904400 0038c75e9e31be849e66c15815cbd80dd97322a3713d4d4dc3e10a0979ab89c1
2904800 000bea444180c8dc42ba77293339b041196d82381902350ce28bf2b47bb63b06
2905200 00247e57c2277edf1075fcaf07d03675b3f98e40d680860f089ca922ae3c7172
2905600 00046b5e5be02cf125341790a8c0b8e7770d04940ca587c9d0d22694bb7e7a12
2906000 001808dd3e24a96fb36875ba4ab10b67ad32484ecc884fd3ea51d7fa0823071a
2906400 000aac97263cc3ac8e33806cc926e669fabef7679f3568d45eaccf1a90e0f7d8
2906800 0012bdb3c5035eefc95c57a957a5fe9d2d13a8b4a93594be88f1cfbae15326b6
2907200 0029a247c9944a18e7ed28bd4cba9907888657a2f89a4e260459f92ca76b03d4
2907600 009c20acb1b6eebab31153dca565aef303f6d442c8378b717fee8b3c1e8d87b2
2908000 00318a5572ffc9fd9c3cd9068eb71b609a934d938969ba5b337ac2cb99baf310
2908400 000839ea2ba72aae4bdce764c3402f5ac24170568a85c8d0eff9388a9f325bb7
2908800 00460bc497f12f47c522d8c74dd58df4552c49f783d9cf2583359a37e7599ae6
2909200 003660ed48fa477c13e54ab4cecdd355fffe7589e263a21fd19d83ec63ced023
2909600 0022aecfe508c626305d14627e60a0a82020094201497c59059cb30f91b7fb8b
2910000 0056f8acd0c51559b9f8fbd67fc51c25c5898e5f8251fee6815dc0d172e6e901
2910400 00002afc6f9954ba68cc53075d27f230ba5de65a82ae960e05cbcc6fd064553b
2910800 0028c7636c4619fb4ad54124430e4d37541d3782d4504bb64263935e472b8d9a
2911200 00281b9524a93dd60d7307ece4693ae81add16db2f3f61503e7cb83d7cfcd6c6
2911600 002ed403a20f14b5765316fea1a550a33e896c9b6b736370bf8f1c1e2b132ba6
2912000 002e0b5b10c7dfc5fecd0d5f45fdd04f069bd85ce3d4dcaa5eb7beab4cc4b302
2912400 0035337a031bbf2081a290766cef0a1278a6035a8f2ac3d830c5aeb4259341d6
2912800 000d2ee1adae0750b0c17fd5cf3a8304e637a3a502bd4657707e178a33b1529a
2913200 001ad109bd23f9809f98477abdf12511f388545f5e061fe426da7c9ea4b45a96
2913600 001299ee1297c7925edb0832da36f8d0e62a28640b66fbc27c6a1bc8eca9a212
2914000 0022a2842422c3397ed010b0f176b3381fded1dd93fa8a3f3dd84eff9cf54f2d
2914400 0060d7a5de8d10bc5b0439ff5179b47a6bd96580bbd1fd2c4010b64cc245f6fb
2914800 000efb678b06ea1f9c354d752f53c44fd23a0b59e2bb2fb5b788cf3f052fe91a
2915200 003944ac07d4111c3ef0391bc038f20ccb64b701fd9b28b84a245b8ef664c18e
2915600 0009eb2c1abb9bb26242af552ccadced84c12e17f060a51a4ad6faf2eb0dc2f9
2916000 00417a45bcf1953118b6eb4ea0b667f332bd1d355495843b53b1f6554867072b
2916400 000dada203811dc57b765f758926f8ccb4ce4b1263ee616d4d402d7f84bf9ad4
2916800 0009ec3c636a195aeea20c3e093d3dd651c367ba6659c4cd2e904e7b11a25f2f
2917200 000a6eed88efa63957bd6699288c05dc07bd8fae16d6e0bba45ba969fa735279
2917600 003311c8f98de3ba8cd1ffb61a34b1f39a55b1b443c34092c4d6534ae12ece02
2918000 003fb42501af5627099c557d911b664b1957c5c6249a8538fbc162ab6dbb716f
2918400 0014db9bc8935772214fdf50223c6e8128fb93bd93fa57c587e3dca320c7c846
2918800 002b484a8db9e3705e1b8e105f33f6ed92b6ad39e7b7017e2412139668ea7133
2919200 002699c3b42c8858ab4f9d7c2033c0b5da2f616520bf2f245e7fb9b5a6366ee4
2919600 0026e73b28cbf7e38880a723478f23cf9fb1bc213cfcad4ba9a59a3c6cfa47ad
2920000 0089c0827a37556745ed3e669200335db0e6ca0d017ca5616d633a2f13211c27
2920400 07f11e44b16dfd183932f3d454101b5a5250033bca68c1fadd1d96bac2895db1
2920800 00001afb14eac431310b051ade3acc1a2b67871337ab2172409d6a42cf274c18
2921200 00613373724f41c1fc3336a3ddb60f8c0808b20664310c0dca2d83f5d3ae298a
2921600 00152b98004b275fe5ba60b0f1825b67387a2bc47f5ddde99841e8e689e71b52
2922000 004b3fe4f4c222105f4bbfc3d008b2f1e8d08f23382ca6643d8ee67a70f06966
2922400 0023151253704ded203a4b84b58ba1cb57a4ee0d2fdab57e7852088b09b392b1
2922800 00439b4e8b9384f7fd01ce94681f3099de08f73e50da013c63c369e1267220c2
2923200 000507ef90f8480971ebe74656aa34f5143c89635e5e82442999a3a0a8cbb3e0
2923600 0020b4a4348fa6ec29b2583490b816c81fcd128ee399cc1214c0039cc20d55f2
2924000 001992e97ba38a0b47eff5941f8254117d3e2cc183df6cf7ee71b7f79e118513
2924400 0011b1d6452c1d00645298e6437459c121aaed30cea1a930e6e5def833a0ca95
2924800 0026715f0e700a336246f7e9eaec64568d75fec1ea147e1220f2482047c3e032
2925200 002a3d0715cdc76eb3b9e04e8ee4e2605adbdffe68a0ff1ecbdd627dfbef02a2
2925600 00232131494ebf9c2abbed930f5a047c7033921d6d3289b092b733db7fa464b9
2926000 003d1968b304fcd187ac89f1e2ec912d088d1f0441e03335bfd0283f7be3a0df
2926400 001f3c72d83a1b4b3b7a15d2447701b0d4ba85fda819c152a956db5a282ea6ef
2926800 000e8bca5fa5abdbe1afae7cfb35ac9363025a884188db85a76cf1398b6768df
2927200 00049caaa4edb7a1f48afe685060d183d1d0fa2452e4e610bfd49c717715b5b6
2927600 0032afbd12fe5ba3e132d390fae6cc38b627fc7e39da02f89e4790a63a3c5bb8
2928000 004af64037c1388b62c95cef062207edc2102924a491f1e3915a81b0172f43dc
2928400 0026fe501581f6e0e625a21fe84f696bc1f422f8bd8807181813fef75b5c66ac
2928800 001c00225de564e1bf65569be362762b56b879b37349f1e7293aa094958ff906
2929200 00165319b7ff06867d70469a86aae38541b1b978c163321ec1c45452123aeb8a
2929600 0000a7a08fe8008b7c7e8c7805bbbaea515338a18e70d16208c607e5de6b49f5
2930000 004c992a2e53aa8f3ebf0ec6219f7ec904cfeaf619b6bc3416eb4cbae7bb1876
2930400 0012466c4cf100ad04f0342b69228cd2f062e37575df380e5181ba06ce93743d
2930800 001588feba45a7c10f7f254881123e7379911997e062f32eeb770ed253c6b45e
2931200 0029bf288360937888b62ad89a99d4c5f1376baf092d7dc3e4ff5a8bf819700a
2931600 00137a1be534d146ef6565fc9a8bed961de446bd1ba847496ffcbfe9ac28fb8a
2932000 003b7fca797df9b08c0629a8e23428d9a68f04753776936f8a821f800e0b0ae6
2932400 003fb3a93e9080a81263d0c5c99f2c738be9f952afcda6cebd81ef9c25c7b0d0
2932800 0019f43cb271cb61862afefc4d6e3ad809567b334bee80c8cab4aad5d36b68b3
2933200 0033033fcbd0530e34cea076d546ddd920bc2542d6fba8dbc3c27dd602ec7325
2933600 0022c1dc57048c96a0b16d6b0baa18876d045c7bdf89f5ca9e6c3157bd1b3c75
2934000 00122f17d22961d80e82853bd8678854897b562876eab55e2093f3c1c0f0d157
2934400 001956c5ae4ef3700fe27b1379a644e23f9263acfdb0f350f109039fb4534951
2934800 0002b85d0f90019206052fb74d289ae8a4b2b75bcd0263ecbdec7ba2e45c548c
2935200 000c2afc44279187cb796a806e49e66b3c2b67e693094b5a836e0c2f8d484805
2935600 0028a22e6e7d80f34aa2e94dce266e13d3f647790aea51ec0bd61636274bfd09
2936000 007663d33cebe1becfd85484dc1f30f41f1f3ab9df67658a1d8467998eeb4a25
2936400 00188d348f38086c74c50137f6f26faac11ffccd140566f0b4fa64421e4dc683
2936800 0031cf18b42a4cebc4c899255e62e4d91c6806b9c79b6d3181ba2eaa3ec2fb30
2937200 000a22d60d646592974584efab56620f8c917a3940206a19487b044340c7ed2e
2937600 0045d3f8c430d7b86ea9345c94adbb5c3b4f3fd3ff46bbc5bc836c2f5cb82070
2938000 00316b00df267cae8a28b8ded040e252793e74e4cd9394893b7077abe45bd52f
2938400 0038354db2d7396a121c15c247f8e51fff89a499c4542392b317fbe14ddd34b6
2938800 003272d6c8b879239a3a6ecee9c7e525420f982df23774703d045b1bdee33063
2939200 0020cede4325704cdf54f94d21f7773fe597bc84530d7a765fb365190d851e73
2939600 001bbca1135a3d687d35b7248f0f3329b5fed6e51b93a24ffc2b21fd8d4abc46
2940000 00060d6c8bb88bc2f4315ade3293191429d6f3b002731607f3a74ebe5bc226c2
2940400 002d59395f37b5adc7d0e80027c656c74f1f8351656e846f7fd8eaf313c102f1
2940800 0003cec5bb5d22962e6c4cf17f1f77cadef34f142b0b6cae040a2fedea22def1
2941200 0008445b20747bb6c398a16b89ed58baee20de8dd4ef061cdb50d927220b29a6
2941600 001b985bfddbdbefcc8101c9d114f54c6ae4a23b63760740fad63836d21e0a1f
2942000 0034b580363eae9b37954b2bf12905f56acffa43ae01aff3c878a596d2561bd8
2942400 002525584140fb60fcbbbd1c2c079c52cc91b7a43d92b5b279aa5281e8e9467c
2942800 0014e7181376ea8262a1309d84bfef51d2a7d86e1ec0222633f49ede80a8da8d
2943200 00973ec48c84c428757790d384fc790cd93e65d270e895bf87e43207e5ca84cf
2943600 00280865092d8129f8e78b83c14d0a4d0b079a930d096931924384422542f8fc
2944000 00675ae69092094964aa3fad47b8fe68b167b3ed1f93f662c5ee8406f9bcad2f
2944400 0014ecfd5b0b15b660146573e3d59a6e92f5d248200b3e423de4dca2e22f5726
2944800 0028e985a029857e349d97e29930e881603f92e781c880d235e969b07d057b22
2945200 000454cea4c83f21ade3fb29346920e11e9da7c3c63bbf40c11437ec89a791a6
2945600 003601333cf73786f356243d295fc97c15ac836a9bea38c7a3b5510ec2eda9bf
2946000 004e79a2a1376d687de88b27bcc413af48eb58a4410a7ca3863f3d371632f747
2946400 0064aefc3b361d442443ff4fc699f040e29a85646dd05e0184cc78fcb6fe2dc7
2946800 00739add4c6157d97ec1f604a474e81b0774c7921532031c2784368897da9b7a
2947200 000946b2f31a70ec5e345a4c4c277a2214c549a930a518a0a4c8a22fdf6cafda
2947600 002a8f67d9b8a4a2da2f1ca115b92ee6a141b33d13fcf18da5e5c278c3b54877
2948000 001dbf163391b4d0e7cd1d64c1dbd6b72b2309d2b3502e6370d0ec867981e98e
2948400 002e461ed86a1b00f992dc87e8924c50cab13354bde4904d24686bd2b70b90fc
2948800 0020b39378c621efefe00cf884878932c1ad4074b536e2838d7a9b40cd08dfeb
2949200 0038c3bf2cb417637f40d9dceb82fda5caf041f9291582d127964945859be8fa
2949600 00268d268b59f86866d899ed60632fee099f467bdd21ad4a530a35473c697cbb
2950000 004343fcc861c3fdfacf6a08d618fdb8324bb02426530ee944bbabd07155a330
2950400 003fb9315d35ca3a19ff70311f6b9d8f785e1bdabfa079e4e68d767c34300f4e
2950800 007db4d4b937dcfa4fe4772289e9cd4760546a32f2dea79b05570d3676537e26
2951200 00002ac219708bae17c53ebf6ce0aa9528a67e88c74f22d052fe93b24fb6cc62
2951600 001462da9401cf20a2b67ca4adf2fea4592af23f1c51ae55ea1091abf078afa9
2952000 00503d4f29aa89f1c99b7324e4e03ed71a3a7f2803344c8abfaa507788c92dfc
2952400 0019a4cc3eccc5aa159468eb5d892a2063b34e7a107655dc6e9a538948cfd172
2952800 003f6d44e7f6e8a437ef3fb823c07776abc88bafca1f3df02adb17218290de81
2953200 004a0e288b5ff6c77a633adb67a91f0a3a87eb3ae41dce48424d433757dd6aff
2953600 0039f9fc75b1e7b9b947eebc21a9ce9f4ffd1a62f0199e4351c69b27d8e29747
2954000 0024c5e7012a938a9364d71f7595907168a4d7bf620ecad53dd745fedbcfa756
2954400 0000f0323ebaddc665f15b3da30f886cdd867cf6f3659224f3023b56fd55ed8c
2954800 000cd2f92d639217b46a691e71cfa612265403181070fa9ce13d1c90a4349831
2955200 0010a5695dc95d3c94d87f03337f96b885a65fd6c93ed6c34e86ee83830ff50c
2955600 002da02114abdc45576994263c4df7c71ae4a4c49be2eac6a04eb2c16101980a
2956000 00c6e36b08f5cd8c945a7f0dc058287fe554a1523c137f0d4eb8c0bdd5834be8
2956400 003426b65c58f85781ab224938cbb9c614876bbce20f14e830ada2fa08fff404
2956800 00280e536343ef2b88b5d165dff380c789f3381f4512648f9c35a9b614180e49
2957200 00468fd3f01ad1ff1e26ddcec16249f7e6cca3b9218b539dc90c613a7abd4142
2957600 00170e94bca07e8c41c25249cd730e18798478b30501c044e7365b85bfba0ce5
2958000 003c17e180d78af72d380815162059f98e5c0d208a3a645e80e40a48d40ce61f
2958400 000225be979094a9cf49ccfbde23132f22905301f5198fdb712f9ce894450d68
2958800 00189d6cdaf0668e102ce30393ba86bfb56a41993de21c0d889407e28896f7e5
2959200 001acfecad7735c0d3a1d1951e2c1ba281348a3315436eaf4aa9ecc61684c4f0
2959600 00020dbb872dabd0e5cf3627629e74fcec5959b5c411154e31baaf6c0d89972d
2960000 003856b283b301f3fc4d0e8a1b4f51b33d2969da9236907897b739f4c564fea9
2960400 001a1ca0409eb4d5341f11abbd16ead4e9618a96757b3e000072f2d0741adbd1
2960800 005636a8e7821de4251b596d23ba43cef53acb2e526141993f8341a4ce4e0492
2961200 0051435a30f5d6c179bb38f98161545ccaec8a5e080922a236e36cd235eb76d6
2961600 002b46e20e3f672c7829237c2da46b24e41d9298feacdae09d4e7b13e4bd4c5f
2962000 002a7ecce8f4e5598ade3594746dee702afa5b5ad6c9b267f1a9aab8cc064d28
2962400 00088ee7605c74993e1238cd5a33ec31888f229156a20d6a288f9271923dc3d0
2962800 0079b82cff472c84194e4bd0a843f8e3ad9fe14caafc7f26213fde9ad1f5b669
2963200 000fe0cdd168970d333c455ae8083bb276405d0bb8bd72e68a41ec84d136a426
2963600 005fb8639e3487f928c7e58eb77a698732114c90858eac28b183a12c4e1afc9b
2964000 0008b1fff1b463a6284de7e0e223ff2ef33eb4eaa8bfab0245f6445c9684f74b
2964400 0037ef47bf2ac75fdd73b2142c87b4093fc8508092e119324fbf38e772ff1f3f
2964800 0050a36c5a7f12c8e4364f1ed347d5071f4ab314f14aa655242ff7d1e928e296
2965200 0017e6041a46b9ac29f59b426af6b54ed1264463e415aa50bc790be3d2080488
2965600 002ebe10ad92069fdf4af3fdaf770bf1e2700c31969710fdd8eb539ddf502a11
2966000 0014ad3a592d7665dd15a3d29a394b12474af8f2321ca2adf38d2ea6a8319256
2966400 003525ad762380dbac0c537b55e737702069cbf24bc9a7fd7c25d1f8c3bbdf89
2966800 004d89194a104eddaaceef209760ca4521f3dcf0488bc583d4abb1f5150fe931
2967200 0052a0cc4afa56f9e4ab4297021171a86034769cee41cea705f46f485a579305
2967600 0002f8ef691e2733450b5b559fb168bc0f2301b7cf26d4064dea1d20e60fc445
2968000 0056b30c5c00fcc16b3792504d8325086ea5de8f0fa43a2d74cd20dacb6bea8e
2968400 004d82f38003740eba51a1fc5f1c72a010f21479f3109fc51b4aa698b7cb1230
2968800 004733ab1614997e4d79308c4a91de6fdbef579fe0062d21d2dfddc3a8aebe44
2969200 0018788ce28c8107daa666957a0ec61ae15a70a02a01c20b1c82193b7b325ef7
2969600 002c9c5b457a2c67904c59713a376f3eb001fdb506df4795d5db52b770e22cdc
2970000 0034fe9e90c24b6cbe6f34aaf990fc994a4d37c81265e71fa23e5acd89d099ee
2970400 000744ca9ab1dd373e8d9b8c5cf68bdc84591678510f4aa39e178717ac66c402
2970800 0030e7d6da8090de4dbb10f7a5a581de52d24c83c75978c1e959f08e163f7d4e
2971200 003490610d7fc1548524b230bf18095bd131aad9a7428b5f77cdf5f29072270c
2971600 000eb2357cafd0c8b382004d23f7aa3d592b56b7cfa913ddb84d03cfd8f711ee
2972000 001cbc09dbbf345bf3c5f4a269eb82910fb4f9661b391b4d52355f34db0fedf6
2972400 004a255fd97ed5b6ef7cbfd2cd51b0b3c09cabddce2cfcdb0f4bd4c289649f9f
2972800 0042012f0efac7093f208cd4636e2026c843437c172df02b64ba9a3259571bfc
2973200 0032c83ee743bcfd5795caaa601d0275f6b54fb75574750a51e5d22c24b14ea8
2973600 0012655ae0ade4590af7c05dd609415b422d33f7ceb1dbb15d2c381bf0576dd2
2974000 004a2810cfe2a2bd83c202a0311cff47c80364ee2a874a93bae34404380e2b98

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-grpc"
version = "0.1.0-alpha.5"
version = "0.1.0-alpha.6"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Zebra gRPC interface"
license = "MIT OR Apache-2.0"
@ -26,10 +26,10 @@ tokio-stream = "0.1.15"
tower = { version = "0.4.13", features = ["util", "buffer", "timeout"] }
color-eyre = "0.6.3"
zcash_primitives = { version = "0.15.0" }
zcash_primitives.workspace = true
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.38", features = ["shielded-scan"] }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.38" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = ["shielded-scan"] }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" }
[build-dependencies]
tonic-build = "0.12.1"

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-network"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>", "Tower Maintainers <team@tower-rs.com>"]
description = "Networking code for Zebra"
# # Legal
@ -83,7 +83,7 @@ howudoin = { version = "0.1.2", optional = true }
proptest = { version = "1.4.0", optional = true }
proptest-derive = { version = "0.5.0", optional = true }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = ["async-error"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["async-error"] }
[dev-dependencies]
proptest = "1.4.0"

View File

@ -2,7 +2,6 @@
use std::{
collections::HashSet,
ffi::OsString,
io::{self, ErrorKind},
net::{IpAddr, SocketAddr},
time::Duration,
@ -10,11 +9,11 @@ use std::{
use indexmap::IndexSet;
use serde::{de, Deserialize, Deserializer};
use tempfile::NamedTempFile;
use tokio::{fs, io::AsyncWriteExt};
use tracing::Span;
use tokio::fs;
use tracing::Span;
use zebra_chain::{
common::atomic_write,
parameters::{
testnet::{self, ConfiguredActivationHeights, ConfiguredFundingStreams},
Magic, Network, NetworkKind,
@ -503,90 +502,36 @@ impl Config {
// Make a newline-separated list
let peer_data = peer_list.join("\n");
// Write to a temporary file, so the cache is not corrupted if Zebra shuts down or crashes
// at the same time.
//
// # Concurrency
//
// We want to use async code to avoid blocking the tokio executor on filesystem operations,
// but `tempfile` is implemented using non-asyc methods. So we wrap its filesystem
// operations in `tokio::spawn_blocking()`.
//
// TODO: split this out into an atomic_write_to_tmp_file() method if we need to re-use it
// Create the peer cache directory if needed
let peer_cache_dir = peer_cache_file
.parent()
.expect("cache path always has a network directory")
.to_owned();
tokio::fs::create_dir_all(&peer_cache_dir).await?;
// Give the temporary file a similar name to the permanent cache file,
// but hide it in directory listings.
let mut tmp_peer_cache_prefix: OsString = ".tmp.".into();
tmp_peer_cache_prefix.push(
peer_cache_file
.file_name()
.expect("cache file always has a file name"),
);
// Create the temporary file.
// Do blocking filesystem operations on a dedicated thread.
// Write the peer cache file atomically so the cache is not corrupted if Zebra shuts down
// or crashes.
let span = Span::current();
let tmp_peer_cache_file = tokio::task::spawn_blocking(move || {
span.in_scope(move || {
// Put the temporary file in the same directory as the permanent file,
// so atomic filesystem operations are possible.
tempfile::Builder::new()
.prefix(&tmp_peer_cache_prefix)
.tempfile_in(peer_cache_dir)
})
let write_result = tokio::task::spawn_blocking(move || {
span.in_scope(move || atomic_write(peer_cache_file, peer_data.as_bytes()))
})
.await
.expect("unexpected panic creating temporary peer cache file")?;
.expect("could not write the peer cache file")?;
// Write the list to the file asynchronously, by extracting the inner file, using it,
// then combining it back into a type that will correctly drop the file on error.
let (tmp_peer_cache_file, tmp_peer_cache_path) = tmp_peer_cache_file.into_parts();
let mut tmp_peer_cache_file = tokio::fs::File::from_std(tmp_peer_cache_file);
tmp_peer_cache_file.write_all(peer_data.as_bytes()).await?;
match write_result {
Ok(peer_cache_file) => {
info!(
cached_ip_count = ?peer_list.len(),
?peer_cache_file,
"updated cached peer IP addresses"
);
let tmp_peer_cache_file =
NamedTempFile::from_parts(tmp_peer_cache_file, tmp_peer_cache_path);
// Atomically replace the current cache with the temporary cache.
// Do blocking filesystem operations on a dedicated thread.
let span = Span::current();
tokio::task::spawn_blocking(move || {
span.in_scope(move || {
let result = tmp_peer_cache_file.persist(&peer_cache_file);
// Drops the temp file if needed
match result {
Ok(_temp_file) => {
info!(
cached_ip_count = ?peer_list.len(),
?peer_cache_file,
"updated cached peer IP addresses"
);
for ip in &peer_list {
metrics::counter!(
"zcash.net.peers.cache",
"cache" => peer_cache_file.display().to_string(),
"remote_ip" => ip.to_string()
)
.increment(1);
}
Ok(())
}
Err(error) => Err(error.error),
for ip in &peer_list {
metrics::counter!(
"zcash.net.peers.cache",
"cache" => peer_cache_file.display().to_string(),
"remote_ip" => ip.to_string()
)
.increment(1);
}
})
})
.await
.expect("unexpected panic making temporary peer cache file permanent")
Ok(())
}
Err(error) => Err(error.error),
}
}
}

View File

@ -2,7 +2,7 @@
use std::path::{Path, PathBuf};
use zebra_chain::parameters::Network;
use zebra_chain::{common::default_cache_dir, parameters::Network};
/// A cache directory config field.
///
@ -56,12 +56,7 @@ impl CacheDir {
/// Returns the `zebra-network` base cache directory, if enabled.
pub fn cache_dir(&self) -> Option<PathBuf> {
match self {
Self::IsEnabled(is_enabled) => is_enabled.then(|| {
dirs::cache_dir()
.unwrap_or_else(|| std::env::current_dir().unwrap().join("cache"))
.join("zebra")
}),
Self::IsEnabled(is_enabled) => is_enabled.then(default_cache_dir),
Self::CustomPath(cache_dir) => Some(cache_dir.to_owned()),
}
}

View File

@ -337,7 +337,7 @@ pub const TIMESTAMP_TRUNCATION_SECONDS: u32 = 30 * 60;
///
/// The current protocol version typically changes before Mainnet and Testnet
/// network upgrades.
pub const CURRENT_NETWORK_PROTOCOL_VERSION: Version = Version(170_100);
pub const CURRENT_NETWORK_PROTOCOL_VERSION: Version = Version(170_110);
/// The default RTT estimate for peer responses.
///

View File

@ -82,9 +82,9 @@ impl Version {
(_, Genesis) | (_, BeforeOverwinter) => 170_002,
(Testnet(params), Overwinter) if params.is_default_testnet() => 170_003,
(Mainnet, Overwinter) => 170_005,
// TODO: Use 170_006 for (Testnet(params), Sapling) if params.is_regtest() (`Regtest` in zcashd uses
// version 170_006 for Sapling, and the same values as Testnet for other network upgrades.)
(_, Sapling) => 170_007,
(Testnet(params), Sapling) if params.is_default_testnet() => 170_007,
(Testnet(params), Sapling) if params.is_regtest() => 170_006,
(Mainnet, Sapling) => 170_007,
(Testnet(params), Blossom) if params.is_default_testnet() => 170_008,
(Mainnet, Blossom) => 170_009,
(Testnet(params), Heartwood) if params.is_default_testnet() => 170_010,
@ -93,11 +93,11 @@ impl Version {
(Mainnet, Canopy) => 170_013,
(Testnet(params), Nu5) if params.is_default_testnet() => 170_050,
(Mainnet, Nu5) => 170_100,
(Testnet(params), Nu6) if params.is_default_testnet() => 170_050,
(Mainnet, Nu6) => 170_100,
(Testnet(params), Nu6) if params.is_default_testnet() => 170_110,
(Mainnet, Nu6) => 170_120,
// It should be fine to reject peers with earlier network protocol versions on custom testnets for now.
(Testnet(_params), _) => CURRENT_NETWORK_PROTOCOL_VERSION.0,
(Testnet(_), _) => CURRENT_NETWORK_PROTOCOL_VERSION.0,
})
}
}
@ -194,7 +194,7 @@ mod test {
let _init_guard = zebra_test::init();
let highest_network_upgrade = NetworkUpgrade::current(network, block::Height::MAX);
assert!(highest_network_upgrade == Nu5 || highest_network_upgrade == Canopy,
assert!(highest_network_upgrade == Nu6 || highest_network_upgrade == Nu5,
"expected coverage of all network upgrades: add the new network upgrade to the list in this test");
for &network_upgrade in &[
@ -205,6 +205,7 @@ mod test {
Heartwood,
Canopy,
Nu5,
Nu6,
] {
let height = network_upgrade.activation_height(network);
if let Some(height) = height {

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-node-services"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "The interfaces of some Zebra node services"
license = "MIT OR Apache-2.0"
@ -34,10 +34,10 @@ rpc-client = [
"serde_json",
]
shielded-scan = ["tokio"]
shielded-scan = []
[dependencies]
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.38" }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" }
# Optional dependencies
@ -48,7 +48,7 @@ jsonrpc-core = { version = "18.0.0", optional = true }
reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true }
serde = { version = "1.0.204", optional = true }
serde_json = { version = "1.0.122", optional = true }
tokio = { version = "1.39.2", features = ["time"], optional = true }
tokio = { version = "1.39.2", features = ["time", "sync"] }
[dev-dependencies]

View File

@ -4,6 +4,7 @@
use std::collections::HashSet;
use tokio::sync::oneshot;
use zebra_chain::transaction::{self, UnminedTx, UnminedTxId};
#[cfg(feature = "getblocktemplate-rpcs")]
@ -114,13 +115,11 @@ pub enum Response {
/// Returns matching cached rejected [`UnminedTxId`]s from the mempool,
RejectedTransactionIds(HashSet<UnminedTxId>),
/// Returns a list of queue results.
///
/// These are the results of the initial queue checks.
/// The transaction may also fail download or verification later.
/// Returns a list of initial queue checks results and a oneshot receiver
/// for awaiting download and/or verification results.
///
/// Each result matches the request at the corresponding vector index.
Queued(Vec<Result<(), BoxError>>),
Queued(Vec<Result<oneshot::Receiver<Result<(), BoxError>>, BoxError>>),
/// Confirms that the mempool has checked for recently verified transactions.
CheckedForVerifiedTransactions,

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-rpc"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "A Zebra JSON Remote Procedure Call (JSON-RPC) interface"
license = "MIT OR Apache-2.0"
@ -88,28 +88,26 @@ hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.204", features = ["serde_derive"] }
# TODO: Revert to a release once librustzcash is released (#8749).
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", branch = "main", features = ["transparent-inputs"] }
zcash_primitives = { workspace = true, features = ["transparent-inputs"] }
# Experimental feature getblocktemplate-rpcs
rand = { version = "0.8.5", optional = true }
# ECC deps used by getblocktemplate-rpcs feature
# TODO: Revert to a release once librustzcash is released (#8749).
zcash_address = { git = "https://github.com/zcash/librustzcash.git", branch = "main", optional = true}
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.38", features = [
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = [
"json-conversion",
] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.38" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.38" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.38", features = [
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = [
"rpc-client",
] }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.38" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38" }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.39" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" }
[build-dependencies]
tonic-build = { version = "0.12.1", optional = true }
@ -122,17 +120,17 @@ proptest = "1.4.0"
thiserror = "1.0.63"
tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = [
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = [
"proptest-impl",
] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.38", features = [
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39", features = [
"proptest-impl",
] }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.38", features = [
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39", features = [
"proptest-impl",
] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38", features = [
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = [
"proptest-impl",
] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.38" }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" }

View File

@ -21,7 +21,7 @@ use tracing::Instrument;
use zcash_primitives::consensus::Parameters;
use zebra_chain::{
block::{self, Height, SerializedBlock},
chain_tip::ChainTip,
chain_tip::{ChainTip, NetworkChainTipHeightEstimator},
parameters::{ConsensusBranchId, Network, NetworkUpgrade},
serialization::ZcashDeserialize,
subtree::NoteCommitmentSubtreeIndex,
@ -45,6 +45,8 @@ use errors::{MapServerError, OkOrServerError};
// We don't use a types/ module here, because it is redundant.
pub mod trees;
pub mod types;
#[cfg(feature = "getblocktemplate-rpcs")]
pub mod get_block_template_rpcs;
@ -85,7 +87,7 @@ pub trait Rpc {
/// Some fields from the zcashd reference are missing from Zebra's [`GetBlockChainInfo`]. It only contains the fields
/// [required for lightwalletd support.](https://github.com/zcash/lightwalletd/blob/v0.4.9/common/common.go#L72-L89)
#[rpc(name = "getblockchaininfo")]
fn get_blockchain_info(&self) -> Result<GetBlockChainInfo>;
fn get_blockchain_info(&self) -> BoxFuture<Result<GetBlockChainInfo>>;
/// Returns the total balance of a provided `addresses` in an [`AddressBalance`] instance.
///
@ -500,98 +502,120 @@ where
Ok(response)
}
// TODO: use a generic error constructor (#5548)
#[allow(clippy::unwrap_in_result)]
fn get_blockchain_info(&self) -> Result<GetBlockChainInfo> {
let network = &self.network;
fn get_blockchain_info(&self) -> BoxFuture<Result<GetBlockChainInfo>> {
let network = self.network.clone();
let debug_force_finished_sync = self.debug_force_finished_sync;
let mut state = self.state.clone();
// `chain` field
let chain = self.network.bip70_network_name();
async move {
// `chain` field
let chain = network.bip70_network_name();
// `blocks` and `best_block_hash` fields
let (tip_height, tip_hash) = self
.latest_chain_tip
.best_tip_height_and_hash()
.ok_or_server_error("No Chain tip available yet")?;
let request = zebra_state::ReadRequest::TipPoolValues;
let response: zebra_state::ReadResponse = state
.ready()
.and_then(|service| service.call(request))
.await
.map_server_error()?;
// `estimated_height` field
let current_block_time = self
.latest_chain_tip
.best_tip_block_time()
.ok_or_server_error("No Chain tip available yet")?;
let zebra_state::ReadResponse::TipPoolValues {
tip_height,
tip_hash,
value_balance,
} = response
else {
unreachable!("unmatched response to a TipPoolValues request")
};
let zebra_estimated_height = self
.latest_chain_tip
.estimate_network_chain_tip_height(network, Utc::now())
.ok_or_server_error("No Chain tip available yet")?;
let request = zebra_state::ReadRequest::BlockHeader(tip_hash.into());
let response: zebra_state::ReadResponse = state
.ready()
.and_then(|service| service.call(request))
.await
.map_server_error()?;
let mut estimated_height =
if current_block_time > Utc::now() || zebra_estimated_height < tip_height {
let zebra_state::ReadResponse::BlockHeader(block_header) = response else {
unreachable!("unmatched response to a BlockHeader request")
};
let tip_block_time = block_header
.ok_or_server_error("unexpectedly could not read best chain tip block header")?
.time;
let now = Utc::now();
let zebra_estimated_height =
NetworkChainTipHeightEstimator::new(tip_block_time, tip_height, &network)
.estimate_height_at(now);
// If we're testing the mempool, force the estimated height to be the actual tip height, otherwise,
// check if the estimated height is below Zebra's latest tip height, or if the latest tip's block time is
// later than the current time on the local clock.
let estimated_height = if tip_block_time > now
|| zebra_estimated_height < tip_height
|| debug_force_finished_sync
{
tip_height
} else {
zebra_estimated_height
};
// If we're testing the mempool, force the estimated height to be the actual tip height.
if self.debug_force_finished_sync {
estimated_height = tip_height;
}
// `upgrades` object
//
// Get the network upgrades in height order, like `zcashd`.
let mut upgrades = IndexMap::new();
for (activation_height, network_upgrade) in network.full_activation_list() {
// Zebra defines network upgrades based on incompatible consensus rule changes,
// but zcashd defines them based on ZIPs.
// `upgrades` object
//
// All the network upgrades with a consensus branch ID are the same in Zebra and zcashd.
if let Some(branch_id) = network_upgrade.branch_id() {
// zcashd's RPC seems to ignore Disabled network upgrades, so Zebra does too.
let status = if tip_height >= activation_height {
NetworkUpgradeStatus::Active
} else {
NetworkUpgradeStatus::Pending
};
// Get the network upgrades in height order, like `zcashd`.
let mut upgrades = IndexMap::new();
for (activation_height, network_upgrade) in network.full_activation_list() {
// Zebra defines network upgrades based on incompatible consensus rule changes,
// but zcashd defines them based on ZIPs.
//
// All the network upgrades with a consensus branch ID are the same in Zebra and zcashd.
if let Some(branch_id) = network_upgrade.branch_id() {
// zcashd's RPC seems to ignore Disabled network upgrades, so Zebra does too.
let status = if tip_height >= activation_height {
NetworkUpgradeStatus::Active
} else {
NetworkUpgradeStatus::Pending
};
let upgrade = NetworkUpgradeInfo {
name: network_upgrade,
activation_height,
status,
};
upgrades.insert(ConsensusBranchIdHex(branch_id), upgrade);
let upgrade = NetworkUpgradeInfo {
name: network_upgrade,
activation_height,
status,
};
upgrades.insert(ConsensusBranchIdHex(branch_id), upgrade);
}
}
// `consensus` object
let next_block_height =
(tip_height + 1).expect("valid chain tips are a lot less than Height::MAX");
let consensus = TipConsensusBranch {
chain_tip: ConsensusBranchIdHex(
NetworkUpgrade::current(&network, tip_height)
.branch_id()
.unwrap_or(ConsensusBranchId::RPC_MISSING_ID),
),
next_block: ConsensusBranchIdHex(
NetworkUpgrade::current(&network, next_block_height)
.branch_id()
.unwrap_or(ConsensusBranchId::RPC_MISSING_ID),
),
};
let response = GetBlockChainInfo {
chain,
blocks: tip_height,
best_block_hash: tip_hash,
estimated_height,
value_pools: types::ValuePoolBalance::from_value_balance(value_balance),
upgrades,
consensus,
};
Ok(response)
}
// `consensus` object
let next_block_height =
(tip_height + 1).expect("valid chain tips are a lot less than Height::MAX");
let consensus = TipConsensusBranch {
chain_tip: ConsensusBranchIdHex(
NetworkUpgrade::current(network, tip_height)
.branch_id()
.unwrap_or(ConsensusBranchId::RPC_MISSING_ID),
),
next_block: ConsensusBranchIdHex(
NetworkUpgrade::current(network, next_block_height)
.branch_id()
.unwrap_or(ConsensusBranchId::RPC_MISSING_ID),
),
};
let response = GetBlockChainInfo {
chain,
blocks: tip_height,
best_block_hash: tip_hash,
estimated_height,
upgrades,
consensus,
};
Ok(response)
.boxed()
}
// TODO: use a generic error constructor (#5548)
fn get_address_balance(
&self,
address_strings: AddressStrings,
@ -615,7 +639,6 @@ where
}
// TODO: use HexData or GetRawTransaction::Bytes to handle the transaction data argument
// use a generic error constructor (#5548)
fn send_raw_transaction(
&self,
raw_transaction_hex: String,
@ -641,7 +664,7 @@ where
let response = mempool.oneshot(request).await.map_server_error()?;
let queue_results = match response {
let mut queue_results = match response {
mempool::Response::Queued(results) => results,
_ => unreachable!("incorrect response variant from mempool service"),
};
@ -652,10 +675,17 @@ where
"mempool service returned more results than expected"
);
tracing::debug!("sent transaction to mempool: {:?}", &queue_results[0]);
let queue_result = queue_results
.pop()
.expect("there should be exactly one item in Vec")
.inspect_err(|err| tracing::debug!("sent transaction to mempool: {:?}", &err))
.map_server_error()?
.await;
queue_results[0]
.as_ref()
tracing::debug!("sent transaction to mempool: {:?}", &queue_result);
queue_result
.map_server_error()?
.map(|_| SentTransactionHash(transaction_hash))
.map_server_error()
}
@ -963,7 +993,6 @@ where
}
// TODO: use HexData or SentTransactionHash to handle the transaction ID
// use a generic error constructor (#5548)
fn get_raw_transaction(
&self,
txid_hex: String,
@ -1197,7 +1226,6 @@ where
.boxed()
}
// TODO: use a generic error constructor (#5548)
fn get_address_tx_ids(
&self,
request: GetAddressTxIdsRequest,
@ -1258,7 +1286,6 @@ where
.boxed()
}
// TODO: use a generic error constructor (#5548)
fn get_address_utxos(
&self,
address_strings: AddressStrings,
@ -1372,6 +1399,10 @@ pub struct GetBlockChainInfo {
#[serde(rename = "estimatedheight")]
estimated_height: Height,
/// Value pool balances
#[serde(rename = "valuePools")]
value_pools: [types::ValuePoolBalance; 5],
/// Status of network upgrades
upgrades: IndexMap<ConsensusBranchIdHex, NetworkUpgradeInfo>,
@ -1386,6 +1417,7 @@ impl Default for GetBlockChainInfo {
blocks: Height(1),
best_block_hash: block::Hash([0; 32]),
estimated_height: Height(1),
value_pools: types::ValuePoolBalance::zero_pools(),
upgrades: IndexMap::new(),
consensus: TipConsensusBranch {
chain_tip: ConsensusBranchIdHex(ConsensusBranchId::default()),

View File

@ -10,11 +10,14 @@ use tower::{Service, ServiceExt};
use zcash_address::{unified::Encoding, TryFromAddress};
use zebra_chain::{
amount::Amount,
amount::{self, Amount, NonNegative},
block::{self, Block, Height, TryIntoHeight},
chain_sync_status::ChainSyncStatus,
chain_tip::ChainTip,
parameters::{subsidy::ParameterSubsidy, Network, NetworkKind, POW_AVERAGING_WINDOW},
parameters::{
subsidy::{FundingStreamReceiver, ParameterSubsidy},
Network, NetworkKind, NetworkUpgrade, POW_AVERAGING_WINDOW,
},
primitives,
serialization::ZcashDeserializeInto,
transparent::{
@ -31,6 +34,7 @@ use zebra_state::{ReadRequest, ReadResponse};
use crate::methods::{
best_chain_tip_height,
errors::MapServerError,
get_block_template_rpcs::{
constants::{
DEFAULT_SOLUTION_RATE_WINDOW_SIZE, GET_BLOCK_TEMPLATE_MEMPOOL_LONG_POLL_INTERVAL,
@ -547,7 +551,6 @@ where
best_chain_tip_height(&self.latest_chain_tip).map(|height| height.0)
}
// TODO: use a generic error constructor (#5548)
fn get_block_hash(&self, index: i32) -> BoxFuture<Result<GetBlockHash>> {
let mut state = self.state.clone();
let latest_chain_tip = self.latest_chain_tip.clone();
@ -563,11 +566,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
.map_server_error()?;
match response {
zebra_state::ReadResponse::BlockHash(Some(hash)) => Ok(GetBlockHash(hash)),
@ -582,7 +581,6 @@ where
.boxed()
}
// TODO: use a generic error constructor (#5548)
fn get_block_template(
&self,
parameters: Option<get_block_template::JsonParameters>,
@ -826,11 +824,7 @@ where
Is Zebra shutting down?"
);
return Err(Error {
code: ErrorCode::ServerError(0),
message: recv_error.to_string(),
data: None,
});
return Err(recv_error).map_server_error();
}
}
}
@ -1178,35 +1172,27 @@ where
});
}
let expected_block_subsidy =
block_subsidy(height, &network).map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let miner_subsidy =
miner_subsidy(height, &network, expected_block_subsidy).map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
// Always zero for post-halving blocks
let founders = Amount::zero();
let funding_streams = funding_stream_values(height, &network, expected_block_subsidy)
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let mut funding_streams: Vec<_> = funding_streams
.iter()
.filter_map(|(receiver, value)| {
let address = funding_stream_address(height, &network, *receiver)?;
Some((*receiver, FundingStream::new(*receiver, *value, address)))
})
.collect();
let total_block_subsidy = block_subsidy(height, &network).map_server_error()?;
let miner_subsidy =
miner_subsidy(height, &network, total_block_subsidy).map_server_error()?;
let (lockbox_streams, mut funding_streams): (Vec<_>, Vec<_>) =
funding_stream_values(height, &network, total_block_subsidy)
.map_server_error()?
.into_iter()
// Separate the funding streams into deferred and non-deferred streams
.partition(|(receiver, _)| matches!(receiver, FundingStreamReceiver::Deferred));
let is_nu6 = NetworkUpgrade::current(&network, height) == NetworkUpgrade::Nu6;
let [lockbox_total, funding_streams_total]: [std::result::Result<
Amount<NonNegative>,
amount::Error,
>; 2] = [&lockbox_streams, &funding_streams]
.map(|streams| streams.iter().map(|&(_, amount)| amount).sum());
// Use the same funding stream order as zcashd
funding_streams.sort_by_key(|(receiver, _funding_stream)| {
@ -1215,12 +1201,26 @@ where
.position(|zcashd_receiver| zcashd_receiver == receiver)
});
let (_receivers, funding_streams): (Vec<_>, _) = funding_streams.into_iter().unzip();
// Format the funding streams and lockbox streams
let [funding_streams, lockbox_streams]: [Vec<_>; 2] =
[funding_streams, lockbox_streams].map(|streams| {
streams
.into_iter()
.map(|(receiver, value)| {
let address = funding_stream_address(height, &network, receiver);
FundingStream::new(is_nu6, receiver, value, address)
})
.collect()
});
Ok(BlockSubsidy {
miner: miner_subsidy.into(),
founders: founders.into(),
funding_streams,
lockbox_streams,
funding_streams_total: funding_streams_total.map_server_error()?.into(),
lockbox_total: lockbox_total.map_server_error()?.into(),
total_block_subsidy: total_block_subsidy.into(),
})
}
.boxed()

View File

@ -25,9 +25,12 @@ use zebra_consensus::{
use zebra_node_services::mempool;
use zebra_state::GetBlockTemplateChainInfo;
use crate::methods::get_block_template_rpcs::{
constants::{MAX_ESTIMATED_DISTANCE_TO_NETWORK_CHAIN_TIP, NOT_SYNCED_ERROR_CODE},
types::{default_roots::DefaultRoots, transaction::TransactionTemplate},
use crate::methods::{
errors::OkOrServerError,
get_block_template_rpcs::{
constants::{MAX_ESTIMATED_DISTANCE_TO_NETWORK_CHAIN_TIP, NOT_SYNCED_ERROR_CODE},
types::{default_roots::DefaultRoots, transaction::TransactionTemplate},
},
};
pub use crate::methods::get_block_template_rpcs::types::get_block_template::*;
@ -178,11 +181,7 @@ where
// but this is ok for an estimate
let (estimated_distance_to_chain_tip, local_tip_height) = latest_chain_tip
.estimate_distance_to_network_chain_tip(network)
.ok_or_else(|| Error {
code: ErrorCode::ServerError(0),
message: "No Chain tip available yet".to_string(),
data: None,
})?;
.ok_or_server_error("no chain tip available yet")?;
if !sync_status.is_close_to_tip()
|| estimated_distance_to_chain_tip > MAX_ESTIMATED_DISTANCE_TO_NETWORK_CHAIN_TIP

View File

@ -11,4 +11,3 @@ pub mod transaction;
pub mod unified_address;
pub mod validate_address;
pub mod z_validate_address;
pub mod zec;

View File

@ -6,16 +6,21 @@ use zebra_chain::{
transparent,
};
use crate::methods::get_block_template_rpcs::types::zec::Zec;
use crate::methods::types::Zec;
/// A response to a `getblocksubsidy` RPC request
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
pub struct BlockSubsidy {
/// An array of funding stream descriptions.
/// Always present, because Zebra returns an error for heights before the first halving.
#[serde(rename = "fundingstreams")]
/// Always present before NU6, because Zebra returns an error for heights before the first halving.
#[serde(rename = "fundingstreams", skip_serializing_if = "Vec::is_empty")]
pub funding_streams: Vec<FundingStream>,
/// An array of lockbox stream descriptions.
/// Always present after NU6.
#[serde(rename = "lockboxstreams", skip_serializing_if = "Vec::is_empty")]
pub lockbox_streams: Vec<FundingStream>,
/// The mining reward amount in ZEC.
///
/// This does not include the miner fee.
@ -26,16 +31,20 @@ pub struct BlockSubsidy {
/// Zebra returns an error when asked for founders reward heights,
/// because it checkpoints those blocks instead.
pub founders: Zec<NonNegative>,
}
impl Default for BlockSubsidy {
fn default() -> Self {
Self {
funding_streams: vec![],
miner: Zec::from_lossy_zec(0.0).unwrap(),
founders: Zec::from_lossy_zec(0.0).unwrap(),
}
}
/// The total funding stream amount in ZEC.
#[serde(rename = "fundingstreamstotal")]
pub funding_streams_total: Zec<NonNegative>,
/// The total lockbox stream amount in ZEC.
#[serde(rename = "lockboxtotal")]
pub lockbox_total: Zec<NonNegative>,
/// The total block subsidy amount in ZEC.
///
/// This does not include the miner fee.
#[serde(rename = "totalblocksubsidy")]
pub total_block_subsidy: Zec<NonNegative>,
}
/// A single funding stream's information in a `getblocksubsidy` RPC request
@ -58,24 +67,28 @@ pub struct FundingStream {
///
/// The current Zcash funding streams only use transparent addresses,
/// so Zebra doesn't support Sapling addresses in this RPC.
pub address: transparent::Address,
///
/// This is optional so we can support funding streams with no addresses (lockbox streams).
#[serde(skip_serializing_if = "Option::is_none")]
pub address: Option<transparent::Address>,
}
impl FundingStream {
/// Convert a `receiver`, `value`, and `address` into a `FundingStream` response.
pub fn new(
is_nu6: bool,
receiver: FundingStreamReceiver,
value: Amount<NonNegative>,
address: &transparent::Address,
address: Option<&transparent::Address>,
) -> FundingStream {
let (name, specification) = receiver.info();
let (name, specification) = receiver.info(is_nu6);
FundingStream {
recipient: name.to_string(),
specification: specification.to_string(),
value: value.into(),
value_zat: value,
address: address.clone(),
address: address.cloned(),
}
}
}

View File

@ -1,17 +1,18 @@
//! Randomised property tests for RPC methods.
use std::collections::HashSet;
use std::{collections::HashSet, sync::Arc};
use futures::{join, FutureExt, TryFutureExt};
use hex::ToHex;
use jsonrpc_core::{Error, ErrorCode};
use proptest::{collection::vec, prelude::*};
use thiserror::Error;
use tokio::sync::oneshot;
use tower::buffer::Buffer;
use zebra_chain::{
amount::{Amount, NonNegative},
block::{Block, Height},
block::{self, Block, Height},
chain_tip::{mock::MockChainTip, NoChainTip},
parameters::{
Network::{self, *},
@ -20,6 +21,7 @@ use zebra_chain::{
serialization::{ZcashDeserialize, ZcashSerialize},
transaction::{self, Transaction, UnminedTx, VerifiedUnminedTx},
transparent,
value_balance::ValueBalance,
};
use zebra_node_services::mempool;
use zebra_state::BoxError;
@ -60,7 +62,9 @@ proptest! {
let unmined_transaction = UnminedTx::from(transaction);
let expected_request = mempool::Request::Queue(vec![unmined_transaction.into()]);
let response = mempool::Response::Queued(vec![Ok(())]);
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Ok(()));
let response = mempool::Response::Queued(vec![Ok(rsp_rx)]);
mempool
.expect_request(expected_request)
@ -110,10 +114,10 @@ proptest! {
.expect("Transaction serializes successfully");
let transaction_hex = hex::encode(&transaction_bytes);
let send_task = tokio::spawn(rpc.send_raw_transaction(transaction_hex));
let send_task = tokio::spawn(rpc.send_raw_transaction(transaction_hex.clone()));
let unmined_transaction = UnminedTx::from(transaction);
let expected_request = mempool::Request::Queue(vec![unmined_transaction.into()]);
let expected_request = mempool::Request::Queue(vec![unmined_transaction.clone().into()]);
mempool
.expect_request(expected_request)
@ -137,6 +141,32 @@ proptest! {
"Result is not a server error: {result:?}"
);
let send_task = tokio::spawn(rpc.send_raw_transaction(transaction_hex));
let expected_request = mempool::Request::Queue(vec![unmined_transaction.clone().into()]);
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Err("any verification error".into()));
mempool
.expect_request(expected_request)
.await?
.respond(Ok::<_, BoxError>(mempool::Response::Queued(vec![Ok(rsp_rx)])));
let result = send_task
.await
.expect("Sending raw transactions should not panic");
prop_assert!(
matches!(
result,
Err(Error {
code: ErrorCode::ServerError(_),
..
})
),
"Result is not a server error: {result:?}"
);
// The queue task should continue without errors or panics
let rpc_tx_queue_task_result = rpc_tx_queue_task_handle.now_or_never();
prop_assert!(rpc_tx_queue_task_result.is_none());
@ -553,19 +583,34 @@ proptest! {
NoChainTip,
);
let response = rpc.get_blockchain_info();
prop_assert_eq!(
&response.err().unwrap().message,
"No Chain tip available yet"
);
// The queue task should continue without errors or panics
let rpc_tx_queue_task_result = rpc_tx_queue_task_handle.now_or_never();
prop_assert!(rpc_tx_queue_task_result.is_none());
runtime.block_on(async move {
let response_fut = rpc.get_blockchain_info();
let mock_state_handler = {
let mut state = state.clone();
async move {
state
.expect_request(zebra_state::ReadRequest::TipPoolValues)
.await
.expect("getblockchaininfo should call mock state service with correct request")
.respond(Err(BoxError::from("no chain tip available yet")));
}
};
let (response, _) = tokio::join!(response_fut, mock_state_handler);
prop_assert_eq!(
&response.err().unwrap().message,
"no chain tip available yet"
);
// The queue task should continue without errors or panics
let rpc_tx_queue_task_result = rpc_tx_queue_task_handle.now_or_never();
prop_assert!(rpc_tx_queue_task_result.is_none());
mempool.expect_no_requests().await?;
state.expect_no_requests().await?;
Ok::<_, TestCaseError>(())
})?;
}
@ -581,17 +626,11 @@ proptest! {
let mut mempool = MockService::build().for_prop_tests();
let mut state: MockService<_, _, _, BoxError> = MockService::build().for_prop_tests();
// get block data
// get arbitrary chain tip data
let block_height = block.coinbase_height().unwrap();
let block_hash = block.hash();
let block_time = block.header.time;
// create a mocked `ChainTip`
let (chain_tip, mock_chain_tip_sender) = MockChainTip::new();
mock_chain_tip_sender.send_best_tip_height(block_height);
mock_chain_tip_sender.send_best_tip_hash(block_hash);
mock_chain_tip_sender.send_best_tip_block_time(block_time);
// Start RPC with the mocked `ChainTip`
let (rpc, rpc_tx_queue_task_handle) = RpcImpl::new(
"RPC test",
@ -601,50 +640,82 @@ proptest! {
true,
mempool.clone(),
Buffer::new(state.clone(), 1),
chain_tip,
NoChainTip,
);
let response = rpc.get_blockchain_info();
// Check response
match response {
Ok(info) => {
prop_assert_eq!(info.chain, network.bip70_network_name());
prop_assert_eq!(info.blocks, block_height);
prop_assert_eq!(info.best_block_hash, block_hash);
prop_assert!(info.estimated_height < Height::MAX);
prop_assert_eq!(
info.consensus.chain_tip.0,
NetworkUpgrade::current(&network, block_height)
.branch_id()
.unwrap()
);
prop_assert_eq!(
info.consensus.next_block.0,
NetworkUpgrade::current(&network, (block_height + 1).unwrap())
.branch_id()
.unwrap()
);
for u in info.upgrades {
let mut status = NetworkUpgradeStatus::Active;
if block_height < u.1.activation_height {
status = NetworkUpgradeStatus::Pending;
}
prop_assert_eq!(u.1.status, status);
}
}
Err(_) => {
unreachable!("Test should never error with the data we are feeding it")
}
};
// The queue task should continue without errors or panics
let rpc_tx_queue_task_result = rpc_tx_queue_task_handle.now_or_never();
prop_assert!(rpc_tx_queue_task_result.is_none());
// check no requests were made during this test
runtime.block_on(async move {
let response_fut = rpc.get_blockchain_info();
let mock_state_handler = {
let mut state = state.clone();
async move {
state
.expect_request(zebra_state::ReadRequest::TipPoolValues)
.await
.expect("getblockchaininfo should call mock state service with correct request")
.respond(zebra_state::ReadResponse::TipPoolValues {
tip_height: block_height,
tip_hash: block_hash,
value_balance: ValueBalance::default(),
});
state
.expect_request(zebra_state::ReadRequest::BlockHeader(block_hash.into()))
.await
.expect("getblockchaininfo should call mock state service with correct request")
.respond(zebra_state::ReadResponse::BlockHeader(Some(Arc::new(block::Header {
time: block_time,
version: Default::default(),
previous_block_hash: Default::default(),
merkle_root: Default::default(),
commitment_bytes: Default::default(),
difficulty_threshold: Default::default(),
nonce: Default::default(),
solution: Default::default()
}))));
}
};
let (response, _) = tokio::join!(response_fut, mock_state_handler);
// Check response
match response {
Ok(info) => {
prop_assert_eq!(info.chain, network.bip70_network_name());
prop_assert_eq!(info.blocks, block_height);
prop_assert_eq!(info.best_block_hash, block_hash);
prop_assert!(info.estimated_height < Height::MAX);
prop_assert_eq!(
info.consensus.chain_tip.0,
NetworkUpgrade::current(&network, block_height)
.branch_id()
.unwrap()
);
prop_assert_eq!(
info.consensus.next_block.0,
NetworkUpgrade::current(&network, (block_height + 1).unwrap())
.branch_id()
.unwrap()
);
for u in info.upgrades {
let mut status = NetworkUpgradeStatus::Active;
if block_height < u.1.activation_height {
status = NetworkUpgradeStatus::Pending;
}
prop_assert_eq!(u.1.status, status);
}
}
Err(_) => {
unreachable!("Test should never error with the data we are feeding it")
}
};
// The queue task should continue without errors or panics
let rpc_tx_queue_task_result = rpc_tx_queue_task_handle.now_or_never();
prop_assert!(rpc_tx_queue_task_result.is_none());
mempool.expect_no_requests().await?;
state.expect_no_requests().await?;
@ -855,7 +926,9 @@ proptest! {
// now a retry will be sent to the mempool
let expected_request =
mempool::Request::Queue(vec![mempool::Gossip::Tx(tx_unmined.clone())]);
let response = mempool::Response::Queued(vec![Ok(())]);
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Ok(()));
let response = mempool::Response::Queued(vec![Ok(rsp_rx)]);
mempool
.expect_request(expected_request)
@ -955,7 +1028,9 @@ proptest! {
for tx in txs.clone() {
let expected_request =
mempool::Request::Queue(vec![mempool::Gossip::Tx(UnminedTx::from(tx))]);
let response = mempool::Response::Queued(vec![Ok(())]);
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Ok(()));
let response = mempool::Response::Queued(vec![Ok(rsp_rx)]);
mempool
.expect_request(expected_request)

View File

@ -2,7 +2,7 @@
//!
//! To update these snapshots, run:
//! ```sh
//! cargo insta test --review -p zebra-rpc --lib -- test_rpc_response_data
//! cargo insta test --review --release -p zebra-rpc --lib -- test_rpc_response_data
//! ```
use std::collections::BTreeMap;
@ -15,7 +15,8 @@ use zebra_chain::{
chain_tip::mock::MockChainTip,
orchard,
parameters::{
testnet::{ConfiguredActivationHeights, Parameters},
subsidy::POST_NU6_FUNDING_STREAMS_TESTNET,
testnet::{self, ConfiguredActivationHeights, Parameters},
Network::Mainnet,
},
sapling,
@ -40,10 +41,19 @@ pub const EXCESSIVE_BLOCK_HEIGHT: u32 = MAX_ON_DISK_HEIGHT.0 + 1;
async fn test_rpc_response_data() {
let _init_guard = zebra_test::init();
let default_testnet = Network::new_default_testnet();
let nu6_testnet = testnet::Parameters::build()
.with_network_name("NU6Testnet")
.with_activation_heights(ConfiguredActivationHeights {
blossom: Some(584_000),
nu6: Some(POST_NU6_FUNDING_STREAMS_TESTNET.height_range().start.0),
..Default::default()
})
.to_network();
tokio::join!(
test_rpc_response_data_for_network(&Mainnet),
test_rpc_response_data_for_network(&default_testnet),
test_rpc_response_data_for_network(&nu6_testnet),
test_mocked_rpc_response_data_for_network(&Mainnet),
test_mocked_rpc_response_data_for_network(&default_testnet),
);
@ -196,6 +206,17 @@ async fn test_rpc_response_data_for_network(network: &Network) {
latest_chain_tip,
);
// We only want a snapshot of the `getblocksubsidy` and `getblockchaininfo` methods for the non-default Testnet (with an NU6 activation height).
if network.is_a_test_network() && !network.is_default_testnet() {
let get_blockchain_info = rpc
.get_blockchain_info()
.await
.expect("We should have a GetBlockChainInfo struct");
snapshot_rpc_getblockchaininfo("_future_nu6_height", get_blockchain_info, &settings);
return;
}
// `getinfo`
let get_info = rpc.get_info().expect("We should have a GetInfo struct");
snapshot_rpc_getinfo(get_info, &settings);
@ -203,8 +224,9 @@ async fn test_rpc_response_data_for_network(network: &Network) {
// `getblockchaininfo`
let get_blockchain_info = rpc
.get_blockchain_info()
.await
.expect("We should have a GetBlockChainInfo struct");
snapshot_rpc_getblockchaininfo(get_blockchain_info, &settings);
snapshot_rpc_getblockchaininfo("", get_blockchain_info, &settings);
// get the first transaction of the first block which is not the genesis
let first_block_first_transaction = &blocks[1].transactions[0];
@ -531,9 +553,13 @@ fn snapshot_rpc_getinfo(info: GetInfo, settings: &insta::Settings) {
}
/// Snapshot `getblockchaininfo` response, using `cargo insta` and JSON serialization.
fn snapshot_rpc_getblockchaininfo(info: GetBlockChainInfo, settings: &insta::Settings) {
fn snapshot_rpc_getblockchaininfo(
variant_suffix: &str,
info: GetBlockChainInfo,
settings: &insta::Settings,
) {
settings.bind(|| {
insta::assert_json_snapshot!("get_blockchain_info", info, {
insta::assert_json_snapshot!(format!("get_blockchain_info{variant_suffix}"), info, {
".estimatedheight" => dynamic_redaction(|value, _path| {
// assert that the value looks like a valid height here
assert!(u32::try_from(value.as_u64().unwrap()).unwrap() < Height::MAX_AS_U32);

View File

@ -148,6 +148,18 @@ pub async fn test_responses<State, ReadState>(
mock_address_book,
);
if network.is_a_test_network() && !network.is_default_testnet() {
let fake_future_nu6_block_height =
NetworkUpgrade::Nu6.activation_height(network).unwrap().0 + 100_000;
let get_block_subsidy = get_block_template_rpc
.get_block_subsidy(Some(fake_future_nu6_block_height))
.await
.expect("We should have a success response");
snapshot_rpc_getblocksubsidy("future_nu6_height", get_block_subsidy, &settings);
// We only want a snapshot of the `getblocksubsidy` method for the non-default Testnet (with an NU6 activation height).
return;
}
// `getblockcount`
let get_block_count = get_block_template_rpc
.get_block_count()

View File

@ -3,7 +3,9 @@ source: zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs
expression: get_block_subsidy
---
{
"fundingstreams": [],
"miner": 0.00610351,
"founders": 0.0
"founders": 0.0,
"fundingstreamstotal": 0.0,
"lockboxtotal": 0.0,
"totalblocksubsidy": 0.00610351
}

View File

@ -3,7 +3,9 @@ source: zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs
expression: get_block_subsidy
---
{
"fundingstreams": [],
"miner": 0.00610351,
"founders": 0.0
"founders": 0.0,
"fundingstreamstotal": 0.0,
"lockboxtotal": 0.0,
"totalblocksubsidy": 0.00610351
}

View File

@ -27,5 +27,8 @@ expression: get_block_subsidy
}
],
"miner": 2.5,
"founders": 0.0
"founders": 0.0,
"fundingstreamstotal": 0.625,
"lockboxtotal": 0.0,
"totalblocksubsidy": 3.125
}

View File

@ -27,5 +27,8 @@ expression: get_block_subsidy
}
],
"miner": 2.5,
"founders": 0.0
"founders": 0.0,
"fundingstreamstotal": 0.625,
"lockboxtotal": 0.0,
"totalblocksubsidy": 3.125
}

View File

@ -0,0 +1,28 @@
---
source: zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs
expression: get_block_subsidy
---
{
"fundingstreams": [
{
"recipient": "Zcash Community Grants NU6",
"specification": "https://zips.z.cash/draft-nuttycom-funding-allocation#alternative-2-hybrid-deferred-dev-fund-transitioning-to-a-non-direct-funding-model",
"value": 0.125,
"valueZat": 12500000,
"address": "t2HifwjUj9uyxr9bknR8LFuQbc98c3vkXtu"
}
],
"lockboxstreams": [
{
"recipient": "Lockbox NU6",
"specification": "https://zips.z.cash/draft-nuttycom-funding-allocation#alternative-2-hybrid-deferred-dev-fund-transitioning-to-a-non-direct-funding-model",
"value": 0.1875,
"valueZat": 18750000
}
],
"miner": 1.25,
"founders": 0.0,
"fundingstreamstotal": 0.125,
"lockboxtotal": 0.1875,
"totalblocksubsidy": 1.5625
}

View File

@ -27,5 +27,8 @@ expression: get_block_subsidy
}
],
"miner": 2.5,
"founders": 0.0
"founders": 0.0,
"fundingstreamstotal": 0.625,
"lockboxtotal": 0.0,
"totalblocksubsidy": 3.125
}

View File

@ -27,5 +27,8 @@ expression: get_block_subsidy
}
],
"miner": 2.5,
"founders": 0.0
"founders": 0.0,
"fundingstreamstotal": 0.625,
"lockboxtotal": 0.0,
"totalblocksubsidy": 3.125
}

View File

@ -1,10 +0,0 @@
---
source: zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs
expression: difficulty
---
{
"Err": {
"code": 0,
"message": "Zebra's state only has a few blocks, wait until it syncs to the chain tip"
}
}

View File

@ -7,6 +7,33 @@ expression: info
"blocks": 10,
"bestblockhash": "00074c46a4aa8172df8ae2ad1848a2e084e1b6989b7d9e6132adc938bf835b36",
"estimatedheight": "[Height]",
"valuePools": [
{
"id": "transparent",
"chainValue": 0.034375,
"chainValueZat": 3437500
},
{
"id": "sprout",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "sapling",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "orchard",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "deferred",
"chainValue": 0.0,
"chainValueZat": 0
}
],
"upgrades": {
"5ba81b19": {
"name": "Overwinter",

View File

@ -7,6 +7,33 @@ expression: info
"blocks": 10,
"bestblockhash": "079f4c752729be63e6341ee9bce42fbbe37236aba22e3deb82405f3c2805c112",
"estimatedheight": "[Height]",
"valuePools": [
{
"id": "transparent",
"chainValue": 0.034375,
"chainValueZat": 3437500
},
{
"id": "sprout",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "sapling",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "orchard",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "deferred",
"chainValue": 0.0,
"chainValueZat": 0
}
],
"upgrades": {
"5ba81b19": {
"name": "Overwinter",
@ -37,6 +64,11 @@ expression: info
"name": "NU5",
"activationheight": 1842420,
"status": "pending"
},
"c8e71055": {
"name": "Nu6",
"activationheight": 2976000,
"status": "pending"
}
},
"consensus": {

View File

@ -0,0 +1,78 @@
---
source: zebra-rpc/src/methods/tests/snapshot.rs
expression: info
---
{
"chain": "test",
"blocks": 10,
"bestblockhash": "079f4c752729be63e6341ee9bce42fbbe37236aba22e3deb82405f3c2805c112",
"estimatedheight": "[Height]",
"valuePools": [
{
"id": "transparent",
"chainValue": 0.034375,
"chainValueZat": 3437500
},
{
"id": "sprout",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "sapling",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "orchard",
"chainValue": 0.0,
"chainValueZat": 0
},
{
"id": "deferred",
"chainValue": 0.0,
"chainValueZat": 0
}
],
"upgrades": {
"5ba81b19": {
"name": "Overwinter",
"activationheight": 584000,
"status": "pending"
},
"76b809bb": {
"name": "Sapling",
"activationheight": 584000,
"status": "pending"
},
"2bb40e60": {
"name": "Blossom",
"activationheight": 584000,
"status": "pending"
},
"f5b9230b": {
"name": "Heartwood",
"activationheight": 2976000,
"status": "pending"
},
"e9ff75a6": {
"name": "Canopy",
"activationheight": 2976000,
"status": "pending"
},
"c2d6d0b4": {
"name": "NU5",
"activationheight": 2976000,
"status": "pending"
},
"c8e71055": {
"name": "Nu6",
"activationheight": 2976000,
"status": "pending"
}
},
"consensus": {
"chaintip": "00000000",
"nextblock": "00000000"
}
}

View File

@ -0,0 +1,7 @@
//! Types used in RPC methods.
mod get_blockchain_info;
mod zec;
pub use get_blockchain_info::ValuePoolBalance;
pub use zec::Zec;

View File

@ -0,0 +1,72 @@
//! Types used in `getblockchaininfo` RPC method.
use zebra_chain::{
amount::{Amount, NonNegative},
value_balance::ValueBalance,
};
use super::*;
/// A value pool's balance in Zec and Zatoshis
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ValuePoolBalance {
/// Name of the pool
id: String,
/// Total amount in the pool, in ZEC
chain_value: Zec<NonNegative>,
/// Total amount in the pool, in zatoshis
chain_value_zat: Amount<NonNegative>,
}
impl ValuePoolBalance {
/// Returns a list of [`ValuePoolBalance`]s converted from the default [`ValueBalance`].
pub fn zero_pools() -> [Self; 5] {
Self::from_value_balance(Default::default())
}
/// Creates a new [`ValuePoolBalance`] from a pool name and its value balance.
pub fn new(id: impl ToString, amount: Amount<NonNegative>) -> Self {
Self {
id: id.to_string(),
chain_value: Zec::from(amount),
chain_value_zat: amount,
}
}
/// Creates a [`ValuePoolBalance`] for the transparent pool.
pub fn transparent(amount: Amount<NonNegative>) -> Self {
Self::new("transparent", amount)
}
/// Creates a [`ValuePoolBalance`] for the Sprout pool.
pub fn sprout(amount: Amount<NonNegative>) -> Self {
Self::new("sprout", amount)
}
/// Creates a [`ValuePoolBalance`] for the Sapling pool.
pub fn sapling(amount: Amount<NonNegative>) -> Self {
Self::new("sapling", amount)
}
/// Creates a [`ValuePoolBalance`] for the Orchard pool.
pub fn orchard(amount: Amount<NonNegative>) -> Self {
Self::new("orchard", amount)
}
/// Creates a [`ValuePoolBalance`] for the Deferred pool.
pub fn deferred(amount: Amount<NonNegative>) -> Self {
Self::new("deferred", amount)
}
/// Converts a [`ValueBalance`] to a list of [`ValuePoolBalance`]s.
pub fn from_value_balance(value_balance: ValueBalance<NonNegative>) -> [Self; 5] {
[
Self::transparent(value_balance.transparent_amount()),
Self::sprout(value_balance.sprout_amount()),
Self::sapling(value_balance.sapling_amount()),
Self::orchard(value_balance.orchard_amount()),
Self::deferred(value_balance.deferred_amount()),
]
}
}

View File

@ -37,7 +37,7 @@ pub const MAX_ZEC_FORMAT_PRECISION: usize = 8;
/// Unlike `zcashd`, Zebra doesn't have control over its JSON number precision,
/// because it uses `serde_json`'s formatter. But `zcashd` uses a fixed-point calculation:
/// <https://github.com/zcash/zcash/blob/f6a4f68115ea4c58d55c8538579d0877ba9c8f79/src/rpc/server.cpp#L134>
#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
#[derive(Clone, Copy, serde::Serialize, serde::Deserialize, Default)]
#[serde(try_from = "f64")]
#[serde(into = "f64")]
#[serde(bound = "C: Constraint + Clone")]

View File

@ -5,7 +5,7 @@ use std::{collections::HashSet, env, sync::Arc};
use proptest::prelude::*;
use chrono::Duration;
use tokio::time;
use tokio::{sync::oneshot, time};
use tower::ServiceExt;
use zebra_chain::{
@ -196,7 +196,9 @@ proptest! {
let request = Request::Queue(vec![Gossip::Tx(unmined_transaction.clone())]);
let expected_request = Request::Queue(vec![Gossip::Tx(unmined_transaction.clone())]);
let send_task = tokio::spawn(mempool.clone().oneshot(request));
let response = Response::Queued(vec![Ok(())]);
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Ok(()));
let response = Response::Queued(vec![Ok(rsp_rx)]);
mempool
.expect_request(expected_request)
@ -337,7 +339,9 @@ proptest! {
// retry will queue the transaction to mempool
let gossip = Gossip::Tx(UnminedTx::from(transaction.clone()));
let expected_request = Request::Queue(vec![gossip]);
let response = Response::Queued(vec![Ok(())]);
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Ok(()));
let response = Response::Queued(vec![Ok(rsp_rx)]);
mempool
.expect_request(expected_request)

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-scan"
version = "0.1.0-alpha.7"
version = "0.1.0-alpha.8"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Shielded transaction scanner for the Zcash blockchain"
license = "MIT OR Apache-2.0"
@ -70,17 +70,19 @@ tower = "0.4.13"
tracing = "0.1.39"
futures = "0.3.30"
zcash_client_backend = { version = "0.12.1" }
zcash_keys = { version = "0.2.0", features = ["sapling"] }
zcash_primitives = "0.15.0"
zcash_address = "0.3.2"
sapling = { package = "sapling-crypto", version = "0.1" }
# ECC dependencies.
# TODO: we can't use the workspace version for all ECC dependencies in this crate yet (#8809)
zcash_client_backend = { git = "https://github.com/zcash/librustzcash/", commit = "40ca428c6081c61d5a2bf3f2053eb9e18219ca95" }
zcash_keys = { workspace = true, features = ["sapling"] }
zcash_primitives = { git = "https://github.com/zcash/librustzcash/", commit = "40ca428c6081c61d5a2bf3f2053eb9e18219ca95" }
zcash_address = { git = "https://github.com/zcash/librustzcash/", commit = "40ca428c6081c61d5a2bf3f2053eb9e18219ca95" }
sapling-crypto.workspace = true
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = ["shielded-scan"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38", features = ["shielded-scan"] }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.38", features = ["shielded-scan"] }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.5" }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.38" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["shielded-scan"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["shielded-scan"] }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = ["shielded-scan"] }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.6" }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39" }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
@ -95,7 +97,7 @@ jubjub = { version = "0.10.0", optional = true }
rand = { version = "0.8.5", optional = true }
zcash_note_encryption = { version = "0.4.0", optional = true }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.38", optional = true }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39", optional = true }
# zebra-scanner binary dependencies
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
@ -106,7 +108,7 @@ serde_json = "1.0.122"
jsonrpc = { version = "0.18.0", optional = true }
hex = { version = "0.4.3", optional = true }
zebrad = { path = "../zebrad", version = "1.8.0" }
zebrad = { path = "../zebrad", version = "1.8.1" }
[dev-dependencies]
insta = { version = "1.39.0", features = ["ron", "redactions"] }
@ -124,6 +126,6 @@ zcash_note_encryption = "0.4.0"
toml = "0.8.19"
tonic = "0.12.1"
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.38" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" }

View File

@ -23,4 +23,4 @@ pub mod tests;
pub use config::Config;
pub use init::{init_with_server, spawn_init};
pub use sapling::{zip32::DiversifiableFullViewingKey, SaplingIvk};
pub use sapling_crypto::{zip32::DiversifiableFullViewingKey, SaplingIvk};

View File

@ -8,7 +8,7 @@ use tokio::sync::{
oneshot,
};
use sapling::zip32::DiversifiableFullViewingKey;
use sapling_crypto::zip32::DiversifiableFullViewingKey;
use zebra_chain::{block::Height, parameters::Network};
use zebra_node_services::scan_service::response::ScanResult;
use zebra_state::SaplingScanningKey;

View File

@ -27,7 +27,7 @@ use zcash_client_backend::{
};
use zcash_primitives::zip32::{AccountId, Scope};
use sapling::zip32::DiversifiableFullViewingKey;
use sapling_crypto::zip32::DiversifiableFullViewingKey;
use zebra_chain::{
block::{Block, Height},

View File

@ -7,7 +7,7 @@ use crate::{
storage::Storage,
};
use color_eyre::eyre::Report;
use sapling::zip32::DiversifiableFullViewingKey;
use sapling_crypto::zip32::DiversifiableFullViewingKey;
use tokio::{
sync::{mpsc::Sender, watch},
task::JoinHandle,

View File

@ -1,4 +1,3 @@
//! Test that we can scan the Zebra blockchain using the external `zcash_client_backend` crate
//! scanning functionality.
//!
//! This tests belong to the proof of concept stage of the external wallet support functionality.
@ -21,7 +20,7 @@ use zcash_client_backend::{
use zcash_note_encryption::Domain;
use zcash_primitives::{block::BlockHash, consensus::BlockHeight, memo::MemoBytes};
use ::sapling::{
use ::sapling_crypto::{
constants::SPENDING_KEY_GENERATOR,
note_encryption::{sapling_note_encryption, SaplingDomain},
util::generate_random_rseed,
@ -170,7 +169,10 @@ pub fn fake_compact_block(
// Create a fake Note for the account
let mut rng = OsRng;
let rseed = generate_random_rseed(::sapling::note_encryption::Zip212Enforcement::Off, &mut rng);
let rseed = generate_random_rseed(
::sapling_crypto::note_encryption::Zip212Enforcement::Off,
&mut rng,
);
let note = Note::from_parts(to, NoteValue::from_raw(value), rseed);
let encryptor = sapling_note_encryption::<_>(

View File

@ -4,7 +4,7 @@ use std::sync::Arc;
use color_eyre::Result;
use sapling::{
use sapling_crypto::{
zip32::{DiversifiableFullViewingKey, ExtendedSpendingKey},
Nullifier,
};

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-script"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
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.38" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" }
thiserror = "1.0.63"
[dev-dependencies]
hex = "0.4.3"
lazy_static = "1.4.0"
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.38" }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" }

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-state"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "State contextual verification and storage code for Zebra"
license = "MIT OR Apache-2.0"
@ -77,13 +77,13 @@ tracing = "0.1.39"
elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true }
serde_json = { version = "1.0.122", package = "serde_json", optional = true }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = ["async-error"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", 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.38", optional = true }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39", optional = true }
proptest = { version = "1.4.0", optional = true }
proptest-derive = { version = "0.5.0", optional = true }
@ -108,5 +108,5 @@ jubjub = "0.10.0"
tokio = { version = "1.39.2", features = ["full", "tracing", "test-util"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.38" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.39" }

View File

@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use tokio::task::{spawn_blocking, JoinHandle};
use tracing::Span;
use zebra_chain::parameters::Network;
use zebra_chain::{common::default_cache_dir, parameters::Network};
use crate::{
constants::{DATABASE_FORMAT_VERSION_FILE_NAME, RESTORABLE_DB_VERSIONS, STATE_DATABASE_KIND},
@ -173,12 +173,8 @@ impl Config {
impl Default for Config {
fn default() -> Self {
let cache_dir = dirs::cache_dir()
.unwrap_or_else(|| std::env::current_dir().unwrap().join("cache"))
.join("zebra");
Self {
cache_dir,
cache_dir: default_cache_dir(),
ephemeral: false,
delete_old_database: true,
debug_stop_at_height: None,
@ -471,6 +467,8 @@ pub(crate) use hidden::{
pub(crate) mod hidden {
#![allow(dead_code)]
use zebra_chain::common::atomic_write;
use super::*;
/// Writes `changed_version` to the on-disk state database after the format is changed.
@ -512,10 +510,9 @@ pub(crate) mod hidden {
let version = format!("{}.{}", changed_version.minor, changed_version.patch);
// # Concurrency
//
// The caller handles locking for this file write.
fs::write(version_path, version.as_bytes())?;
// Write the version file atomically so the cache is not corrupted if Zebra shuts down or
// crashes.
atomic_write(version_path, version.as_bytes())??;
Ok(())
}

View File

@ -815,6 +815,10 @@ pub enum ReadRequest {
/// with the current best chain tip.
Tip,
/// Returns [`ReadResponse::TipPoolValues(Option<(Height, block::Hash, ValueBalance)>)`](ReadResponse::TipPoolValues)
/// with the current best chain tip.
TipPoolValues,
/// Computes the depth in the current best chain of the block identified by the given hash.
///
/// Returns
@ -1065,6 +1069,7 @@ impl ReadRequest {
fn variant_name(&self) -> &'static str {
match self {
ReadRequest::Tip => "tip",
ReadRequest::TipPoolValues => "tip_pool_values",
ReadRequest::Depth(_) => "depth",
ReadRequest::Block(_) => "block",
ReadRequest::BlockHeader(_) => "block_header",

View File

@ -10,6 +10,7 @@ use zebra_chain::{
subtree::{NoteCommitmentSubtreeData, NoteCommitmentSubtreeIndex},
transaction::{self, Transaction},
transparent,
value_balance::ValueBalance,
};
#[cfg(feature = "getblocktemplate-rpcs")]
@ -128,6 +129,17 @@ pub enum ReadResponse {
/// Response to [`ReadRequest::Tip`] with the current best chain tip.
Tip(Option<(block::Height, block::Hash)>),
/// Response to [`ReadRequest::TipPoolValues`] with
/// the current best chain tip and its [`ValueBalance`].
TipPoolValues {
/// The current best chain tip height.
tip_height: block::Height,
/// The current best chain tip hash.
tip_hash: block::Hash,
/// The value pool balance at the current best chain tip.
value_balance: ValueBalance<NonNegative>,
},
/// Response to [`ReadRequest::Depth`] with the depth of the specified block.
Depth(Option<u32>),
@ -287,7 +299,8 @@ impl TryFrom<ReadResponse> for Response {
ReadResponse::ValidBestChainTipNullifiersAndAnchors => Ok(Response::ValidBestChainTipNullifiersAndAnchors),
ReadResponse::TransactionIdsForBlock(_)
ReadResponse::TipPoolValues { .. }
| ReadResponse::TransactionIdsForBlock(_)
| ReadResponse::SaplingTree(_)
| ReadResponse::OrchardTree(_)
| ReadResponse::SaplingSubtrees(_)

View File

@ -1192,6 +1192,38 @@ impl Service<ReadRequest> for ReadStateService {
.wait_for_panics()
}
// Used by `getblockchaininfo` RPC method.
ReadRequest::TipPoolValues => {
let state = self.clone();
tokio::task::spawn_blocking(move || {
span.in_scope(move || {
let tip_with_value_balance = state
.non_finalized_state_receiver
.with_watch_data(|non_finalized_state| {
read::tip_with_value_balance(
non_finalized_state.best_chain(),
&state.db,
)
});
// The work is done in the future.
// TODO: Do this in the Drop impl with the variant name?
timer.finish(module_path!(), line!(), "ReadRequest::TipPoolValues");
let (tip_height, tip_hash, value_balance) = tip_with_value_balance?
.ok_or(BoxError::from("no chain tip available yet"))?;
Ok(ReadResponse::TipPoolValues {
tip_height,
tip_hash,
value_balance,
})
})
})
.wait_for_panics()
}
// Used by the StateService.
ReadRequest::Depth(hash) => {
let state = self.clone();

View File

@ -482,6 +482,17 @@ impl Chain {
)
}
/// Returns the non-finalized tip block height, hash, and total pool value balances.
pub fn non_finalized_tip_with_value_balance(
&self,
) -> (Height, block::Hash, ValueBalance<NonNegative>) {
(
self.non_finalized_tip_height(),
self.non_finalized_tip_hash(),
self.chain_value_pools,
)
}
/// Returns the Sprout note commitment tree of the tip of this [`Chain`],
/// including all finalized notes, and the non-finalized notes in this chain.
///

View File

@ -36,7 +36,7 @@ pub use block::{
pub use find::{
best_tip, block_locator, depth, finalized_state_contains_block_hash, find_chain_hashes,
find_chain_headers, hash_by_height, height_by_hash, next_median_time_past,
non_finalized_state_contains_block_hash, tip, tip_height,
non_finalized_state_contains_block_hash, tip, tip_height, tip_with_value_balance,
};
pub use tree::{orchard_subtrees, orchard_tree, sapling_subtrees, sapling_tree};

View File

@ -19,8 +19,10 @@ use std::{
use chrono::{DateTime, Utc};
use zebra_chain::{
amount::NonNegative,
block::{self, Block, Height},
serialization::DateTime32,
value_balance::ValueBalance,
};
use crate::{
@ -82,6 +84,40 @@ where
tip(chain, db).map(|(_height, hash)| hash)
}
/// Returns the tip of `chain` with its [`ValueBalance`].
/// If there is no chain, returns the tip of `db`.
pub fn tip_with_value_balance<C>(
chain: Option<C>,
db: &ZebraDb,
) -> Result<Option<(Height, block::Hash, ValueBalance<NonNegative>)>, BoxError>
where
C: AsRef<Chain>,
{
match chain.map(|chain| chain.as_ref().non_finalized_tip_with_value_balance()) {
tip_with_value_balance @ Some(_) => Ok(tip_with_value_balance),
None => {
// Retry the finalized state query if it was interrupted by a finalizing block.
//
// TODO: refactor this into a generic retry(finalized_closure, process_and_check_closure) fn
for _ in 0..=FINALIZED_STATE_QUERY_RETRIES {
let tip @ Some((tip_height, tip_hash)) = db.tip() else {
return Ok(None);
};
let value_balance = db.finalized_value_pool();
if tip == db.tip() {
return Ok(Some((tip_height, tip_hash, value_balance)));
}
}
Err("Zebra is committing too many blocks to the state, \
wait until it syncs to the chain tip"
.into())
}
}
}
/// Return the depth of block `hash` from the chain tip.
/// Searches `chain` for `hash`, then searches `db`.
pub fn depth<C>(chain: Option<C>, db: &ZebraDb, hash: block::Hash) -> Option<u32>

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-test"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Test harnesses and test vectors for Zebra"
license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-utils"
version = "1.0.0-beta.38"
version = "1.0.0-beta.39"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Developer tools for Zebra maintenance and testing"
license = "MIT OR Apache-2.0"
@ -94,11 +94,11 @@ tracing-error = "0.2.0"
tracing-subscriber = "0.3.18"
thiserror = "1.0.63"
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.38" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" }
# These crates are needed for the block-template-to-proposal binary
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.38", optional = true }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39", optional = true }
# These crates are needed for the zebra-checkpoints binary
itertools = { version = "0.13.0", optional = true }
@ -113,9 +113,9 @@ tokio = { version = "1.39.2", features = ["full"], optional = true }
jsonrpc = { version = "0.18.0", optional = true }
zcash_primitives = { version = "0.15.0", optional = true }
zcash_client_backend = { version = "0.12.1", optional = true }
zcash_protocol = { version = "0.1.1" }
zcash_primitives = { workspace = true, optional = true }
zcash_client_backend = { workspace = true, optional = true }
zcash_protocol.workspace = true
# For the openapi generator
rand = "0.8.5"
@ -123,3 +123,5 @@ syn = { version = "2.0.72", features = ["full"], optional = true }
quote = { version = "1.0.36", optional = true }
serde_yaml = { version = "0.9.34+deprecated", optional = true }
serde = { version = "1.0.204", features = ["serde_derive"], optional = true }
indexmap = "2.3.0"

View File

@ -1,7 +1,8 @@
//! Generate an openapi.yaml file from the Zebra RPC methods
use std::{collections::HashMap, error::Error, fs::File, io::Write};
use std::{error::Error, fs::File, io::Write};
use indexmap::IndexMap;
use quote::ToTokens;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use serde::Serialize;
@ -15,7 +16,7 @@ const SERVER: &str = "http://localhost:8232";
// The API methods
#[derive(Serialize, Debug)]
struct Methods {
paths: HashMap<String, HashMap<String, MethodConfig>>,
paths: IndexMap<String, IndexMap<String, MethodConfig>>,
}
// The configuration for each method
@ -25,7 +26,7 @@ struct MethodConfig {
description: String,
#[serde(rename = "requestBody")]
request_body: RequestBody,
responses: HashMap<String, Response>,
responses: IndexMap<String, Response>,
}
// The request body
@ -53,7 +54,7 @@ struct Application {
struct Schema {
#[serde(rename = "type")]
type_: String,
properties: HashMap<String, Property>,
properties: IndexMap<String, Property>,
}
// The properties of the request body
@ -95,8 +96,8 @@ fn main() -> Result<(), Box<dyn Error>> {
),
];
// Create a hashmap to store the method names and configuration
let mut methods = HashMap::new();
// Create an indexmap to store the method names and configuration
let mut methods = IndexMap::new();
for zebra_rpc_methods_path in paths {
// Read the source code from the file
@ -105,8 +106,8 @@ fn main() -> Result<(), Box<dyn Error>> {
// Parse the source code into a syn AST
let syn_file = syn::parse_file(&source_code)?;
// Create a hashmap to store the methods configuration
let mut methods_config = HashMap::new();
// Create an indexmap to store the methods configuration
let mut methods_config = IndexMap::new();
// Iterate over items in the file looking for traits
for item in &syn_file.items {
@ -150,7 +151,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// Create the responses
let responses = create_responses(&method_name, have_parameters)?;
// Add the method configuration to the hashmap
// Add the method configuration to the indexmap
methods_config.insert(
request_type,
MethodConfig {
@ -161,7 +162,7 @@ fn main() -> Result<(), Box<dyn Error>> {
},
);
// Add the method name and configuration to the hashmap
// Add the method name and configuration to the indexmap
methods.insert(format!("/{}", method_name), methods_config.clone());
}
}
@ -371,7 +372,7 @@ fn create_request_body(method_name: &str, parameters_example: &str) -> RequestBo
};
// Create the schema and add the first 2 properties
let mut schema = HashMap::new();
let mut schema = IndexMap::new();
schema.insert("method".to_string(), method_name_prop);
schema.insert("id".to_string(), request_id_prop);
@ -406,8 +407,8 @@ fn create_request_body(method_name: &str, parameters_example: &str) -> RequestBo
fn create_responses(
method_name: &str,
have_parameters: bool,
) -> Result<HashMap<String, Response>, Box<dyn Error>> {
let mut responses = HashMap::new();
) -> Result<IndexMap<String, Response>, Box<dyn Error>> {
let mut responses = IndexMap::new();
let properties = get_default_properties(method_name)?;
@ -424,7 +425,7 @@ fn create_responses(
};
responses.insert("200".to_string(), res_ok);
let mut properties = HashMap::new();
let mut properties = IndexMap::new();
if have_parameters {
properties.insert(
"error".to_string(),
@ -473,10 +474,10 @@ fn default_property<T: serde::Serialize>(
// Get requests examples by using defaults from the Zebra RPC methods
// TODO: Make this function more concise/readable (https://github.com/ZcashFoundation/zebra/pull/8616#discussion_r1643193949)
fn get_default_properties(method_name: &str) -> Result<HashMap<String, Property>, Box<dyn Error>> {
fn get_default_properties(method_name: &str) -> Result<IndexMap<String, Property>, Box<dyn Error>> {
let type_ = "object";
let items = None;
let mut props = HashMap::new();
let mut props = IndexMap::new();
// TODO: An entry has to be added here manually for each new RPC method introduced, can we automate?
let default_result = match method_name {

View File

@ -1,7 +1,7 @@
[package]
# Crate metadata
name = "zebrad"
version = "1.8.0"
version = "1.9.0"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "The Zcash Foundation's independent, consensus-compatible implementation of a Zcash node"
license = "MIT OR Apache-2.0"
@ -157,15 +157,15 @@ test_sync_past_mandatory_checkpoint_mainnet = []
test_sync_past_mandatory_checkpoint_testnet = []
[dependencies]
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.38" }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.38" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.38" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.38", features = ["rpc-client"] }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.38" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39" }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.39", features = ["rpc-client"] }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.39" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39" }
# Required for crates.io publishing, but it's only used in tests
zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.38", optional = true }
zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.39", optional = true }
abscissa_core = "0.7.0"
clap = { version = "4.5.13", features = ["cargo"] }
@ -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.38", features = ["proptest-impl"] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.38", features = ["proptest-impl"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.39", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.38" }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.5" }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.39" }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.6" }
# 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.5" }
# 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.38" }
zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.39" }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }

View File

@ -27,7 +27,7 @@ use std::{
};
use futures::{future::FutureExt, stream::Stream};
use tokio::sync::broadcast;
use tokio::sync::{broadcast, oneshot};
use tokio_stream::StreamExt;
use tower::{buffer::Buffer, timeout::Timeout, util::BoxService, Service};
@ -560,7 +560,7 @@ impl Service<Request> for Mempool {
for tx in tx_retries {
// This is just an efficiency optimisation, so we don't care if queueing
// transaction requests fails.
let _result = tx_downloads.download_if_needed_and_verify(tx);
let _result = tx_downloads.download_if_needed_and_verify(tx, None);
}
}
@ -608,8 +608,8 @@ impl Service<Request> for Mempool {
tracing::trace!("chain grew during tx verification, retrying ..",);
// We don't care if re-queueing the transaction request fails.
let _result =
tx_downloads.download_if_needed_and_verify(tx.transaction.into());
let _result = tx_downloads
.download_if_needed_and_verify(tx.transaction.into(), None);
}
}
Ok(Err((txid, error))) => {
@ -758,16 +758,24 @@ impl Service<Request> for Mempool {
Request::Queue(gossiped_txs) => {
trace!(req_count = ?gossiped_txs.len(), "got mempool Queue request");
let rsp: Vec<Result<(), BoxError>> = gossiped_txs
.into_iter()
.map(|gossiped_tx| -> Result<(), MempoolError> {
storage.should_download_or_verify(gossiped_tx.id())?;
tx_downloads.download_if_needed_and_verify(gossiped_tx)?;
let rsp: Vec<Result<oneshot::Receiver<Result<(), BoxError>>, BoxError>> =
gossiped_txs
.into_iter()
.map(
|gossiped_tx| -> Result<
oneshot::Receiver<Result<(), BoxError>>,
MempoolError,
> {
let (rsp_tx, rsp_rx) = oneshot::channel();
storage.should_download_or_verify(gossiped_tx.id())?;
tx_downloads
.download_if_needed_and_verify(gossiped_tx, Some(rsp_tx))?;
Ok(())
})
.map(|result| result.map_err(BoxError::from))
.collect();
Ok(rsp_rx)
},
)
.map(|result| result.map_err(BoxError::from))
.collect();
// We've added transactions to the queue
self.update_metrics();

View File

@ -6,7 +6,7 @@ use proptest::{
collection::{hash_set, vec},
prelude::*,
};
use tokio::time;
use tokio::{sync::oneshot, time};
use zebra_chain::{
chain_sync_status::ChainSyncStatus, parameters::Network, transaction::UnminedTxId,
@ -317,9 +317,17 @@ async fn respond_to_queue_request(
expected_transaction_ids: HashSet<UnminedTxId>,
response: impl IntoIterator<Item = Result<(), MempoolError>>,
) -> Result<(), TestCaseError> {
let response = response
let response: Vec<Result<oneshot::Receiver<Result<(), BoxError>>, BoxError>> = response
.into_iter()
.map(|result| result.map_err(BoxError::from))
.map(|result| {
result
.map(|_| {
let (rsp_tx, rsp_rx) = oneshot::channel();
let _ = rsp_tx.send(Ok(()));
rsp_rx
})
.map_err(BoxError::from)
})
.collect();
mempool

View File

@ -51,7 +51,7 @@ use zebra_chain::{
use zebra_consensus::transaction as tx;
use zebra_network as zn;
use zebra_node_services::mempool::Gossip;
use zebra_state as zs;
use zebra_state::{self as zs, CloneError};
use crate::components::sync::{BLOCK_DOWNLOAD_TIMEOUT, BLOCK_VERIFY_TIMEOUT};
@ -105,17 +105,17 @@ pub const MAX_INBOUND_CONCURRENCY: usize = 25;
struct CancelDownloadAndVerify;
/// Errors that can occur while downloading and verifying a transaction.
#[derive(Error, Debug)]
#[derive(Error, Debug, Clone)]
#[allow(dead_code)]
pub enum TransactionDownloadVerifyError {
#[error("transaction is already in state")]
InState,
#[error("error in state service")]
StateError(#[source] BoxError),
StateError(#[source] CloneError),
#[error("error downloading transaction")]
DownloadFailed(#[source] BoxError),
DownloadFailed(#[source] CloneError),
#[error("transaction download / verification was cancelled")]
Cancelled,
@ -243,6 +243,7 @@ where
pub fn download_if_needed_and_verify(
&mut self,
gossiped_tx: Gossip,
rsp_tx: Option<oneshot::Sender<Result<(), BoxError>>>,
) -> Result<(), MempoolError> {
let txid = gossiped_tx.id();
@ -295,7 +296,7 @@ where
Ok((Some(height), next_height))
}
Ok(_) => unreachable!("wrong response"),
Err(e) => Err(TransactionDownloadVerifyError::StateError(e)),
Err(e) => Err(TransactionDownloadVerifyError::StateError(e.into())),
}?;
trace!(?txid, ?next_height, "got next height");
@ -307,11 +308,12 @@ where
let tx = match network
.oneshot(req)
.await
.map_err(CloneError::from)
.map_err(TransactionDownloadVerifyError::DownloadFailed)?
{
zn::Response::Transactions(mut txs) => txs.pop().ok_or_else(|| {
TransactionDownloadVerifyError::DownloadFailed(
"no transactions returned".into(),
BoxError::from("no transactions returned").into(),
)
})?,
_ => unreachable!("wrong response to transaction request"),
@ -373,7 +375,7 @@ where
let task = tokio::spawn(async move {
// Prefer the cancel handle if both are ready.
tokio::select! {
let result = tokio::select! {
biased;
_ = &mut cancel_rx => {
trace!("task cancelled prior to completion");
@ -381,7 +383,19 @@ where
Err((TransactionDownloadVerifyError::Cancelled, txid))
}
verification = fut => verification,
};
// Send the result to responder channel if one was provided.
if let Some(rsp_tx) = rsp_tx {
let _ = rsp_tx.send(
result
.as_ref()
.map(|_| ())
.map_err(|(err, _)| err.clone().into()),
);
}
result
});
self.pending.push(task);
@ -458,6 +472,7 @@ where
match state
.ready()
.await
.map_err(CloneError::from)
.map_err(TransactionDownloadVerifyError::StateError)?
.call(zs::Request::Transaction(txid.mined_id()))
.await
@ -465,7 +480,7 @@ where
Ok(zs::Response::Transaction(None)) => Ok(()),
Ok(zs::Response::Transaction(Some(_))) => Err(TransactionDownloadVerifyError::InState),
Ok(_) => unreachable!("wrong response"),
Err(e) => Err(TransactionDownloadVerifyError::StateError(e)),
Err(e) => Err(TransactionDownloadVerifyError::StateError(e.into())),
}?;
Ok(())

View File

@ -294,8 +294,8 @@ impl Storage {
/// - Removes from the 'verified' set, if present.
/// Maintains the order in which the other unmined transactions have been inserted into the mempool.
///
/// Reject and remove transactions from the mempool that contain any outpoints or nullifiers in
/// the `spent_outpoints` or `nullifiers` collections that are passed in.
/// Reject and remove transactions from the mempool that contain any spent outpoints or revealed
/// nullifiers from the passed in `transactions`.
///
/// Returns the number of transactions that were removed.
pub fn reject_and_remove_same_effects(

View File

@ -445,12 +445,17 @@ async fn mempool_cancel_mined() -> Result<(), Report> {
.call(Request::Queue(vec![txid.into()]))
.await
.unwrap();
let queued_responses = match response {
let mut queued_responses = match response {
Response::Queued(queue_responses) => queue_responses,
_ => unreachable!("will never happen in this test"),
};
assert_eq!(queued_responses.len(), 1);
assert!(queued_responses[0].is_ok());
let queued_response = queued_responses
.pop()
.expect("already checked that there is exactly 1 item in Vec")
.expect("initial queue checks result should be Ok");
assert_eq!(mempool.tx_downloads().in_flight(), 1);
// Push block 2 to the state
@ -489,6 +494,14 @@ async fn mempool_cancel_mined() -> Result<(), Report> {
// Check if download was cancelled.
assert_eq!(mempool.tx_downloads().in_flight(), 0);
assert!(
queued_response
.await
.expect("channel should not be closed")
.is_err(),
"queued tx should fail to download and verify due to chain tip change"
);
Ok(())
}

View File

@ -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_562_000;
pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_626_500;
/// The maximum number of days after `ESTIMATED_RELEASE_HEIGHT` where a Zebra server will run
/// without halting.
@ -22,8 +22,8 @@ pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_562_000;
///
/// - Zebra will exit with a panic if the current tip height is bigger than the `ESTIMATED_RELEASE_HEIGHT`
/// plus this number of days.
/// - Currently set to 16 weeks.
pub const EOS_PANIC_AFTER: u32 = 112;
/// - Currently set to 14 weeks.
pub const EOS_PANIC_AFTER: u32 = 70;
/// The number of days before the end of support where Zebra will display warnings.
pub const EOS_WARN_AFTER: u32 = EOS_PANIC_AFTER - 14;

View File

@ -2957,7 +2957,7 @@ fn external_address() -> Result<()> {
// TODO: Test this with an NU5 activation height too once config can be serialized.
#[tokio::test]
#[cfg(feature = "getblocktemplate-rpcs")]
async fn regtest_submit_blocks() -> Result<()> {
async fn regtest_block_templates_are_valid_block_submissions() -> Result<()> {
common::regtest::submit_blocks_test().await?;
Ok(())
}

View File

@ -121,7 +121,7 @@ pub const LIGHTWALLETD_EMPTY_ZEBRA_STATE_IGNORE_MESSAGES: &[&str] = &[
//
// This log matches the "error with" RPC error message,
// but we expect Zebra to start with an empty state.
r#"No Chain tip available yet","level":"warning","msg":"error with getblockchaininfo rpc, retrying"#,
r#"no chain tip available yet","level":"warning","msg":"error with getblockchaininfo rpc, retrying"#,
];
/// Failure log messages from `zebra-checkpoints`.

View File

@ -330,7 +330,7 @@ impl TestType {
// Zebra state failures
if self.needs_zebra_cached_state() {
// Fail if we need a cached Zebra state, but it's empty
lightwalletd_failure_messages.push("No Chain tip available yet".to_string());
lightwalletd_failure_messages.push("no chain tip available yet".to_string());
}
// lightwalletd state failures