Merge branch 'zsa1' into zsa-integration-zsadeps-old

This commit is contained in:
Dmitry Demin 2024-10-29 14:38:50 +01:00
commit 77e9d4dd2b
64 changed files with 1005 additions and 594 deletions

View File

@ -1,3 +1,4 @@
[codespell]
ignore-words-list=crate,Sur,inout,Groth,groth,re-use,
exclude-file=book/mermaid.min.js
ignore-words-list = crate,Sur,inout,Groth,groth,re-use,
exclude-file = book/mermaid.min.js
skip = ./zebra-rpc/qa/rpc-tests,./supply-chain

View File

@ -30,17 +30,39 @@ on:
workflow_dispatch:
inputs:
network:
default: 'Mainnet'
default: Mainnet
description: 'Network to deploy: Mainnet or Testnet'
required: true
log_file:
default: ''
description: 'Log to a file path rather than standard output'
type: choice
options:
- Mainnet
- Testnet
cached_disk_type:
default: tip
description: 'Type of cached disk to use'
required: true
type: choice
options:
- tip
- checkpoint
prefer_main_cached_state:
default: false
description: 'Prefer cached state from the main branch'
required: false
type: boolean
no_cached_disk:
default: false
description: 'Do not use a cached state disk'
required: false
type: boolean
no_cache:
description: 'Disable the Docker cache for this build'
required: false
type: boolean
default: false
log_file:
default: ''
description: 'Log to a file path rather than standard output'
push:
# Skip main branch updates where Rust code and dependencies aren't modified.
@ -175,18 +197,19 @@ jobs:
test_variables: '-e NETWORK -e ZEBRA_CONF_PATH="zebrad/tests/common/configs/v1.0.0-rc.2.toml"'
network: ${{ inputs.network || vars.ZCASH_NETWORK }}
# Finds a `tip` cached state disk for zebra from the main branch
# Finds a cached state disk for zebra
#
# Passes the disk name to subsequent jobs using `cached_disk_name` output
#
get-disk-name:
name: Get disk name
uses: ./.github/workflows/sub-find-cached-disks.yml
if: ${{ !inputs.no_cached_disk }}
with:
network: ${{ inputs.network || vars.ZCASH_NETWORK }}
disk_prefix: zebrad-cache
disk_suffix: tip
prefer_main_cached_state: true
disk_suffix: ${{ inputs.cached_disk_type || 'tip' }}
prefer_main_cached_state: ${{ inputs.prefer_main_cached_state || (github.event_name == 'push' && github.ref_name == 'main' && true) || false }}
# Deploy Managed Instance Groups (MiGs) for Mainnet and Testnet,
# with one node in the configured GCP region.
@ -250,14 +273,14 @@ jobs:
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.1
# TODO we should implement the fixes from https://github.com/ZcashFoundation/zebra/pull/5670 here
# but the implementation is failing as it's requiring the disk names, contrary to what is stated in the official documentation
- name: Create instance template for ${{ matrix.network }}
run: |
NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}"
DISK_PARAMS="name=${NAME},device-name=${NAME},size=400GB,type=pd-ssd"
DISK_NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}"
DISK_PARAMS="name=${DISK_NAME},device-name=${DISK_NAME},size=400GB,type=pd-ssd"
if [ -n "${{ env.CACHED_DISK_NAME }}" ]; then
DISK_PARAMS+=",image=${{ env.CACHED_DISK_NAME }}"
elif [ ${{ inputs.no_cached_disk && github.event_name == 'workflow_dispatch' }} ]; then
echo "No cached disk required"
else
echo "No cached disk found for ${{ matrix.network }} in main branch"
exit 1
@ -270,7 +293,7 @@ jobs:
--image-family=cos-stable \
--network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \
--create-disk="${DISK_PARAMS}" \
--container-mount-disk=mount-path='/var/cache/zebrad-cache',name=${NAME},mode=rw \
--container-mount-disk=mount-path='/var/cache/zebrad-cache',name=${DISK_NAME},mode=rw \
--container-stdin \
--container-tty \
--container-image ${{ vars.GAR_BASE }}/zebrad@${{ needs.build.outputs.image_digest }} \
@ -326,7 +349,8 @@ jobs:
permissions:
contents: 'read'
id-token: 'write'
if: github.event_name == 'workflow_dispatch'
# Run even if we don't need a cached disk, but only when triggered by a workflow_dispatch
if: ${{ !failure() && github.event_name == 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v4.2.1
@ -363,10 +387,12 @@ jobs:
# Create instance template from container image
- name: Manual deploy of a single ${{ inputs.network }} instance running zebrad
run: |
NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}"
DISK_PARAMS="name=${NAME},device-name=${NAME},size=400GB,type=pd-ssd"
DISK_NAME="zebrad-cache-${{ env.GITHUB_HEAD_REF_SLUG_URL || env.GITHUB_REF_SLUG_URL }}-${{ env.GITHUB_SHA_SHORT }}-${NETWORK}"
DISK_PARAMS="name=${DISK_NAME},device-name=${DISK_NAME},size=400GB,type=pd-ssd"
if [ -n "${{ env.CACHED_DISK_NAME }}" ]; then
DISK_PARAMS+=",image=${{ env.CACHED_DISK_NAME }}"
elif [ ${{ inputs.no_cached_disk && github.event_name == 'workflow_dispatch' }} ]; then
echo "No cached disk required"
else
echo "No cached disk found for ${{ matrix.network }} in main branch"
exit 1
@ -379,7 +405,7 @@ jobs:
--image-family=cos-stable \
--network-interface=subnet=${{ vars.GCP_SUBNETWORK }} \
--create-disk="${DISK_PARAMS}" \
--container-mount-disk=mount-path='/var/cache/zebrad-cache',name=${NAME},mode=rw \
--container-mount-disk=mount-path='/var/cache/zebrad-cache',name=${DISK_NAME},mode=rw \
--container-stdin \
--container-tty \
--container-image ${{ vars.GAR_BASE }}/zebrad@${{ needs.build.outputs.image_digest }} \

View File

@ -93,7 +93,7 @@ jobs:
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=stable --profile=default
- uses: Swatinem/rust-cache@v2.7.3
- uses: Swatinem/rust-cache@v2.7.5
with:
shared-key: "clippy-cargo-lock"
@ -138,7 +138,7 @@ jobs:
# We don't cache `fmt` outputs because the job is quick,
# and we want to use the limited GitHub actions cache space for slower jobs.
#- uses: Swatinem/rust-cache@v2.7.3
#- uses: Swatinem/rust-cache@v2.7.5
- run: |
cargo fmt --all -- --check

View File

@ -112,7 +112,7 @@ jobs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=${{ matrix.rust }} --profile=minimal
- uses: Swatinem/rust-cache@v2.7.3
- uses: Swatinem/rust-cache@v2.7.5
# TODO: change Rust cache target directory on Windows,
# or remove this workaround once the build is more efficient (#3005).
#with:
@ -221,7 +221,7 @@ jobs:
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=stable --profile=minimal
- uses: Swatinem/rust-cache@v2.7.3
- uses: Swatinem/rust-cache@v2.7.5
with:
shared-key: "clippy-cargo-lock"

View File

@ -155,7 +155,7 @@ jobs:
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=beta --profile=default
- uses: Swatinem/rust-cache@v2.7.3
- uses: Swatinem/rust-cache@v2.7.5
- name: Build internal docs
run: |

View File

@ -3,9 +3,9 @@
# This script finds a cached Google Cloud Compute image based on specific criteria.
#
# If there are multiple disks:
# - prefer images generated from the same commit, then
# - if prefer_main_cached_state is true, prefer images from the `main` branch, then
# - use any images from any other branch or commit.
# - if `PREFER_MAIN_CACHED_STATE` is "true", then select an image from the `main` branch, else
# - try to find a cached disk image from the current branch (or PR), else
# - try to find an image from any branch.
#
# Within each of these categories:
# - prefer newer images to older images
@ -20,7 +20,7 @@ echo "Extracting local state version..."
LOCAL_STATE_VERSION=$(grep -oE "DATABASE_FORMAT_VERSION: .* [0-9]+" "${GITHUB_WORKSPACE}/zebra-state/src/constants.rs" | grep -oE "[0-9]+" | tail -n1)
echo "STATE_VERSION: ${LOCAL_STATE_VERSION}"
# Function to find a cached disk image based on the git pattern (commit, main, or any branch)
# Function to find a cached disk image based on the git pattern (branch, main, or any branch)
find_cached_disk_image() {
local git_pattern="${1}"
local git_source="${2}"
@ -34,40 +34,36 @@ find_cached_disk_image() {
echo "Found ${git_source} Disk: ${disk_name}" >&2
disk_description=$(gcloud compute images describe "${disk_name}" --format="value(DESCRIPTION)")
echo "Description: ${disk_description}" >&2
echo "${disk_name}" # This is the actual return value when a disk is found
echo "${disk_name}" # This is the actual return value when a disk is found
else
echo "No ${git_source} disk found." >&2
echo "No ${git_source} disk found with '${disk_search_pattern}' pattern." >&2
fi
}
# Check if both $DISK_PREFIX and $DISK_SUFFIX are set, as they are required to find a cached disk image
# Check if both $DISK_PREFIX and $DISK_SUFFIX are set, as they are required to
# find a cached disk image.
if [[ -n "${DISK_PREFIX}" && -n "${DISK_SUFFIX}" ]]; then
# Find the most suitable cached disk image
echo "Finding the most suitable cached disk image..."
echo "Finding a ${DISK_PREFIX}-${DISK_SUFFIX} disk image for ${NETWORK}..."
CACHED_DISK_NAME=""
# First, try to find a cached disk image from the current commit
CACHED_DISK_NAME=$(find_cached_disk_image ".+-${GITHUB_SHA_SHORT}" "commit")
# If no cached disk image is found
if [[ -z "${CACHED_DISK_NAME}" ]]; then
# Check if main branch images are preferred
if [[ "${PREFER_MAIN_CACHED_STATE}" == "true" ]]; then
CACHED_DISK_NAME=$(find_cached_disk_image "main-[0-9a-f]+" "main branch")
# Else, try to find one from any branch
else
CACHED_DISK_NAME=$(find_cached_disk_image ".+-[0-9a-f]+" "any branch")
fi
# Try to find an image based on the `main` branch if that branch is preferred.
if [[ "${PREFER_MAIN_CACHED_STATE}" == "true" ]]; then
CACHED_DISK_NAME=$(find_cached_disk_image "main-[0-9a-f]+" "main branch")
fi
# If no image was found, try to find one from the current branch (or PR).
CACHED_DISK_NAME=${CACHED_DISK_NAME:-$(find_cached_disk_image ".+-${GITHUB_REF}" "branch")}
# If we still have no image, try to find one from any branch.
CACHED_DISK_NAME=${CACHED_DISK_NAME:-$(find_cached_disk_image ".+-[0-9a-f]+" "any branch")}
# Handle case where no suitable disk image is found
# Handle the case where no suitable disk image is found
if [[ -z "${CACHED_DISK_NAME}" ]]; then
echo "No suitable cached state disk available."
echo "Cached state test jobs must depend on the cached state rebuild job."
echo "No suitable cached state disk available. Try running the cached state rebuild job."
exit 1
else
echo "Selected Disk: ${CACHED_DISK_NAME}"
fi
echo "Selected Disk: ${CACHED_DISK_NAME}"
else
echo "DISK_PREFIX or DISK_SUFFIX is not set. Skipping disk image search."
fi
@ -77,7 +73,6 @@ find_available_disk_type() {
local base_name="${1}"
local disk_type="${2}"
local disk_pattern="${base_name}-cache"
local output_var="${base_name}_${disk_type}_disk"
local disk_name
disk_name=$(gcloud compute images list --filter="status=READY AND name~${disk_pattern}-.+-[0-9a-f]+-v${LOCAL_STATE_VERSION}-${NETWORK}-${disk_type}" --format="value(NAME)" --sort-by=~creationTimestamp --limit=1)
@ -87,10 +82,10 @@ find_available_disk_type() {
echo "Found ${disk_type^^} disk: ${disk_name} for ${base_name^^} on network: ${NETWORK}" >&2
disk_description=$(gcloud compute images describe "${disk_name}" --format="value(DESCRIPTION)")
echo "Description: ${disk_description}" >&2
echo "true" # This is the actual return value when a disk is found
echo "true" # This is the actual return value when a disk is found
else
echo "No ${disk_type^^} disk found for ${base_name^^} on network: ${NETWORK}" >&2
echo "false" # This is the actual return value when no disk is found
echo "false" # This is the actual return value when no disk is found
fi
}
if [[ -n "${NETWORK}" ]]; then

View File

@ -2,7 +2,7 @@
set -ex
# Check if necessary tools are installed
if ! command -v git &> /dev/null || ! command -v cargo &> /dev/null; then
if ! command -v git &>/dev/null || ! command -v cargo &>/dev/null; then
echo "ERROR: Required tools (git, cargo) are not installed."
exit 1
fi
@ -11,7 +11,7 @@ git config --global user.email "release-tests-no-reply@zfnd.org"
git config --global user.name "Automated Release Test"
# Ensure cargo-release is installed
if ! cargo release --version &> /dev/null; then
if ! cargo release --version &>/dev/null; then
echo "ERROR: cargo release must be installed."
exit 1
fi
@ -23,12 +23,11 @@ fi
cargo release version --verbose --execute --no-confirm --allow-branch '*' --workspace --exclude zebrad --exclude zebra-scan --exclude zebra-grpc patch
# Due to a bug in cargo-release, we need to pass exact versions for alpha crates:
cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-scan 0.1.0-alpha.9
cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-grpc 0.1.0-alpha.7
cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-scan 0.1.0-alpha.10
cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebra-grpc 0.1.0-alpha.8
# Update zebrad:
# TODO: Revert `2.0.0-rc.0` to `patch` in the next release candidate.
cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebrad 2.0.0-rc.0
cargo release version --verbose --execute --no-confirm --allow-branch '*' --package zebrad patch
# Continue with the release process:
cargo release replace --verbose --execute --no-confirm --allow-branch '*' --package zebrad
cargo release commit --verbose --execute --no-confirm --allow-branch '*'

View File

@ -654,6 +654,7 @@ jobs:
# (This is unlikely, because each image created by a workflow has a different name.)
#
# The image name must also be 63 characters or less.
# More info: https://cloud.google.com/compute/docs/naming-resources#resource-name-format
#
# Force the image creation (--force) as the disk is still attached even though is not being
# used by the container.

View File

@ -74,20 +74,30 @@ jobs:
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.1
# Disk images in GCP are required to be in lowercase, but the blockchain network
# uses sentence case, so we need to downcase ${{ inputs.network }}
# Performs formatting on disk name components.
#
# Passes a lowercase Network name to subsequent steps using $NETWORK env variable
- name: Downcase network name for disks
# Disk images in GCP are required to be in lowercase, but the blockchain network
# uses sentence case, so we need to downcase ${{ inputs.network }}.
#
# Disk image names in GCP are limited to 63 characters, so we need to limit
# branch names to 12 characters.
# Check the `create-state-image` in `sub-deploy-integration-tests-gcp.yml` for more details in image names.
# More info: https://cloud.google.com/compute/docs/naming-resources#resource-name-format
#
# Passes ${{ inputs.network }} to subsequent steps using $NETWORK env variable.
# Passes ${{ env.GITHUB_REF_SLUG_URL }} to subsequent steps using $SHORT_GITHUB_REF env variable.
- name: Format network name and branch name for disks
run: |
NETWORK_CAPS=${{ inputs.network }}
echo "NETWORK=${NETWORK_CAPS,,}" >> $GITHUB_ENV
NETWORK_CAPS="${{ inputs.network }}"
echo "NETWORK=${NETWORK_CAPS,,}" >> "$GITHUB_ENV"
LONG_GITHUB_REF="${{ env.GITHUB_REF_SLUG_URL }}"
echo "SHORT_GITHUB_REF=${LONG_GITHUB_REF:0:12}" >> "$GITHUB_ENV"
# Check if there are cached state disks available for subsequent jobs to use.
- name: Check if cached state disks exists
id: get-available-disks
env:
GITHUB_SHA_SHORT: ${{ env.GITHUB_SHA_SHORT }}
GITHUB_REF: ${{ env.SHORT_GITHUB_REF }}
NETWORK: ${{ env.NETWORK }} # use lowercase version from env, not input
DISK_PREFIX: ${{ inputs.disk_prefix }}
DISK_SUFFIX: ${{ inputs.disk_suffix }}

View File

@ -5,6 +5,29 @@ All notable changes to Zebra are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org).
## [Zebra 2.0.0](https://github.com/ZcashFoundation/zebra/releases/tag/v2.0.0) - 2024-10-25
This release brings full support for NU6.
### Breaking Changes
- Zebra now supports NU6 on Mainnet.
- The JSON RPC endpoint has a cookie-based authentication enabled by default.
### Added
- NU6-related documentation ([#8949](https://github.com/ZcashFoundation/zebra/pull/8949))
- A cookie-based authentication system for the JSON RPC endpoint ([#8900](https://github.com/ZcashFoundation/zebra/pull/8900), [#8965](https://github.com/ZcashFoundation/zebra/pull/8965))
### Changed
- Set the activation height of NU6 for Mainnet and bumped Zebra's current network protocol version ([#8960](https://github.com/ZcashFoundation/zebra/pull/8960))
### Contributors
Thank you to everyone who contributed to this release, we couldn't make Zebra without you:
@arya2, @gustavovalverde, @oxarbitrage and @upbqdn.
## [Zebra 2.0.0-rc.0](https://github.com/ZcashFoundation/zebra/releases/tag/v2.0.0-rc.0) - 2024-10-11
This version is a release candidate for the Zcash NU6 network upgrade on the Mainnet. While this version does not yet include the NU6 Mainnet activation height or current protocol version, all required functionality and tests are in place.

View File

@ -2,13 +2,17 @@
---
[![Integration Tests](https://github.com/ZcashFoundation/zebra/actions/workflows/sub-ci-integration-tests-gcp.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/sub-ci-integration-tests-gcp.yml) [![CI OSes](https://github.com/ZcashFoundation/zebra/actions/workflows/ci-unit-tests-os.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/ci-unit-tests-os.yml) [![Continuous Delivery](https://github.com/ZcashFoundation/zebra/actions/workflows/cd-deploy-nodes-gcp.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/cd-deploy-nodes-gcp.yml) [![codecov](https://codecov.io/gh/ZcashFoundation/zebra/branch/main/graph/badge.svg)](https://codecov.io/gh/ZcashFoundation/zebra) [![Build docs](https://github.com/ZcashFoundation/zebra/actions/workflows/docs-deploy-firebase.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/docs-deploy-firebase.yml)
[![Integration Tests](https://github.com/ZcashFoundation/zebra/actions/workflows/ci-tests.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/ci-tests.yml)
[![CI OSes](https://github.com/ZcashFoundation/zebra/actions/workflows/ci-unit-tests-os.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/ci-unit-tests-os.yml)
[![Continuous Delivery](https://github.com/ZcashFoundation/zebra/actions/workflows/cd-deploy-nodes-gcp.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/cd-deploy-nodes-gcp.yml)
[![codecov](https://codecov.io/gh/ZcashFoundation/zebra/branch/main/graph/badge.svg)](https://codecov.io/gh/ZcashFoundation/zebra)
[![Build docs](https://github.com/ZcashFoundation/zebra/actions/workflows/docs-deploy-firebase.yml/badge.svg)](https://github.com/ZcashFoundation/zebra/actions/workflows/docs-deploy-firebase.yml)
![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)
- [About](#about)
- [Getting Started](#getting-started)
- [Docker](#docker)
- [Building Zebra](#building-zebra)
- [Manual Build](#manual-build)
- [Documentation](#documentation)
- [User support](#user-support)
- [Security](#security)
@ -16,14 +20,12 @@
## About
[Zebra](https://zebra.zfnd.org/) is the Zcash Foundation's independent,
consensus-compatible implementation of a Zcash node.
[Zebra](https://zebra.zfnd.org/) is a Zcash full-node written in Rust.
Zebra's network stack is interoperable with `zcashd`, and Zebra implements all
the features required to reach Zcash network consensus, including the validation
of all the consensus rules for the NU5 network upgrade.
[Here](https://docs.rs/zebrad/latest/zebrad/index.html#zebra-advantages) are some
benefits of Zebra.
Zebra implements all the features required to reach Zcash network consensus, and
the network stack is interoperable with `zcashd`.
[Here](https://docs.rs/zebrad/latest/zebrad/index.html#zebra-advantages) are
some benefits of Zebra.
Zebra validates blocks and transactions, but needs extra software to generate
them:
@ -53,7 +55,7 @@ docker run zfnd/zebra:latest
For more information, read our [Docker documentation](https://zebra.zfnd.org/user/docker.html).
### Building Zebra
### Manual Build
Building Zebra requires [Rust](https://www.rust-lang.org/tools/install),
[libclang](https://clang.llvm.org/doxygen/group__CINDEX.html), and a C++

View File

@ -37,7 +37,7 @@ docker run -d --platform linux/amd64 \
### Build it locally
```shell
git clone --depth 1 --branch v1.9.0 https://github.com/ZcashFoundation/zebra.git
git clone --depth 1 --branch v2.0.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.9.0
git checkout v2.0.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.9.0 zebrad
cargo install --git https://github.com/ZcashFoundation/zebra --tag v2.0.0 zebrad
```
### Compiling on ARM

View File

@ -46,6 +46,8 @@ for Zebra is:
- `8232` for Mainnet, and
- `18232` for Testnet.
Starting with Zebra v2.0.0, a cookie authentication method like the one used by the `zcashd` node is enabled by default for the RPC server. However, lightwalletd currently [does not support cookie authentication](https://github.com/zcash/lightwalletd/blob/master/docs/docker-compose-setup.md#edit-the-two-zcashconf-files), so we need to disable this authentication method to use Zebra as a backend for lightwalletd.
For example, to use Zebra as a `lightwalletd` backend on Mainnet, give it this
`~/.config/zebrad.toml`:
@ -56,6 +58,9 @@ listen_addr = '127.0.0.1:8232'
# automatically use multiple CPU threads
parallel_cpu_threads = 0
# disable cookie auth
enable_cookie_auth = false
```
**WARNING:** This config allows multiple Zebra instances to share the same RPC port.

View File

@ -13,6 +13,7 @@ These fixes disable mining pool operator payments and miner payments: they just
- change the `network.network` config to `Testnet`
- add your testnet transparent address in `mining.miner_address`, or you can use the ZF testnet address `t27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v`
- ensure that there is an `rpc.listen_addr` in the config to enable the RPC server
- disable the cookie auth system by changing `rpc.enable_cookie_auth` to `false`
Example config:
<details>
@ -48,6 +49,7 @@ These fixes disable mining pool operator payments and miner payments: they just
debug_force_finished_sync = false
parallel_cpu_threads = 1
listen_addr = '127.0.0.1:18232'
enable_cookie_auth = false
[state]
cache_dir = '/home/ar/.cache/zebra'

View File

@ -80,8 +80,16 @@ Wait until zebra is in sync, you will see the sync at 100% when this happens:
The easiest way to check your setup is to call the `getblocktemplate` RPC method and check the result.
Starting with Zebra v2.0.0, a cookie authentication method similar to the one used by the `zcashd` node is enabled by default. The cookie is stored in the default cache directory when the RPC endpoint starts and is deleted at shutdown. By default, the cookie is located in the cache directory; for example, on Linux, it may be found at `/home/user/.cache/zebra/.cookie`. You can change the cookie's location using the `rpc.cookie_dir` option in the configuration, or disable cookie authentication altogether by setting `rpc.enable_cookie_auth` to false. The contents of the cookie file look like this:
```
__cookie__:YwDDua GzvtEmWG6KWnhgd9gilo5mKdi6m38v__we3Ko=
```
The password is an encoded, randomly generated string. You can use it in your call as follows:
```console
$ curl --silent --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblocktemplate", "params": [] }' -H 'Content-type: application/json' http://127.0.0.1:8232/ | jq
$ curl --silent --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblocktemplate", "params": [] }' -H 'Content-type: application/json' http://__cookie__:YwDDuaGzvtEmWG6KWnhgd9gilo5mKdi6m38v__we3Ko=@127.0.0.1:8232/ | jq
```
If you can see something similar to the following then you are good to go.

View File

@ -12,7 +12,7 @@ There are a few bugs in Zebra that we're still working on fixing:
- Block download and verification sometimes times out during Zebra's initial sync [#5709](https://github.com/ZcashFoundation/zebra/issues/5709). The full sync still finishes reasonably quickly.
- Experimental Tor support is disabled until Zebra upgrades to the latest `arti-client`. This happened due to a Rust dependency conflict ([#5492](https://github.com/ZcashFoundation/zebra/issues/5492)) and is still an issue due to [another dependency conflict](https://github.com/ZcashFoundation/zebra/issues/8328#issuecomment-1969989648).
- Experimental Tor support is disabled until Zebra upgrades to the latest `arti-client`. [#8328](https://github.com/ZcashFoundation/zebra/issues/8328#issuecomment-1969989648)
## Memory Issues

View File

@ -82,13 +82,22 @@ skip-tree = [
{ name = "h2", version = "=0.3.26" },
{ name = "http", version = "=0.2.12" },
{ name = "http-body", version = "=0.4.6" },
{ name = "hyper", version = "=0.14.30" },
{ name = "hyper", version = "=0.14.31" },
{ name = "hyper-rustls", version = "=0.24.2" },
{ name = "reqwest", version = "=0.11.27" },
{ name = "rustls", version = "=0.21.12" },
{ name = "rustls-pemfile", version = "=1.0.4" },
{ name = "rustls-webpki", version = "=0.101.7" },
{ name = "tokio-rustls", version = "=0.24.1" },
{ name = "webpki-roots", version = "=0.25.4" },
# wait for structopt-derive to update heck
{ name = "heck", version = "=0.3.3" },
# wait for librocksdb-sys to update bindgen to one that uses newer itertools
{ name = "itertools", version = "=0.12.1" },
{ name = "bindgen", version = "=0.69.5" },
# wait for halo2_gadgets and primitive-types to update uint
{ name = "uint", version = "=0.9.5" },
@ -96,6 +105,10 @@ skip-tree = [
# wait for dirs-sys to update windows-sys
{ name = "windows-sys", version = "=0.48.0" },
# wait for zebra to update tower
{ name = "tower", version = "=0.4.13" },
{ name = "hashbrown", version = "=0.12.3" },
# Remove after release candicate period is over and the ECC crates are not patched anymore
{ name = "equihash", version = "=0.2.0" },
{ name = "f4jumble", version = "=0.1.0" },

View File

@ -21,7 +21,7 @@ ARG TEST_FEATURES="lightwalletd-grpc-tests zebra-checkpoints"
ARG EXPERIMENTAL_FEATURES=""
ARG APP_HOME="/opt/zebrad"
ARG RUST_VERSION=1.79.0
ARG RUST_VERSION=1.82.0
# In this stage we download all system requirements to build the project
#
# It also captures all the build arguments to be used as environment variables.

View File

@ -46,6 +46,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.6.1 -> 1.7.1"
[[audits.bytes]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.7.2 -> 1.8.0"
[[audits.cfg_aliases]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -108,11 +113,66 @@ criteria = "safe-to-deploy"
delta = "0.1.0 -> 0.1.0@git:1410f1449100a417bfbc4f6c7167aa9808e38792"
importable = false
[[audits.foldhash]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
version = "0.1.3"
[[audits.futures]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-channel]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-core]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-executor]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-io]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-macro]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-sink]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-task]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.futures-util]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.3.30 -> 0.3.31"
[[audits.git2]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.18.3 -> 0.19.0"
[[audits.hashbrown]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.14.5 -> 0.15.0"
[[audits.hyper]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -123,6 +183,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.3.1 -> 1.4.1"
[[audits.hyper]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.4.1 -> 1.5.0"
[[audits.hyper-util]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -154,6 +219,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "2.3.0 -> 2.5.0"
[[audits.indexmap]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "2.5.0 -> 2.6.0"
[[audits.inferno]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -194,6 +264,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.22.3 -> 0.23.0"
[[audits.metrics]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.23.0 -> 0.24.0"
[[audits.metrics-exporter-prometheus]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -204,11 +279,21 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.15.1 -> 0.15.3"
[[audits.metrics-exporter-prometheus]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.15.3 -> 0.16.0"
[[audits.metrics-util]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.16.3 -> 0.17.0"
[[audits.metrics-util]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0 -> 0.18.0"
[[audits.mio]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -219,6 +304,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
version = "0.15.0"
[[audits.once_cell]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.19.0 -> 1.20.2"
[[audits.orchard]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -240,6 +330,16 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "4.0.0 -> 4.1.0"
[[audits.pin-project]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.1.5 -> 1.1.6"
[[audits.pin-project-internal]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.1.5 -> 1.1.6"
[[audits.proptest-derive]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -321,6 +421,16 @@ criteria = "safe-to-deploy"
delta = "0.3.0 -> 0.2.0@git:b1ad3694ee13a2fc5d291ad04721a6252da0993c"
importable = false
[[audits.serde]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.0.210 -> 1.0.211"
[[audits.serde_derive]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.0.210 -> 1.0.211"
[[audits.serde_spanned]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -336,6 +446,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "3.8.3 -> 3.9.0"
[[audits.serde_with]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "3.9.0 -> 3.11.0"
[[audits.serde_with_macros]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -346,6 +461,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "3.8.3 -> 3.9.0"
[[audits.serde_with_macros]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "3.9.0 -> 3.11.0"
[[audits.serde_yml]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -367,6 +487,11 @@ criteria = "safe-to-deploy"
delta = "0.5.0 -> 0.4.0@git:ffe4234788fd22662b937ba7c6ea01535fcc1293"
importable = false
[[audits.sketches-ddsketch]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "0.2.2 -> 0.3.0"
[[audits.tempfile]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
@ -735,6 +860,11 @@ who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.0.0-beta.38 -> 1.0.0-beta.39"
[[audits.zebra-test]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"
delta = "1.0.0-beta.39 -> 1.0.0-beta.40"
[[audits.zebra-utils]]
who = "Alfredo Garcia <oxarbitrage@gmail.com>"
criteria = "safe-to-deploy"

View File

@ -1,10 +1,58 @@
# cargo-vet imports lock
[[unpublished.tower-batch-control]]
version = "0.2.41-beta.16"
audited_as = "0.2.41-beta.15"
[[unpublished.tower-fallback]]
version = "0.2.41-beta.16"
audited_as = "0.2.41-beta.15"
[[unpublished.zebra-chain]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-consensus]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-grpc]]
version = "0.1.0-alpha.7"
audited_as = "0.1.0-alpha.6"
[[unpublished.zebra-network]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-node-services]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-rpc]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-scan]]
version = "0.1.0-alpha.8"
version = "0.1.0-alpha.9"
audited_as = "0.1.0-alpha.7"
[[unpublished.zebra-script]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-state]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebra-utils]]
version = "1.0.0-beta.40"
audited_as = "1.0.0-beta.39"
[[unpublished.zebrad]]
version = "2.0.0-rc.0"
audited_as = "1.9.0"
[[publisher.cexpr]]
version = "0.6.0"
when = "2021-10-11"
@ -13,15 +61,15 @@ user-login = "emilio"
user-name = "Emilio Cobos Álvarez"
[[publisher.clap]]
version = "4.5.18"
when = "2024-09-20"
version = "4.5.20"
when = "2024-10-08"
user-id = 6743
user-login = "epage"
user-name = "Ed Page"
[[publisher.clap_builder]]
version = "4.5.18"
when = "2024-09-20"
version = "4.5.20"
when = "2024-10-08"
user-id = 6743
user-login = "epage"
user-name = "Ed Page"
@ -48,8 +96,8 @@ user-login = "hsivonen"
user-name = "Henri Sivonen"
[[publisher.serde_json]]
version = "1.0.128"
when = "2024-09-04"
version = "1.0.132"
when = "2024-10-19"
user-id = 3618
user-login = "dtolnay"
user-name = "David Tolnay"
@ -62,15 +110,15 @@ user-login = "dtolnay"
user-name = "David Tolnay"
[[publisher.syn]]
version = "2.0.79"
when = "2024-09-27"
version = "2.0.82"
when = "2024-10-20"
user-id = 3618
user-login = "dtolnay"
user-name = "David Tolnay"
[[publisher.tokio]]
version = "1.40.0"
when = "2024-08-30"
version = "1.41.0"
when = "2024-10-22"
user-id = 6741
user-login = "Darksonn"
user-name = "Alice Ryhl"

View File

@ -1,6 +1,6 @@
[package]
name = "tower-batch-control"
version = "0.2.41-beta.16"
version = "0.2.41-beta.17"
authors = ["Zcash Foundation <zebra@zfnd.org>", "Tower Maintainers <team@tower-rs.com>"]
description = "Tower middleware for batch request processing"
# # Legal
@ -22,11 +22,11 @@ keywords = ["tower", "batch"]
categories = ["algorithms", "asynchronous"]
[dependencies]
futures = "0.3.30"
futures = "0.3.31"
futures-core = "0.3.28"
pin-project = "1.1.5"
pin-project = "1.1.6"
rayon = "1.10.0"
tokio = { version = "1.40.0", features = ["time", "sync", "tracing", "macros"] }
tokio = { version = "1.41.0", features = ["time", "sync", "tracing", "macros"] }
tokio-util = "0.7.12"
tower = { version = "0.4.13", features = ["util", "buffer"] }
tracing = "0.1.39"
@ -41,12 +41,12 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] }
ed25519-zebra = "4.0.3"
rand = "0.8.5"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
tokio-test = "0.4.4"
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.16" }
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.17" }
tower-test = "0.4.0"
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41" }
[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.16"
version = "0.2.41-beta.17"
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"
@ -16,12 +16,12 @@ keywords = ["tower", "batch"]
categories = ["algorithms", "asynchronous"]
[dependencies]
pin-project = "1.1.5"
pin-project = "1.1.6"
tower = "0.4.13"
futures-core = "0.3.28"
tracing = "0.1.39"
[dev-dependencies]
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41" }

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-chain"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Core Zcash data structures"
license = "MIT OR Apache-2.0"
@ -115,12 +115,12 @@ tracing = "0.1.39"
# Serialization
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.210", features = ["serde_derive", "rc"] }
serde_with = "3.9.0"
serde = { version = "1.0.211", features = ["serde_derive", "rc"] }
serde_with = "3.11.0"
serde-big-array = "0.5.1"
# Processing
futures = "0.3.30"
futures = "0.3.31"
itertools = "0.13.0"
rayon = "1.10.0"
@ -130,10 +130,10 @@ redjubjub = "0.7.0"
reddsa = "0.5.1"
# Production feature json-conversion
serde_json = { version = "1.0.128", optional = true }
serde_json = { version = "1.0.132", optional = true }
# Production feature async-error and testing feature proptest-impl
tokio = { version = "1.40.0", optional = true }
tokio = { version = "1.41.0", optional = true }
# Experimental feature shielded-scan
zcash_client_backend = { workspace = true, optional = true }
@ -145,7 +145,7 @@ proptest-derive = { version = "0.5.0", optional = true }
rand = { version = "0.8.5", optional = true }
rand_chacha = { version = "0.3.1", optional = true }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40", optional = true }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41", optional = true }
[dev-dependencies]
# Benchmarks
@ -166,9 +166,9 @@ proptest-derive = "0.5.0"
rand = "0.8.5"
rand_chacha = "0.3.1"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41" }
[[bench]]
name = "block"

View File

@ -65,18 +65,18 @@ pub enum FundingStreamReceiver {
/// The Major Grants (Zcash Community Grants) funding stream.
MajorGrants,
/// The deferred pool contribution.
// TODO: Add link to lockbox stream ZIP
/// The deferred pool contribution, see [ZIP-1015](https://zips.z.cash/zip-1015) for more details.
Deferred,
}
impl FundingStreamReceiver {
/// Returns a human-readable name and a specification URL for the receiver, as described in
/// [ZIP-1014] and [`zcashd`] before NU6. After NU6, the specification is in the [ZIP-lockbox].
/// [ZIP-1014] and [`zcashd`] before NU6. After NU6, the specification is in the [ZIP-1015].
///
/// [ZIP-1014]: https://zips.z.cash/zip-1014#abstract
/// [`zcashd`]: https://github.com/zcash/zcash/blob/3f09cfa00a3c90336580a127e0096d99e25a38d6/src/consensus/funding.cpp#L13-L32
/// [ZIP-lockbox]: https://zips.z.cash/draft-nuttycom-funding-allocation#alternative-2-hybrid-deferred-dev-fund-transitioning-to-a-non-direct-funding-model
/// [ZIP-1015]: https://zips.z.cash/zip-1015
pub fn info(&self, is_nu6: bool) -> (&'static str, &'static str) {
if is_nu6 {
(
@ -112,10 +112,10 @@ pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100;
/// [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].
/// The specification for post-NU6 funding stream and lockbox receivers, a URL that links to [ZIP-1015].
///
/// [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";
/// [ZIP-1015]: https://zips.z.cash/zip-1015
pub const LOCKBOX_SPECIFICATION: &str = "https://zips.z.cash/zip-1015";
/// Funding stream recipients and height ranges.
#[derive(Deserialize, Clone, Debug, Eq, PartialEq)]
@ -225,10 +225,8 @@ lazy_static! {
.collect(),
};
/// The post-NU6 funding streams for Mainnet
// TODO: Add a reference to lockbox stream ZIP, this is currently based on https://zips.z.cash/draft-nuttycom-funding-allocation
/// The post-NU6 funding streams for Mainnet as described in [ZIP-1015](https://zips.z.cash/zip-1015).
pub static ref POST_NU6_FUNDING_STREAMS_MAINNET: FundingStreams = FundingStreams {
// TODO: Adjust this height range and recipient list once a proposal is selected
height_range: POST_NU6_FUNDING_STREAM_START_RANGE_MAINNET,
recipients: [
(
@ -266,11 +264,8 @@ lazy_static! {
.collect(),
};
/// The post-NU6 funding streams for Testnet
// TODO: Add a reference to lockbox stream ZIP, this is currently based on the number of blocks between the
// start and end heights for Mainnet in https://zips.z.cash/draft-nuttycom-funding-allocation
/// The post-NU6 funding streams for Testnet as described in [ZIP-1015](https://zips.z.cash/zip-1015).
pub static ref POST_NU6_FUNDING_STREAMS_TESTNET: FundingStreams = FundingStreams {
// TODO: Adjust this height range and recipient list once a proposal is selected
height_range: POST_NU6_FUNDING_STREAM_START_RANGE_TESTNET,
recipients: [
(
@ -279,7 +274,6 @@ lazy_static! {
),
(
FundingStreamReceiver::MajorGrants,
// TODO: Update these addresses
FundingStreamRecipient::new(8, POST_NU6_FUNDING_STREAM_FPF_ADDRESSES_TESTNET),
),
]
@ -288,15 +282,14 @@ lazy_static! {
};
}
/// The start height of post-NU6 funding streams on Mainnet
// TODO: Add a reference to lockbox stream ZIP, this is currently based on https://zips.z.cash/draft-nuttycom-funding-allocation
/// The start height of post-NU6 funding streams on Mainnet as described in [ZIP-1015](https://zips.z.cash/zip-1015).
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
/// The start height of post-NU6 funding streams on Testnet as described in [ZIP-1015](https://zips.z.cash/zip-1015).
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.
/// The number of blocks contained in the post-NU6 funding streams height ranges on Mainnet or Testnet, as specified
/// in [ZIP-1015](https://zips.z.cash/zip-1015).
const POST_NU6_FUNDING_STREAM_NUM_BLOCKS: u32 = 420_000;
/// The post-NU6 funding stream height range on Mainnet

View File

@ -751,6 +751,12 @@ impl Network {
}
/// Returns pre-NU6 funding streams for this network
///
/// Commonly referred to as the "Dev Fund".
///
/// Defined in [Zcash Protocol Specification §7.10.1][7.10.1]
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub fn pre_nu6_funding_streams(&self) -> &FundingStreams {
if let Self::Testnet(params) = self {
params.pre_nu6_funding_streams()
@ -760,6 +766,10 @@ impl Network {
}
/// Returns post-NU6 funding streams for this network
///
/// Defined in [Zcash Protocol Specification §7.10.1][7.10.1]
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub fn post_nu6_funding_streams(&self) -> &FundingStreams {
if let Self::Testnet(params) = self {
params.post_nu6_funding_streams()

View File

@ -89,8 +89,7 @@ pub(super) const MAINNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)]
(block::Height(903_000), Heartwood),
(block::Height(1_046_400), Canopy),
(block::Height(1_687_104), Nu5),
// TODO: Add NU6
// (block::Height(2_726_400), Nu6),
(block::Height(2_726_400), Nu6),
];
/// Fake mainnet network upgrade activation heights, used in tests.

View File

@ -622,9 +622,8 @@ impl ZcashSerialize for Transaction {
}
// Denoted as `bindingSigSapling` in the spec.
match sapling_shielded_data {
Some(sd) => writer.write_all(&<[u8; 64]>::from(sd.binding_sig)[..])?,
None => {}
if let Some(shielded_data) = sapling_shielded_data {
writer.write_all(&<[u8; 64]>::from(shielded_data.binding_sig)[..])?;
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-consensus"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Implementation of Zcash consensus checks"
license = "MIT OR Apache-2.0"
@ -45,14 +45,14 @@ rayon = "1.10.0"
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
lazy_static = "1.4.0"
once_cell = "1.18.0"
serde = { version = "1.0.210", features = ["serde_derive"] }
once_cell = "1.20.2"
serde = { version = "1.0.211", features = ["serde_derive"] }
futures = "0.3.30"
futures = "0.3.31"
futures-util = "0.3.28"
metrics = "0.23.0"
metrics = "0.24.0"
thiserror = "1.0.64"
tokio = { version = "1.40.0", features = ["time", "sync", "tracing", "rt-multi-thread"] }
tokio = { version = "1.41.0", features = ["time", "sync", "tracing", "rt-multi-thread"] }
tower = { version = "0.4.13", features = ["timeout", "util", "buffer"] }
tracing = "0.1.39"
tracing-futures = "0.2.5"
@ -63,13 +63,13 @@ orchard.workspace = true
zcash_proofs = { workspace = true, features = ["multicore" ] }
wagyu-zcash-parameters = "0.2.0"
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.16" }
tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.16" }
tower-fallback = { path = "../tower-fallback/", version = "0.2.41-beta.17" }
tower-batch-control = { path = "../tower-batch-control/", version = "0.2.41-beta.17" }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.40" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.41" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.41" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41" }
# prod feature progress-bar
howudoin = { version = "0.1.2", optional = true }
@ -90,10 +90,10 @@ proptest = "1.4.0"
proptest-derive = "0.5.0"
spandoc = "0.2.2"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
tracing-error = "0.2.0"
tracing-subscriber = "0.3.18"
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41" }

View File

@ -284,7 +284,7 @@ where
})?;
}
// TODO: Add link to lockbox stream ZIP
// See [ZIP-1015](https://zips.z.cash/zip-1015).
let expected_deferred_amount = subsidy::funding_streams::funding_stream_values(
height,
&network,

View File

@ -162,13 +162,7 @@ pub fn subsidy_is_valid(
.activation_height(network)
.expect("Canopy activation height is known");
// TODO: Add this as a field on `testnet::Parameters` instead of checking `disable_pow()`, this is 0 for Regtest in zcashd,
// see <https://github.com/zcash/zcash/blob/master/src/chainparams.cpp#L640>
let slow_start_interval = if network.disable_pow() {
Height(0)
} else {
network.slow_start_interval()
};
let slow_start_interval = network.slow_start_interval();
if height < slow_start_interval {
unreachable!(
@ -191,7 +185,8 @@ pub fn subsidy_is_valid(
network,
expected_block_subsidy,
)
.expect("We always expect a funding stream hashmap response even if empty");
// we always expect a funding stream hashmap response even if empty
.map_err(|err| BlockError::Other(err.to_string()))?;
// # Consensus
//
@ -204,14 +199,18 @@ pub fn subsidy_is_valid(
for (receiver, expected_amount) in funding_streams {
if receiver == FundingStreamReceiver::Deferred {
// The deferred pool contribution is checked in `miner_fees_are_valid()`
// TODO: Add link to lockbox stream ZIP
// See [ZIP-1015](https://zips.z.cash/zip-1015) for more details.
continue;
}
let address = subsidy::funding_streams::funding_stream_address(
height, network, receiver,
)
.expect("funding stream receivers other than the deferred pool must have an address");
let address =
subsidy::funding_streams::funding_stream_address(height, network, receiver)
// funding stream receivers other than the deferred pool must have an address
.ok_or_else(|| {
BlockError::Other(format!(
"missing funding stream address at height {height:?}"
))
})?;
let has_expected_output =
subsidy::funding_streams::filter_outputs_by_address(coinbase, address)
@ -250,25 +249,23 @@ pub fn miner_fees_are_valid(
let sapling_value_balance = coinbase_tx.sapling_value_balance().sapling_amount();
let orchard_value_balance = coinbase_tx.orchard_value_balance().orchard_amount();
// TODO: Update the quote below once its been updated for NU6.
//
// # Consensus
//
// > The total value in zatoshi of transparent outputs from a coinbase transaction,
// > minus vbalanceSapling, minus vbalanceOrchard, MUST NOT be greater than the value
// > in zatoshi of block subsidy plus the transaction fees paid by transactions in this block.
// > - define the total output value of its coinbase transaction to be the total value in zatoshi of its transparent
// > outputs, minus vbalanceSapling, minus vbalanceOrchard, plus totalDeferredOutput(height);
// > define the total input value of its coinbase transaction to be the value in zatoshi of the block subsidy,
// > plus the transaction fees paid by transactions in the block.
//
// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
//
// The expected lockbox funding stream output of the coinbase transaction is also subtracted
// from the block subsidy value plus the transaction fees paid by transactions in this block.
let left = (transparent_value_balance - sapling_value_balance - orchard_value_balance)
.map_err(|_| SubsidyError::SumOverflow)?;
let right = (expected_block_subsidy + block_miner_fees - expected_deferred_amount)
.map_err(|_| SubsidyError::SumOverflow)?;
let total_output_value = (transparent_value_balance - sapling_value_balance - orchard_value_balance
+ expected_deferred_amount.constrain().expect("valid Amount with NonNegative constraint should be valid with NegativeAllowed constraint"))
.map_err(|_| SubsidyError::SumOverflow)?;
let total_input_value =
(expected_block_subsidy + block_miner_fees).map_err(|_| SubsidyError::SumOverflow)?;
// TODO: Updadte the quotes below if the final phrasing changes in the spec for NU6.
//
// # Consensus
//
// > [Pre-NU6] The total output of a coinbase transaction MUST NOT be greater than its total
@ -276,9 +273,9 @@ pub fn miner_fees_are_valid(
//
// > [NU6 onward] The total output of a coinbase transaction MUST be equal to its total input.
if if NetworkUpgrade::current(network, height) < NetworkUpgrade::Nu6 {
left > right
total_output_value > total_input_value
} else {
left != right
total_output_value != total_input_value
} {
Err(SubsidyError::InvalidMinerFees)?
};

View File

@ -43,6 +43,7 @@ pub fn funding_stream_values(
}
}
}
Ok(results)
}

View File

@ -1,199 +1,86 @@
//! Tests for funding streams.
use color_eyre::Report;
use zebra_chain::parameters::{
subsidy::FundingStreamReceiver,
testnet::{
self, ConfiguredActivationHeights, ConfiguredFundingStreamRecipient,
ConfiguredFundingStreams,
},
NetworkKind,
};
use zebra_chain::parameters::{subsidy::FundingStreamReceiver, NetworkKind};
use crate::block::subsidy::general::block_subsidy;
use super::*;
/// Check mainnet funding stream values are correct for the entire period.
/// Checks that the Mainnet funding stream values are correct.
#[test]
fn test_funding_stream_values() -> Result<(), Report> {
let _init_guard = zebra_test::init();
let network = &Network::Mainnet;
// funding streams not active
let canopy_height_minus1 = (Canopy.activation_height(network).unwrap() - 1).unwrap();
let canopy_activation_height = Canopy.activation_height(network).unwrap();
let nu6_activation_height = Nu6.activation_height(network).unwrap();
assert!(funding_stream_values(
canopy_height_minus1,
network,
block_subsidy(canopy_height_minus1, network)?
)?
.is_empty());
let dev_fund_height_range = network.pre_nu6_funding_streams().height_range();
let nu6_fund_height_range = network.post_nu6_funding_streams().height_range();
// funding stream is active
let canopy_height = Canopy.activation_height(network).unwrap();
let canopy_height_plus1 = (Canopy.activation_height(network).unwrap() + 1).unwrap();
let canopy_height_plus2 = (Canopy.activation_height(network).unwrap() + 2).unwrap();
let nu6_fund_end = Height(3_146_400);
let mut hash_map = HashMap::new();
hash_map.insert(FundingStreamReceiver::Ecc, Amount::try_from(21_875_000)?);
hash_map.insert(
assert_eq!(canopy_activation_height, Height(1_046_400));
assert_eq!(nu6_activation_height, Height(2_726_400));
assert_eq!(dev_fund_height_range.start, canopy_activation_height);
assert_eq!(dev_fund_height_range.end, nu6_activation_height);
assert_eq!(nu6_fund_height_range.start, nu6_activation_height);
assert_eq!(nu6_fund_height_range.end, nu6_fund_end);
assert_eq!(dev_fund_height_range.end, nu6_fund_height_range.start);
let mut expected_dev_fund = HashMap::new();
expected_dev_fund.insert(FundingStreamReceiver::Ecc, Amount::try_from(21_875_000)?);
expected_dev_fund.insert(
FundingStreamReceiver::ZcashFoundation,
Amount::try_from(15_625_000)?,
);
hash_map.insert(
expected_dev_fund.insert(
FundingStreamReceiver::MajorGrants,
Amount::try_from(25_000_000)?,
);
let expected_dev_fund = expected_dev_fund;
assert_eq!(
funding_stream_values(
canopy_height,
network,
block_subsidy(canopy_height, network)?
)
.unwrap(),
hash_map
);
assert_eq!(
funding_stream_values(
canopy_height_plus1,
network,
block_subsidy(canopy_height_plus1, network)?
)
.unwrap(),
hash_map
);
assert_eq!(
funding_stream_values(
canopy_height_plus2,
network,
block_subsidy(canopy_height_plus2, network)?
)
.unwrap(),
hash_map
);
// funding stream period is ending
let range = network.pre_nu6_funding_streams().height_range();
let end = range.end;
let last = (end - 1).unwrap();
assert_eq!(
funding_stream_values(last, network, block_subsidy(last, network)?).unwrap(),
hash_map
);
assert!(funding_stream_values(end, network, block_subsidy(end, network)?)?.is_empty());
// TODO: Replace this with Mainnet once there's an NU6 activation height defined for Mainnet
let network = testnet::Parameters::build()
.with_activation_heights(ConfiguredActivationHeights {
blossom: Some(Blossom.activation_height(network).unwrap().0),
nu6: Some(POST_NU6_FUNDING_STREAMS_MAINNET.height_range().start.0),
..Default::default()
})
.with_post_nu6_funding_streams(ConfiguredFundingStreams {
// Start checking funding streams from block height 1
height_range: Some(POST_NU6_FUNDING_STREAMS_MAINNET.height_range().clone()),
// Use default post-NU6 recipients
recipients: Some(
POST_NU6_FUNDING_STREAMS_TESTNET
.recipients()
.iter()
.map(|(&receiver, recipient)| ConfiguredFundingStreamRecipient {
receiver,
numerator: recipient.numerator(),
addresses: Some(
recipient
.addresses()
.iter()
.map(|addr| addr.to_string())
.collect(),
),
})
.collect(),
),
})
.to_network();
let mut hash_map = HashMap::new();
hash_map.insert(
let mut expected_nu6_fund = HashMap::new();
expected_nu6_fund.insert(
FundingStreamReceiver::Deferred,
Amount::try_from(18_750_000)?,
);
hash_map.insert(
expected_nu6_fund.insert(
FundingStreamReceiver::MajorGrants,
Amount::try_from(12_500_000)?,
);
let nu6_height = Nu6.activation_height(&network).unwrap();
let expected_nu6_fund = expected_nu6_fund;
for height in [
nu6_height,
Height(nu6_height.0 + 1),
Height(nu6_height.0 + 1),
dev_fund_height_range.start.previous().unwrap(),
dev_fund_height_range.start,
dev_fund_height_range.start.next().unwrap(),
dev_fund_height_range.end.previous().unwrap(),
dev_fund_height_range.end,
dev_fund_height_range.end.next().unwrap(),
nu6_fund_height_range.start.previous().unwrap(),
nu6_fund_height_range.start,
nu6_fund_height_range.start.next().unwrap(),
nu6_fund_height_range.end.previous().unwrap(),
nu6_fund_height_range.end,
nu6_fund_height_range.end.next().unwrap(),
] {
assert_eq!(
funding_stream_values(height, &network, block_subsidy(height, &network)?).unwrap(),
hash_map
);
}
let fsv = funding_stream_values(height, network, block_subsidy(height, network)?).unwrap();
// TODO: Replace this with Mainnet once there's an NU6 activation height defined for Mainnet
let network = testnet::Parameters::build()
.with_activation_heights(ConfiguredActivationHeights {
blossom: Some(Blossom.activation_height(&network).unwrap().0),
nu6: Some(POST_NU6_FUNDING_STREAMS_MAINNET.height_range().start.0),
..Default::default()
})
.with_post_nu6_funding_streams(ConfiguredFundingStreams {
// Start checking funding streams from block height 1
height_range: Some(POST_NU6_FUNDING_STREAMS_MAINNET.height_range().clone()),
// Use default post-NU6 recipients
recipients: Some(
POST_NU6_FUNDING_STREAMS_TESTNET
.recipients()
.iter()
.map(|(&receiver, recipient)| ConfiguredFundingStreamRecipient {
receiver,
numerator: recipient.numerator(),
addresses: Some(
recipient
.addresses()
.iter()
.map(|addr| addr.to_string())
.collect(),
),
})
.collect(),
),
})
.to_network();
let mut hash_map = HashMap::new();
hash_map.insert(
FundingStreamReceiver::Deferred,
Amount::try_from(18_750_000)?,
);
hash_map.insert(
FundingStreamReceiver::MajorGrants,
Amount::try_from(12_500_000)?,
);
let nu6_height = Nu6.activation_height(&network).unwrap();
for height in [
nu6_height,
Height(nu6_height.0 + 1),
Height(nu6_height.0 + 1),
] {
assert_eq!(
funding_stream_values(height, &network, block_subsidy(height, &network)?).unwrap(),
hash_map
);
if height < canopy_activation_height {
assert!(fsv.is_empty());
} else if height < nu6_activation_height {
assert_eq!(fsv, expected_dev_fund);
} else if height < nu6_fund_end {
assert_eq!(fsv, expected_nu6_fund);
} else {
assert!(fsv.is_empty());
}
}
Ok(())

View File

@ -120,47 +120,10 @@ pub fn output_amounts(transaction: &Transaction) -> HashSet<Amount<NonNegative>>
.collect()
}
/// Lockbox funding stream total input value for a block height.
///
/// Assumes a constant funding stream amount per block.
// TODO: Cache the lockbox value balance in zebra-state (will be required for tracking lockbox
// value balance after the Zcash Sustainability Fund ZIPs or after a ZIP for spending from the deferred pool)
#[allow(dead_code)]
fn lockbox_input_value(network: &Network, height: Height) -> Amount<NonNegative> {
let Some(nu6_activation_height) = Nu6.activation_height(network) else {
return Amount::zero();
};
let expected_block_subsidy = block_subsidy(nu6_activation_height, network)
.expect("block at NU6 activation height must have valid expected subsidy");
let &deferred_amount_per_block =
funding_stream_values(nu6_activation_height, network, expected_block_subsidy)
.expect("we always expect a funding stream hashmap response even if empty")
.get(&FundingStreamReceiver::Deferred)
.expect("we expect a lockbox funding stream after NU5");
let post_nu6_funding_stream_height_range = network.post_nu6_funding_streams().height_range();
// `min(height, last_height_with_deferred_pool_contribution) - (nu6_activation_height - 1)`,
// We decrement NU6 activation height since it's an inclusive lower bound.
// Funding stream height range end bound is not incremented since it's an exclusive end bound
let num_blocks_with_lockbox_output = (height.0 + 1)
.min(post_nu6_funding_stream_height_range.end.0)
.checked_sub(post_nu6_funding_stream_height_range.start.0)
.unwrap_or_default();
(deferred_amount_per_block * num_blocks_with_lockbox_output.into())
.expect("lockbox input value should fit in Amount")
}
#[cfg(test)]
mod test {
use super::*;
use color_eyre::Report;
use zebra_chain::parameters::testnet::{
self, ConfiguredActivationHeights, ConfiguredFundingStreamRecipient,
ConfiguredFundingStreams,
};
#[test]
fn halving_test() -> Result<(), Report> {
@ -436,73 +399,6 @@ mod test {
Ok(())
}
#[test]
fn check_lockbox_input_value() -> Result<(), Report> {
let _init_guard = zebra_test::init();
let network = testnet::Parameters::build()
.with_activation_heights(ConfiguredActivationHeights {
blossom: Some(Blossom.activation_height(&Network::Mainnet).unwrap().0),
nu6: Some(POST_NU6_FUNDING_STREAMS_MAINNET.height_range().start.0),
..Default::default()
})
.with_post_nu6_funding_streams(ConfiguredFundingStreams {
// Start checking funding streams from block height 1
height_range: Some(POST_NU6_FUNDING_STREAMS_MAINNET.height_range().clone()),
// Use default post-NU6 recipients
recipients: Some(
POST_NU6_FUNDING_STREAMS_TESTNET
.recipients()
.iter()
.map(|(&receiver, recipient)| ConfiguredFundingStreamRecipient {
receiver,
numerator: recipient.numerator(),
addresses: Some(
recipient
.addresses()
.iter()
.map(|addr| addr.to_string())
.collect(),
),
})
.collect(),
),
})
.to_network();
let nu6_height = Nu6.activation_height(&network).unwrap();
let post_nu6_funding_streams = network.post_nu6_funding_streams();
let height_range = post_nu6_funding_streams.height_range();
let last_funding_stream_height = post_nu6_funding_streams
.height_range()
.end
.previous()
.expect("the previous height should be valid");
assert_eq!(
Amount::<NonNegative>::zero(),
lockbox_input_value(&network, Height::MIN)
);
let expected_lockbox_value: Amount<NonNegative> = Amount::try_from(18_750_000)?;
assert_eq!(
expected_lockbox_value,
lockbox_input_value(&network, nu6_height)
);
let num_blocks_total = height_range.end.0 - height_range.start.0;
let expected_input_per_block: Amount<NonNegative> = Amount::try_from(18_750_000)?;
let expected_lockbox_value = (expected_input_per_block * num_blocks_total.into())?;
assert_eq!(
expected_lockbox_value,
lockbox_input_value(&network, last_funding_stream_height)
);
Ok(())
}
#[test]
fn check_height_for_num_halvings() {
for network in Network::iter() {

View File

@ -515,7 +515,7 @@ fn miner_fees_validation_for_network(network: Network) -> Result<(), Report> {
let expected_block_subsidy = block_subsidy(height, &network)?;
// TODO: Add link to lockbox stream ZIP
// See [ZIP-1015](https://zips.z.cash/zip-1015).
let expected_deferred_amount = subsidy::funding_streams::funding_stream_values(
height,
&network,
@ -549,8 +549,8 @@ fn miner_fees_validation_failure() -> Result<(), Report> {
.expect("block should deserialize");
let height = block.coinbase_height().expect("valid coinbase height");
let expected_block_subsidy = block_subsidy(height, &network)?;
// TODO: Add link to lockbox stream ZIP
let expected_deferred_amount =
// See [ZIP-1015](https://zips.z.cash/zip-1015).
let expected_deferred_amount: Amount<zebra_chain::amount::NonNegative> =
subsidy::funding_streams::funding_stream_values(height, &network, expected_block_subsidy)
.expect("we always expect a funding stream hashmap response even if empty")
.remove(&FundingStreamReceiver::Deferred)

View File

@ -611,7 +611,7 @@ where
// We can't get the block subsidy for blocks with heights in the slow start interval, so we
// omit the calculation of the expected deferred amount.
let expected_deferred_amount = if height > self.network.slow_start_interval() {
// TODO: Add link to lockbox stream ZIP
// See [ZIP-1015](https://zips.z.cash/zip-1015).
funding_stream_values(height, &self.network, block_subsidy(height, &self.network)?)?
.remove(&FundingStreamReceiver::Deferred)
} else {

View File

@ -12303,3 +12303,44 @@
2674806 00000000014f2059c0d91a8ed6023b08294593de773268abb0b4ad79d9d20581
2675206 00000000003ebb8baab4ceaf73fde6753d4281edfa07c897458ce9a1c5ff57ee
2675606 0000000000065afdce346665ab6ca463930733149eaaf1e79033b08232f7a363
2676006 0000000000ae0fb36f32bebe3cec27138c17442b8f960b44eddc79dc4969b908
2676406 000000000132fe4bd59ece660621ff96a30d780dc544459ce1eb94b6537d2511
2676806 000000000179777a6a7dd70e5c4791522458300612e95026a2f4081941216a87
2677206 0000000000050ec5366c935475d03b93acb930c8050c99978c1f354991cdba07
2677606 000000000126f7174d1012be32008f308ff34e54d6368f015bce9074134e3856
2678006 0000000000b06a9511a735b19be0db8460b8e4cbae128b54a9b7ff39998531a7
2678406 000000000192f01202a19f87fecc5d92222c23bed2ab64df250782e2bfff4120
2678806 00000000016260f71bacd75a453116ab5376fb38d2f056b60e14031f780f5e55
2679206 00000000013163a96dd7dff82aad81ee27bb7cac2c0bdec637d7a09fe4f63788
2679606 000000000159321160154c3315582efbe7b4f05f683c77c8022ebc2862c929f4
2680006 00000000014270fb475e0aab7c7561c36fd58ab925eca2636c2a70e40bf7e23e
2680406 00000000002db0db381bc4cf519b450d5953ee371e28c317ca204770118f64dd
2680806 0000000000b05f2a1efa6edbe4a6176b860dc9cee99980f136953b2addde0058
2681206 00000000012c125a114701916aa2d29cb25b84a6d68680328d606c3ef7d08934
2681606 0000000001425cb05ee9358e9edb7a1e91428f76456ad2769ef8d13d12db0a65
2682006 00000000001463dfd47a94d900a2c8c6ee4013c1cc22e78eb3c6e09416323222
2682406 00000000006805bed45600d40df8f62d6133c6ae563e70d365b0610d171823fb
2682806 0000000000001915d3ebc38ab8a37307fa8a2e7c8228161820d4a0a936d12456
2683206 00000000002cc19cd0e5b7c0ee0ae6f2535eaf632efd6e3d87788f046cee43eb
2683606 00000000003ed8e350ceeac08f8579c63386696c42d4e63d666459ec93d5c22a
2684006 00000000007e9a086dc2586d0a139aa906007793a435055f4acd6543d710663b
2684406 000000000138cdd1607839258c15e684de1733db967a3a4645b0b64ea6ed2521
2684806 0000000000a11042fcdd30f8d52dc52229ccac9cdebf9610413db239865100ff
2685206 00000000009464c0848870970a56d670f7f144423f3726ff893edc160df911b3
2685606 00000000001e26dd383717aeb9a9331300994bffc621ed8f00cc83168e9be720
2686006 0000000000a88a85865f8cb56fc8a03114649e589f2aae0f53921ff993b878c6
2686406 00000000005f0ed9b676e945092065fd073ffb4e4c2a80a2efa632f188921ea5
2686806 00000000006353f0748266e3cfa5306aaa4a8eeb83de7864836ef681cd8f911e
2687206 00000000013a162bcbe3cdceeab9724e4c7cdde6ab5b384353434e04aa09db8b
2687606 0000000000d2b7c500864c5b16f35fd519a28b1a26ecb1f249a3be1903165c8a
2688006 000000000061ed5dc31dcdc8af5de0c92354a4fe9cee00d726e78b7b2e55a26e
2688406 0000000001283342e0cd041487dbf38d1a2b2c987071cf847b930864a2244587
2688806 00000000008b79e1eac8be1c9376df5aab25fb1feb6655d473b24605e2732212
2689206 0000000000b4446a46d369ef91b7f02984ac079be0049cf65c2f4117ede74551
2689606 00000000005a8f415767fce4aec3e4994b518ec0b74923255cc8d2146c61d527
2690006 0000000000e485f4e858c0ba264419fc1e39b7c8dae7a468ffe80c054cad4f03
2690406 00000000009d3bea65e90ea624b25e6cd34843941d0688a7d859f3d6f6b5262b
2690806 0000000000079e9c443b47d4208c2465aa89245824b6b420af0f77bb4088f267
2691206 00000000015ff7395bab470fe1bc13758db68653bbcddf26f4d967817bcb5f6c
2691606 0000000000b35f7d242f8456123e83718c33af77072ce6cf709bfb34cb59fd3f
2692006 0000000000cc6bed9807a23d703d66735a63d615a494c5131c7f7c9f1f464cdc

View File

@ -7533,3 +7533,63 @@
3012800 00a5a4c7aa1e5120b05358100083165fdae6d3da4932391f806dc70b17de43b0
3013200 005816e627c296c77a1088915b359185349a4b4b345a325a889a4854c6598f71
3013600 0067f8576378bcfa73c91f734526234125ab0cc306bcbfc415359000f54908fe
3014000 0047db25b5870ba5647e850b31d06a0bd3a64d8227fe4c4479776f3e561144c2
3014400 0082aedbe923338010bc24b74c5f4b8a2def5980a594632e0862a218199182ea
3014800 003efd3df72cd4f2f3dfffd7bfd0c987abb43148635b09f0b554ac96cf4d77ff
3015200 0026fe0c4014b137f56fb103d1e5eb23bb586d0f18ab1043c67aec24f96fea69
3015600 00aef18251e46a440005bec4d07322def2a5c9a386ca9a7c3d4ad96b6d31465f
3016000 000ebd6ecca080b1b124e34b15e47ac174dd22bee50b6425a19fe0d2e94cf164
3016400 00801bd3ae71526b707d8907eec5fbc858faef07397bfce9b883380ed1a203e2
3016800 004c3c99816d2f5fd5fdf52f9b2682960963450674cd7857f213fb109750771d
3017200 003e417aab3c028eeff98ea2510f90be9b1d7923d0ba8660218a7af42a793045
3017600 0006feba88f2d2a73b31c4a355fdd4e6841a40eaa4947de11541809f58ea091f
3018000 007029069b2fe1195bf062b79c5d8ff1e6f3656e080daf6cd9c950c95b81b56e
3018400 0014fb41444c4716e179c9cc4636116aad70fac626a0e4495fa4f379fc8b1e6c
3018800 00403a00bb37790b932e5c61e5f9d8c5ce553f9881b5d478f68e8cc734f7fb8b
3019200 0067e637848ad92b5a686d4f05fce8c915aa697b2d6ec994362632ac2db62815
3019600 00033cb248e2fcbe49e20a6bfa1d4782e9587b7f1a8da1bbcb02a1894b8cdfee
3020000 00aa46c4cee563ee16aedad5a4c204ac15715087bd4e988193439ec6aab74e50
3020400 00000810081b7776aafb8c772511e3a6fa7b5df3d3699cea769676412eb37e91
3020800 00a60475dcf37ceba4610e1228a98d59f54eb2446498636131c05fd8433f0461
3021200 0000058dd082ad737e2279b54ac4db390e19c8c33ad0cd75bb395f4400af01d7
3021600 0018edaf94a979633b92303dfe7e6da19ae1304dda76dc220bb951c6921a2144
3022000 00086d3b10982cdda5d3c5aae5c17cbd588e65764f19e3976c2e16822218e2b9
3022400 00032f7487a09797f764b2925a9abcb5f53a6c28fcf892c104f102dae49012ed
3022800 009d941281cf33b562a833d90ae3df8bc21aaebfb88d8eea2fe96e62a3c66e44
3023200 002f0bfd1e23bb01a36f2743a8c9d5d71aaf7e064eaf40f26eb7d68e582e5c6b
3023600 0084d119c5b83fac272b433a6cd1ac15a8b7f63be9263095d210532be48427ec
3024000 005f83cd9c8e1886b9e57cbb63024113ec8a7e701cf20726186a05227be031dd
3024400 0010483256d69d7c50160328638c7e1cfcd6f8a5f57f18138692fa9264759771
3024800 001b66d2440019053592404d5fe5a0571b4398760353a739b68711b13f157dbb
3025200 0019c9f670531c8ac0eb9d2e04aca45db303b7398b8be69b2126d4a342b405f8
3025600 00234944d221b69685fb991e61322f8c05f1aa4e74bfd0d54f6c6d5684119625
3026000 004fce9e3a8c893cef64cefea26ea7ec4eb43fb997a5ebb861f1b8c6934acf1b
3026400 0023d6bce6b7024f5c8370ca03113b612c7f463e76260505ff51fba9eb50b773
3026800 00324f18aa6a9dde2111af5dda458d9a25e60569503483094024555d79c6eb04
3027200 0032663b3021c78f5ae8dcf187accd5286aba69f6b322f733480c435d4afc314
3027600 0026bbd7606bd027b5104b0caf814f14e5135a2415d87d7ef4e838ff88746486
3028000 00dd4248207a87d206a079f271e02ec44303f9cff352d401a63c20bfaef7d4c4
3028400 003a7519cf0199b59114d73ec441418b5b667aa7bf7bb40a052e2f2c74d75da6
3028800 00526c96220485d7fd697e1ffb11ecb49ae6086cefe1a6bd73ee632dfab0135a
3029200 0003d88d4998cd49bd83115c7b864ace6ef1e78240a3dff4ad42624c9bc29a17
3029600 00568a51b1b822f72785e1ccb1604cc6e38a1b2c6233da5e13bd41730403eaaa
3030000 00118e6ca5f8545f6f6351c6f4ab549a0b012f68cd340c9caf8f0c3c608f37aa
3030400 0087bc46a5fff506d8ffed4d778349d5789b7b78867cea281931f4e3ba5288f4
3030800 003587d5014130b331972bb05d0fa39b9fc97a0606b83041f5b666869c0bc098
3031200 006538bd02d4cbb6eaab7c24478b30eddab46c420da124c8c2ea5924bb4ae9b4
3031600 001b7216bb9078dd384ff26f9062e83b2852e65f475599d261c7f5f552429de7
3032000 003199fca669ee1b3325a2f8e7e0d93156d8fba4a8de1e31d0180d7ed8b81732
3032400 0056bb821d2572bb29446b99c13056397e79a088e575068d5489559c976f5bd7
3032800 00145652968a8f4924b435e4f6da8ac6fbd6977cd08c63ad7673723c93cfcd6d
3033200 007ec80961e0026d08f73289a80887e3083fccd194d78a7ecc3ca3340b906dda
3033600 003d60228ba1b12f8ff36d5f25bae4e79c8dff77342449ff35167190ee82e8f4
3034000 000988b3b1bd6d9d63ce99fe7af49614245adac3d0ac3a9c4054efe5574ddb39
3034400 001255003bd53890368ed97a39afb59925718cee148fff51881c54ed6ccf1243
3034800 00101aff2b5d53af8173408a147686f765e9922bc8331e2c789e40ce8adb18b0
3035200 01429efa675108f6c13f29a23e7c44847c98e0d267aafddd0efac8cd0e2ba6d2
3035600 00e868391b70a80d81599f7687262b8451dbe57992e630db772344008900fec8
3036000 0086fcb484bd4b1639d64b2f42d1d62be8bc2ea353eb8cac735ccd50264f2772
3036400 0199867258074263dd540bf4047e91d8c1cd40fb294ab102fd8c9072317de95f
3036800 002aa078e4546a72e4c6290402924c0917c2080a4dd9e0f7e7e851e82bcf562c
3037200 00613812406826a9bfa52508d602c8d14271c4dcf1cee107a9d2b8cff9ef51b5
3037600 00b758e58e0b8f8298a52e0246860ea833e6dc3ffb447d44474662c658b373c0

View File

@ -345,6 +345,9 @@ pub enum BlockError {
hash: zebra_chain::block::Hash,
source: amount::Error,
},
#[error("unexpected error occurred: {0}")]
Other(String),
}
impl From<SubsidyError> for BlockError {

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-grpc"
version = "0.1.0-alpha.7"
version = "0.1.0-alpha.8"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Zebra gRPC interface"
license = "MIT OR Apache-2.0"
@ -20,16 +20,16 @@ futures-util = "0.3.28"
tonic = "0.12.3"
tonic-reflection = "0.12.3"
prost = "0.13.3"
serde = { version = "1.0.210", features = ["serde_derive"] }
tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread"] }
serde = { version = "1.0.211", features = ["serde_derive"] }
tokio = { version = "1.41.0", features = ["macros", "rt-multi-thread"] }
tokio-stream = "0.1.16"
tower = { version = "0.4.13", features = ["util", "buffer", "timeout"] }
color-eyre = "0.6.3"
zcash_primitives.workspace = true
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = ["shielded-scan"] }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.40" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.41", features = ["shielded-scan"] }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.41" }
[build-dependencies]
tonic-build = "0.12.3"

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-network"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>", "Tower Maintainers <team@tower-rs.com>"]
description = "Networking code for Zebra"
# # Legal
@ -42,31 +42,31 @@ proptest-impl = ["proptest", "proptest-derive", "zebra-chain/proptest-impl"]
[dependencies]
bitflags = "2.5.0"
byteorder = "1.5.0"
bytes = "1.7.2"
bytes = "1.8.0"
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
dirs = "5.0.1"
hex = "0.4.3"
humantime-serde = "1.1.1"
indexmap = { version = "2.5.0", features = ["serde"] }
indexmap = { version = "2.6.0", features = ["serde"] }
itertools = "0.13.0"
lazy_static = "1.4.0"
num-integer = "0.1.46"
ordered-map = "0.4.2"
pin-project = "1.1.5"
pin-project = "1.1.6"
rand = "0.8.5"
rayon = "1.10.0"
regex = "1.11.0"
serde = { version = "1.0.210", features = ["serde_derive"] }
serde = { version = "1.0.211", features = ["serde_derive"] }
tempfile = "3.13.0"
thiserror = "1.0.64"
futures = "0.3.30"
tokio = { version = "1.40.0", features = ["fs", "io-util", "net", "time", "tracing", "macros", "rt-multi-thread"] }
futures = "0.3.31"
tokio = { version = "1.41.0", features = ["fs", "io-util", "net", "time", "tracing", "macros", "rt-multi-thread"] }
tokio-stream = { version = "0.1.16", features = ["sync", "time"] }
tokio-util = { version = "0.7.12", features = ["codec"] }
tower = { version = "0.4.13", features = ["retry", "discover", "load", "load-shed", "timeout", "util", "buffer"] }
metrics = "0.23.0"
metrics = "0.24.0"
tracing-futures = "0.2.5"
tracing-error = { version = "0.2.0", features = ["traced-error"] }
tracing = "0.1.39"
@ -83,14 +83,14 @@ howudoin = { version = "0.1.2", optional = true }
proptest = { version = "1.4.0", optional = true }
proptest-derive = { version = "0.5.0", optional = true }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["async-error"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = ["async-error"] }
[dev-dependencies]
proptest = "1.4.0"
proptest-derive = "0.5.0"
static_assertions = "1.1.0"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
toml = "0.8.19"
zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] }

View File

@ -337,7 +337,10 @@ 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_110);
///
/// This version of Zebra draws the current network protocol version from
/// [ZIP-253](https://zips.z.cash/zip-0253).
pub const CURRENT_NETWORK_PROTOCOL_VERSION: Version = Version(170_120);
/// The default RTT estimate for peer responses.
///
@ -393,6 +396,7 @@ lazy_static! {
///
/// The minimum network protocol version typically changes after Mainnet and
/// Testnet network upgrades.
// TODO: Change `Nu5` to `Nu6` after NU6 activation.
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
pub static ref INITIAL_MIN_NETWORK_PROTOCOL_VERSION: HashMap<NetworkKind, Version> = {
let mut hash_map = HashMap::new();

View File

@ -72,12 +72,23 @@ impl Version {
/// Returns the minimum specified network protocol version for `network` and
/// `network_upgrade`.
///
/// ## ZIP-253
///
/// > Nodes compatible with a network upgrade activation MUST advertise a network protocol
/// > version that is greater than or equal to the MIN_NETWORK_PROTOCOL_VERSION for that
/// > activation.
///
/// <https://zips.z.cash/zip-0253>
///
/// ### Notes
///
/// - The citation above is a generalization of a statement in ZIP-253 since that ZIP is
/// concerned only with NU6 on Mainnet and Testnet.
pub(crate) fn min_specified_for_upgrade(
network: &Network,
network_upgrade: NetworkUpgrade,
) -> Version {
// TODO: Should we reject earlier protocol versions during our initial
// sync? zcashd accepts 170_002 or later during its initial sync.
Version(match (network, network_upgrade) {
(_, Genesis) | (_, BeforeOverwinter) => 170_002,
(Testnet(params), Overwinter) if params.is_default_testnet() => 170_003,

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-node-services"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "The interfaces of some Zebra node services"
license = "MIT OR Apache-2.0"
@ -37,7 +37,7 @@ rpc-client = [
shielded-scan = []
[dependencies]
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.40" }
zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.41" }
# Optional dependencies
@ -46,14 +46,14 @@ color-eyre = { version = "0.6.3", optional = true }
jsonrpc-core = { version = "18.0.0", optional = true }
# Security: avoid default dependency on openssl
reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true }
serde = { version = "1.0.210", optional = true }
serde_json = { version = "1.0.128", optional = true }
tokio = { version = "1.40.0", features = ["time", "sync"] }
serde = { version = "1.0.211", optional = true }
serde_json = { version = "1.0.132", optional = true }
tokio = { version = "1.41.0", features = ["time", "sync"] }
[dev-dependencies]
color-eyre = "0.6.3"
jsonrpc-core = "18.0.0"
reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"] }
serde = "1.0.210"
serde_json = "1.0.128"
serde = "1.0.211"
serde_json = "1.0.132"

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-rpc"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "A Zebra JSON Remote Procedure Call (JSON-RPC) interface"
license = "MIT OR Apache-2.0"
@ -33,7 +33,6 @@ indexer-rpcs = [
# Mining RPC support
getblocktemplate-rpcs = [
"rand",
"zcash_address",
"zebra-consensus/getblocktemplate-rpcs",
"zebra-state/getblocktemplate-rpcs",
@ -58,17 +57,24 @@ chrono = { version = "0.4.38", default-features = false, features = [
"clock",
"std",
] }
futures = "0.3.30"
futures = "0.3.31"
jsonrpc-core = "18.0.0"
jsonrpc-derive = "18.0.0"
jsonrpc-http-server = "18.0.0"
# zebra-rpc needs the preserve_order feature in serde_json, which is a dependency of jsonrpc-core
serde_json = { version = "1.0.128", features = ["preserve_order"] }
indexmap = { version = "2.5.0", features = ["serde"] }
serde_json = { version = "1.0.132", features = ["preserve_order"] }
indexmap = { version = "2.6.0", features = ["serde"] }
tokio = { version = "1.40.0", features = [
# RPC endpoint basic auth
base64 = "0.22.1"
rand = "0.8.5"
# Error handling
color-eyre = "0.6.3"
tokio = { version = "1.41.0", features = [
"time",
"rt-multi-thread",
"macros",
@ -85,31 +91,29 @@ tokio-stream = { version = "0.1.16", optional = true }
tracing = "0.1.39"
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.210", features = ["serde_derive"] }
serde = { version = "1.0.211", features = ["serde_derive"] }
# For the `stop` RPC method.
nix = { version = "0.29.0", features = ["signal"] }
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
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.40", features = [
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = [
"json-conversion",
] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = [
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.41" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.41" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.41", features = [
"rpc-client",
] }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.40" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40" }
zebra-script = { path = "../zebra-script", version = "1.0.0-beta.41" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41" }
[build-dependencies]
tonic-build = { version = "0.12.3", optional = true }
@ -120,19 +124,19 @@ insta = { version = "1.40.0", features = ["redactions", "json", "ron"] }
proptest = "1.4.0"
thiserror = "1.0.64"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = [
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = [
"proptest-impl",
] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40", features = [
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.41", features = [
"proptest-impl",
] }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40", features = [
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.41", features = [
"proptest-impl",
] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = [
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41", features = [
"proptest-impl",
] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.41" }

View File

@ -7,6 +7,7 @@ network = "Regtest"
[rpc]
listen_addr = "127.0.0.1:0"
enable_cookie_auth = false
[state]
cache_dir = ""

View File

@ -1,9 +1,11 @@
//! User-configurable RPC settings.
use std::net::SocketAddr;
use std::{net::SocketAddr, path::PathBuf};
use serde::{Deserialize, Serialize};
use zebra_chain::common::default_cache_dir;
pub mod mining;
/// RPC configuration section.
@ -71,6 +73,12 @@ pub struct Config {
/// Test-only option that makes Zebra say it is at the chain tip,
/// no matter what the estimated height or local clock is.
pub debug_force_finished_sync: bool,
/// The directory where Zebra stores RPC cookies.
pub cookie_dir: PathBuf,
/// Enable cookie-based authentication for RPCs.
pub enable_cookie_auth: bool,
}
// This impl isn't derivable because it depends on features.
@ -94,6 +102,12 @@ impl Default for Config {
// Debug options are always off by default.
debug_force_finished_sync: false,
// Use the default cache dir for the auth cookie.
cookie_dir: default_cache_dir(),
// Enable cookie-based authentication by default.
enable_cookie_auth: true,
}
}
}

View File

@ -6,7 +6,7 @@ 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",
"specification": "https://zips.z.cash/zip-1015",
"value": 0.125,
"valueZat": 12500000,
"address": "t2HifwjUj9uyxr9bknR8LFuQbc98c3vkXtu"
@ -15,7 +15,7 @@ expression: get_block_subsidy
"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",
"specification": "https://zips.z.cash/zip-1015",
"value": 0.1875,
"valueZat": 18750000
}

View File

@ -64,6 +64,11 @@ expression: info
"name": "NU5",
"activationheight": 1687104,
"status": "pending"
},
"c8e71055": {
"name": "NU6",
"activationheight": 2726400,
"status": "pending"
}
},
"consensus": {

View File

@ -9,6 +9,8 @@
use std::{fmt, panic, thread::available_parallelism};
use cookie::Cookie;
use http_request_compatibility::With;
use jsonrpc_core::{Compatibility, MetaIoHandler};
use jsonrpc_http_server::{CloseHandle, ServerBuilder};
use tokio::task::JoinHandle;
@ -25,7 +27,7 @@ use crate::{
config::Config,
methods::{Rpc, RpcImpl},
server::{
http_request_compatibility::FixHttpRequestMiddleware,
http_request_compatibility::HttpRequestMiddleware,
rpc_call_compatibility::FixRpcResponseMiddleware,
},
};
@ -33,6 +35,7 @@ use crate::{
#[cfg(feature = "getblocktemplate-rpcs")]
use crate::methods::{GetBlockTemplateRpc, GetBlockTemplateRpcImpl};
pub mod cookie;
pub mod http_request_compatibility;
pub mod rpc_call_compatibility;
@ -199,13 +202,22 @@ impl RpcServer {
let span = Span::current();
let start_server = move || {
span.in_scope(|| {
let middleware = if config.enable_cookie_auth {
let cookie = Cookie::default();
cookie::write_to_disk(&cookie, &config.cookie_dir)
.expect("Zebra must be able to write the auth cookie to the disk");
HttpRequestMiddleware::default().with(cookie)
} else {
HttpRequestMiddleware::default()
};
// Use a different tokio executor from the rest of Zebra,
// so that large RPCs and any task handling bugs don't impact Zebra.
let server_instance = ServerBuilder::new(io)
.threads(parallel_cpu_threads)
// TODO: disable this security check if we see errors from lightwalletd
//.allowed_hosts(DomainsValidation::Disabled)
.request_middleware(FixHttpRequestMiddleware)
.request_middleware(middleware)
.start_http(&listen_addr)
.expect("Unable to start RPC server");
@ -274,29 +286,39 @@ impl RpcServer {
/// This method can be called from within a tokio executor without panicking.
/// But it is blocking, so `shutdown()` should be used instead.
pub fn shutdown_blocking(&self) {
Self::shutdown_blocking_inner(self.close_handle.clone())
Self::shutdown_blocking_inner(self.close_handle.clone(), self.config.clone())
}
/// Shut down this RPC server asynchronously.
/// Returns a task that completes when the server is shut down.
pub fn shutdown(&self) -> JoinHandle<()> {
let close_handle = self.close_handle.clone();
let config = self.config.clone();
let span = Span::current();
tokio::task::spawn_blocking(move || {
span.in_scope(|| Self::shutdown_blocking_inner(close_handle))
span.in_scope(|| Self::shutdown_blocking_inner(close_handle, config))
})
}
/// Shuts down this RPC server using its `close_handle`.
///
/// See `shutdown_blocking()` for details.
fn shutdown_blocking_inner(close_handle: CloseHandle) {
fn shutdown_blocking_inner(close_handle: CloseHandle, config: Config) {
// The server is a blocking task, so it can't run inside a tokio thread.
// See the note at wait_on_server.
let span = Span::current();
let wait_on_shutdown = move || {
span.in_scope(|| {
if config.enable_cookie_auth {
if let Err(err) = cookie::remove_from_disk(&config.cookie_dir) {
warn!(
?err,
"unexpectedly could not remove the rpc auth cookie from the disk"
)
}
}
info!("Stopping RPC server");
close_handle.clone().close();
debug!("Stopped RPC server");

View File

@ -0,0 +1,54 @@
//! Cookie-based authentication for the RPC server.
use base64::{engine::general_purpose::URL_SAFE, Engine as _};
use color_eyre::Result;
use rand::RngCore;
use std::{
fs::{remove_file, File},
io::Write,
path::Path,
};
/// The name of the cookie file on the disk
const FILE: &str = ".cookie";
/// If the RPC authentication is enabled, all requests must contain this cookie.
#[derive(Clone, Debug)]
pub struct Cookie(String);
impl Cookie {
/// Checks if the given passwd matches the contents of the cookie.
pub fn authenticate(&self, passwd: String) -> bool {
*passwd == self.0
}
}
impl Default for Cookie {
fn default() -> Self {
let mut bytes = [0u8; 32];
rand::thread_rng().fill_bytes(&mut bytes);
Self(URL_SAFE.encode(bytes))
}
}
/// Writes the given cookie to the given dir.
pub fn write_to_disk(cookie: &Cookie, dir: &Path) -> Result<()> {
// Create the directory if needed.
std::fs::create_dir_all(dir)?;
File::create(dir.join(FILE))?.write_all(format!("__cookie__:{}", cookie.0).as_bytes())?;
tracing::info!("RPC auth cookie written to disk");
Ok(())
}
/// Removes a cookie from the given dir.
pub fn remove_from_disk(dir: &Path) -> Result<()> {
remove_file(dir.join(FILE))?;
tracing::info!("RPC auth cookie removed from disk");
Ok(())
}

View File

@ -2,24 +2,27 @@
//!
//! These fixes are applied at the HTTP level, before the RPC request is parsed.
use base64::{engine::general_purpose::URL_SAFE, Engine as _};
use futures::TryStreamExt;
use jsonrpc_http_server::{
hyper::{body::Bytes, header, Body, Request},
RequestMiddleware, RequestMiddlewareAction,
};
use super::cookie::Cookie;
/// HTTP [`RequestMiddleware`] with compatibility workarounds.
///
/// This middleware makes the following changes to HTTP requests:
///
/// ## Remove `jsonrpc` field in JSON RPC 1.0
/// ### Remove `jsonrpc` field in JSON RPC 1.0
///
/// Removes "jsonrpc: 1.0" fields from requests,
/// because the "jsonrpc" field was only added in JSON-RPC 2.0.
///
/// <http://www.simple-is-better.org/rpc/#differences-between-1-0-and-2-0>
///
/// ## Add missing `content-type` HTTP header
/// ### Add missing `content-type` HTTP header
///
/// Some RPC clients don't include a `content-type` HTTP header.
/// But unlike web browsers, [`jsonrpc_http_server`] does not do content sniffing.
@ -27,6 +30,11 @@ use jsonrpc_http_server::{
/// If there is no `content-type` header, we assume the content is JSON,
/// and let the parser error if we are incorrect.
///
/// ### Authenticate incoming requests
///
/// If the cookie-based RPC authentication is enabled, check that the incoming request contains the
/// authentication cookie.
///
/// This enables compatibility with `zcash-cli`.
///
/// ## Security
@ -34,15 +42,47 @@ use jsonrpc_http_server::{
/// Any user-specified data in RPC requests is hex or base58check encoded.
/// We assume lightwalletd validates data encodings before sending it on to Zebra.
/// So any fixes Zebra performs won't change user-specified data.
#[derive(Copy, Clone, Debug)]
pub struct FixHttpRequestMiddleware;
#[derive(Clone, Debug, Default)]
pub struct HttpRequestMiddleware {
cookie: Option<Cookie>,
}
impl RequestMiddleware for FixHttpRequestMiddleware {
/// A trait for updating an object, consuming it and returning the updated version.
pub trait With<T> {
/// Updates `self` with an instance of type `T` and returns the updated version of `self`.
fn with(self, _: T) -> Self;
}
impl With<Cookie> for HttpRequestMiddleware {
fn with(mut self, cookie: Cookie) -> Self {
self.cookie = Some(cookie);
self
}
}
impl RequestMiddleware for HttpRequestMiddleware {
fn on_request(&self, mut request: Request<Body>) -> RequestMiddlewareAction {
tracing::trace!(?request, "original HTTP request");
// Check if the request is authenticated
if !self.check_credentials(request.headers_mut()) {
let error = jsonrpc_core::Error {
code: jsonrpc_core::ErrorCode::ServerError(401),
message: "unauthenticated method".to_string(),
data: None,
};
return jsonrpc_http_server::Response {
code: jsonrpc_http_server::hyper::StatusCode::from_u16(401)
.expect("hard-coded status code should be valid"),
content_type: header::HeaderValue::from_static("application/json; charset=utf-8"),
content: serde_json::to_string(&jsonrpc_core::Response::from(error, None))
.expect("hard-coded result should serialize"),
}
.into();
}
// Fix the request headers if needed and we can do so.
FixHttpRequestMiddleware::insert_or_replace_content_type_header(request.headers_mut());
HttpRequestMiddleware::insert_or_replace_content_type_header(request.headers_mut());
// Fix the request body
let request = request.map(|body| {
@ -80,7 +120,7 @@ impl RequestMiddleware for FixHttpRequestMiddleware {
}
}
impl FixHttpRequestMiddleware {
impl HttpRequestMiddleware {
/// Remove any "jsonrpc: 1.0" fields in `data`, and return the resulting string.
pub fn remove_json_1_fields(data: String) -> String {
// Replace "jsonrpc = 1.0":
@ -141,4 +181,18 @@ impl FixHttpRequestMiddleware {
);
}
}
/// Check if the request is authenticated.
pub fn check_credentials(&self, headers: &header::HeaderMap) -> bool {
self.cookie.as_ref().map_or(true, |internal_cookie| {
headers
.get(header::AUTHORIZATION)
.and_then(|auth_header| auth_header.to_str().ok())
.and_then(|auth_header| auth_header.split_whitespace().nth(1))
.and_then(|encoded| URL_SAFE.decode(encoded).ok())
.and_then(|decoded| String::from_utf8(decoded).ok())
.and_then(|request_cookie| request_cookie.split(':').nth(1).map(String::from))
.map_or(false, |passwd| internal_cookie.authenticate(passwd))
})
}
}

View File

@ -46,6 +46,8 @@ fn rpc_server_spawn(parallel_cpu_threads: bool) {
indexer_listen_addr: None,
parallel_cpu_threads: if parallel_cpu_threads { 2 } else { 1 },
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};
let rt = tokio::runtime::Runtime::new().unwrap();
@ -134,6 +136,8 @@ fn rpc_server_spawn_unallocated_port(parallel_cpu_threads: bool, do_shutdown: bo
indexer_listen_addr: None,
parallel_cpu_threads: if parallel_cpu_threads { 0 } else { 1 },
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};
let rt = tokio::runtime::Runtime::new().unwrap();
@ -215,6 +219,8 @@ fn rpc_server_spawn_port_conflict() {
indexer_listen_addr: None,
parallel_cpu_threads: 1,
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};
let rt = tokio::runtime::Runtime::new().unwrap();
@ -326,6 +332,8 @@ fn rpc_server_spawn_port_conflict_parallel_auto() {
indexer_listen_addr: None,
parallel_cpu_threads: 2,
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};
let rt = tokio::runtime::Runtime::new().unwrap();

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-scan"
version = "0.1.0-alpha.9"
version = "0.1.0-alpha.10"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Shielded transaction scanner for the Zcash blockchain"
license = "MIT OR Apache-2.0"
@ -61,14 +61,14 @@ results-reader = [
[dependencies]
color-eyre = "0.6.3"
indexmap = { version = "2.5.0", features = ["serde"] }
indexmap = { version = "2.6.0", features = ["serde"] }
itertools = "0.13.0"
semver = "1.0.23"
serde = { version = "1.0.210", features = ["serde_derive"] }
tokio = { version = "1.40.0", features = ["time"] }
serde = { version = "1.0.211", features = ["serde_derive"] }
tokio = { version = "1.41.0", features = ["time"] }
tower = "0.4.13"
tracing = "0.1.39"
futures = "0.3.30"
futures = "0.3.31"
# ECC dependencies.
zcash_client_backend.workspace = true
@ -77,11 +77,11 @@ zcash_primitives.workspace = true
zcash_address.workspace = true
sapling-crypto.workspace = true
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["shielded-scan"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["shielded-scan"] }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = ["shielded-scan"] }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.7" }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.40" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = ["shielded-scan"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41", features = ["shielded-scan"] }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.41", features = ["shielded-scan"] }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.8" }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.41" }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
@ -96,22 +96,22 @@ jubjub = { version = "0.10.0", optional = true }
rand = { version = "0.8.5", optional = true }
zcash_note_encryption = { version = "0.4.0", optional = true }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40", optional = true }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.41", optional = true }
# zebra-scanner binary dependencies
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
structopt = "0.3.26"
lazy_static = "1.4.0"
serde_json = "1.0.128"
serde_json = "1.0.132"
jsonrpc = { version = "0.18.0", optional = true }
hex = { version = "0.4.3", optional = true }
zebrad = { path = "../zebrad", version = "2.0.0-rc.0" }
zebrad = { path = "../zebrad", version = "2.0.0" }
[dev-dependencies]
insta = { version = "1.40.0", features = ["ron", "redactions"] }
tokio = { version = "1.40.0", features = ["test-util"] }
tokio = { version = "1.41.0", features = ["test-util"] }
proptest = "1.4.0"
proptest-derive = "0.5.0"
@ -125,6 +125,6 @@ zcash_note_encryption = "0.4.0"
toml = "0.8.19"
tonic = "0.12.3"
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.41" }

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-script"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
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.40" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41" }
thiserror = "1.0.64"
[dev-dependencies]
hex = "0.4.3"
lazy_static = "1.4.0"
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.41" }

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-state"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "State contextual verification and storage code for Zebra"
license = "MIT OR Apache-2.0"
@ -49,41 +49,41 @@ elasticsearch = [
bincode = "1.3.3"
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
dirs = "5.0.1"
futures = "0.3.30"
futures = "0.3.31"
hex = "0.4.3"
hex-literal = "0.4.1"
humantime-serde = "1.1.1"
human_bytes = { version = "0.4.3", default-features = false }
indexmap = "2.5.0"
indexmap = "2.6.0"
itertools = "0.13.0"
lazy_static = "1.4.0"
metrics = "0.23.0"
metrics = "0.24.0"
mset = "0.1.1"
regex = "1.11.0"
rlimit = "0.10.2"
rocksdb = { version = "0.22.0", default-features = false, features = ["lz4"] }
semver = "1.0.23"
serde = { version = "1.0.210", features = ["serde_derive"] }
serde = { version = "1.0.211", features = ["serde_derive"] }
tempfile = "3.13.0"
thiserror = "1.0.64"
rayon = "1.10.0"
tokio = { version = "1.40.0", features = ["rt-multi-thread", "sync", "tracing"] }
tokio = { version = "1.41.0", features = ["rt-multi-thread", "sync", "tracing"] }
tower = { version = "0.4.13", features = ["buffer", "util"] }
tracing = "0.1.39"
# elasticsearch specific dependencies.
# Security: avoid default dependency on openssl
elasticsearch = { version = "8.5.0-alpha.1", default-features = false, features = ["rustls-tls"], optional = true }
serde_json = { version = "1.0.128", package = "serde_json", optional = true }
serde_json = { version = "1.0.132", package = "serde_json", optional = true }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["async-error"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", 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.40", optional = true }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41", optional = true }
proptest = { version = "1.4.0", optional = true }
proptest-derive = { version = "0.5.0", optional = true }
@ -93,7 +93,7 @@ color-eyre = "0.6.3"
# Enable a feature that makes tinyvec compile much faster.
tinyvec = { version = "1.8.0", features = ["rustc_1_55"] }
once_cell = "1.18.0"
once_cell = "1.20.2"
spandoc = "0.2.2"
hex = { version = "0.4.3", features = ["serde"] }
@ -106,7 +106,7 @@ rand = "0.8.5"
halo2 = { package = "halo2_proofs", version = "0.3.0" }
jubjub = "0.10.0"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.40" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test/", version = "1.0.0-beta.41" }

View File

@ -537,7 +537,7 @@ impl DiskDb {
let total_sst_files_size = db
.property_int_value_cf(cf_handle, "rocksdb.total-sst-files-size")
.unwrap_or(Some(0));
let cf_disk_size = live_data_size.unwrap_or(0) + total_sst_files_size.unwrap_or(0);
let cf_disk_size = total_sst_files_size.unwrap_or(0);
total_size_on_disk += cf_disk_size;
total_live_size_on_disk += live_data_size.unwrap_or(0);
let mem_table_size = db

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-test"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Test harnesses and test vectors for Zebra"
license = "MIT OR Apache-2.0"
@ -16,18 +16,18 @@ categories = ["command-line-utilities", "cryptography::cryptocurrencies"]
[dependencies]
hex = "0.4.3"
indexmap = "2.5.0"
indexmap = "2.6.0"
lazy_static = "1.4.0"
insta = "1.40.0"
itertools = "0.13.0"
proptest = "1.4.0"
once_cell = "1.18.0"
once_cell = "1.20.2"
rand = "0.8.5"
regex = "1.11.0"
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
tower = { version = "0.4.13", features = ["util"] }
futures = "0.3.30"
futures = "0.3.31"
color-eyre = "0.6.3"
# This is a transitive dependency via color-eyre.

View File

@ -182,7 +182,7 @@ struct SkipTestReturnedErrPanicMessages;
impl PanicMessage for SkipTestReturnedErrPanicMessages {
fn display(
&self,
pi: &std::panic::PanicInfo<'_>,
pi: &std::panic::PanicHookInfo<'_>,
f: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
let payload = pi

View File

@ -1,6 +1,6 @@
[package]
name = "zebra-utils"
version = "1.0.0-beta.40"
version = "1.0.0-beta.41"
authors = ["Zcash Foundation <zebra@zfnd.org>"]
description = "Developer tools for Zebra maintenance and testing"
license = "MIT OR Apache-2.0"
@ -89,16 +89,16 @@ tinyvec = { version = "1.8.0", features = ["rustc_1_55"] }
structopt = "0.3.26"
hex = "0.4.3"
serde_json = "1.0.128"
serde_json = "1.0.132"
tracing-error = "0.2.0"
tracing-subscriber = "0.3.18"
thiserror = "1.0.64"
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.41" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41" }
# These crates are needed for the block-template-to-proposal binary
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.40", optional = true }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.41", optional = true }
# These crates are needed for the zebra-checkpoints binary
itertools = { version = "0.13.0", optional = true }
@ -109,7 +109,7 @@ regex = { version = "1.11.0", optional = true }
reqwest = { version = "0.11.26", default-features = false, features = ["rustls-tls"], optional = true }
# These crates are needed for the zebra-checkpoints and search-issue-refs binaries
tokio = { version = "1.40.0", features = ["full"], optional = true }
tokio = { version = "1.41.0", features = ["full"], optional = true }
jsonrpc = { version = "0.18.0", optional = true }
@ -122,6 +122,6 @@ rand = "0.8.5"
syn = { version = "2.0.79", features = ["full"], optional = true }
quote = { version = "1.0.37", optional = true }
serde_yml = { version = "0.0.12", optional = true }
serde = { version = "1.0.210", features = ["serde_derive"], optional = true }
indexmap = "2.5.0"
serde = { version = "1.0.211", features = ["serde_derive"], optional = true }
indexmap = "2.6.0"

View File

@ -1,7 +1,7 @@
[package]
# Crate metadata
name = "zebrad"
version = "2.0.0-rc.0"
version = "2.0.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"
@ -19,7 +19,7 @@ edition = "2021"
# Zebra is only supported on the latest stable Rust version. See the README for details.
# Any Zebra release can break compatibility with older Rust versions.
rust-version = "1.76"
rust-version = "1.81.0"
# Settings that impact runtime behaviour
@ -157,32 +157,32 @@ test_sync_past_mandatory_checkpoint_mainnet = []
test_sync_past_mandatory_checkpoint_testnet = []
[dependencies]
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.40" }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.40", features = ["rpc-client"] }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.40" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40" }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41" }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.41" }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.41" }
zebra-node-services = { path = "../zebra-node-services", version = "1.0.0-beta.41", features = ["rpc-client"] }
zebra-rpc = { path = "../zebra-rpc", version = "1.0.0-beta.41" }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41" }
# Required for crates.io publishing, but it's only used in tests
zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.40", optional = true }
zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.41", optional = true }
abscissa_core = "0.7.0"
clap = { version = "4.5.18", features = ["cargo"] }
clap = { version = "4.5.20", features = ["cargo"] }
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std"] }
humantime-serde = "1.1.1"
indexmap = "2.5.0"
indexmap = "2.6.0"
lazy_static = "1.4.0"
semver = "1.0.23"
serde = { version = "1.0.210", features = ["serde_derive"] }
serde = { version = "1.0.211", features = ["serde_derive"] }
toml = "0.8.19"
futures = "0.3.30"
futures = "0.3.31"
rayon = "1.10.0"
tokio = { version = "1.40.0", features = ["time", "rt-multi-thread", "macros", "tracing", "signal"] }
tokio = { version = "1.41.0", features = ["time", "rt-multi-thread", "macros", "tracing", "signal"] }
tokio-stream = { version = "0.1.16", features = ["time"] }
tower = { version = "0.4.13", features = ["hedge", "limit"] }
pin-project = "1.1.5"
pin-project = "1.1.6"
color-eyre = { version = "0.6.3", default-features = false, features = ["issue-url"] }
# This is a transitive dependency via color-eyre.
@ -197,7 +197,7 @@ tracing-error = "0.2.0"
tracing-futures = "0.2.5"
tracing = "0.1.39"
metrics = "0.23.0"
metrics = "0.24.0"
dirs = "5.0.1"
atty = "0.2.14"
@ -219,13 +219,13 @@ inferno = { version = "0.11.21", default-features = false, optional = true }
tracing-journald = { version = "0.3.0", optional = true }
# prod feature filter-reload
hyper = { version = "1.3.1", features = ["http1", "http2", "server"], optional = true }
hyper = { version = "1.5.0", features = ["http1", "http2", "server"], optional = true }
http-body-util = { version = "0.1.2", optional = true }
hyper-util = { version = "0.1.9", optional = true }
bytes = { version = "1.7.2", optional = true }
bytes = { version = "1.8.0", optional = true }
# prod feature prometheus
metrics-exporter-prometheus = { version = "0.15.3", default-features = false, features = ["http-listener"], optional = true }
metrics-exporter-prometheus = { version = "0.16.0", default-features = false, features = ["http-listener"], optional = true }
# prod feature release_max_level_info
#
@ -255,18 +255,18 @@ abscissa_core = { version = "0.7.0", features = ["testing"] }
hex = "0.4.3"
hex-literal = "0.4.1"
jsonrpc-core = "18.0.0"
once_cell = "1.18.0"
once_cell = "1.20.2"
regex = "1.11.0"
insta = { version = "1.40.0", features = ["json"] }
# zebra-rpc needs the preserve_order feature, it also makes test results more stable
serde_json = { version = "1.0.128", features = ["preserve_order"] }
serde_json = { version = "1.0.132", features = ["preserve_order"] }
tempfile = "3.13.0"
hyper = { version = "1.3.1", features = ["http1", "http2", "server"]}
hyper = { version = "1.5.0", features = ["http1", "http2", "server"]}
tracing-test = { version = "0.2.4", features = ["no-env-filter"] }
tokio = { version = "1.40.0", features = ["full", "tracing", "test-util"] }
tokio = { version = "1.41.0", features = ["full", "tracing", "test-util"] }
tokio-stream = "0.1.16"
# test feature lightwalletd-grpc-tests
@ -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.40", features = ["proptest-impl"] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.40", features = ["proptest-impl"] }
zebra-chain = { path = "../zebra-chain", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-consensus = { path = "../zebra-consensus", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-network = { path = "../zebra-network", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-state = { path = "../zebra-state", version = "1.0.0-beta.41", features = ["proptest-impl"] }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.40" }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.7" }
zebra-test = { path = "../zebra-test", version = "1.0.0-beta.41" }
zebra-grpc = { path = "../zebra-grpc", version = "0.1.0-alpha.8" }
# 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.7" }
# 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.40" }
zebra-utils = { path = "../zebra-utils", version = "1.0.0-beta.41" }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }

View File

@ -13,17 +13,17 @@ use zebra_chain::{
use crate::application::release_version;
/// The estimated height that this release will be published.
pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_678_363;
pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_694_000;
/// The maximum number of days after `ESTIMATED_RELEASE_HEIGHT` where a Zebra server will run
/// without halting.
///
/// Notes:
///
/// - 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 5 weeks to end support before Mainnet Nu6 activation at block [`2_726_400`](https://zips.z.cash/zip-0253).
pub const EOS_PANIC_AFTER: u32 = 35;
/// - 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;
/// 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

@ -166,6 +166,7 @@ pub fn rpc_port_config(
// Default config, users who want to detect port conflicts configure this
config.rpc.parallel_cpu_threads = 1;
}
config.rpc.enable_cookie_auth = false;
Ok(config)
}

View File

@ -0,0 +1,84 @@
# Default configuration for zebrad.
#
# This file can be used as a skeleton for custom configs.
#
# Unspecified fields use default values. Optional fields are Some(field) if the
# field is present and None if it is absent.
#
# This file is generated as an example using zebrad's current defaults.
# You should set only the config options you want to keep, and delete the rest.
# Only a subset of fields are present in the skeleton, since optional values
# whose default is None are omitted.
#
# The config format (including a complete list of sections and fields) is
# documented here:
# https://docs.rs/zebrad/latest/zebrad/config/struct.ZebradConfig.html
#
# zebrad attempts to load configs in the following order:
#
# 1. The -c flag on the command line, e.g., `zebrad -c myconfig.toml start`;
# 2. The file `zebrad.toml` in the users's preference directory (platform-dependent);
# 3. The default config.
#
# The user's preference directory and the default path to the `zebrad` config are platform dependent,
# based on `dirs::preference_dir`, see https://docs.rs/dirs/latest/dirs/fn.preference_dir.html :
#
# | Platform | Value | Example |
# | -------- | ------------------------------------- | ---------------------------------------------- |
# | Linux | `$XDG_CONFIG_HOME` or `$HOME/.config` | `/home/alice/.config/zebrad.toml` |
# | macOS | `$HOME/Library/Preferences` | `/Users/Alice/Library/Preferences/zebrad.toml` |
# | Windows | `{FOLDERID_RoamingAppData}` | `C:\Users\Alice\AppData\Local\zebrad.toml` |
[consensus]
checkpoint_sync = true
[mempool]
eviction_memory_time = "1h"
tx_cost_limit = 80000000
[metrics]
[mining]
debug_like_zcashd = true
[network]
cache_dir = true
crawl_new_peer_interval = "1m 1s"
initial_mainnet_peers = [
"dnsseed.z.cash:8233",
"dnsseed.str4d.xyz:8233",
"mainnet.seeder.zfnd.org:8233",
"mainnet.is.yolo.money:8233",
]
initial_testnet_peers = [
"dnsseed.testnet.z.cash:18233",
"testnet.seeder.zfnd.org:18233",
"testnet.is.yolo.money:18233",
]
listen_addr = "0.0.0.0:8233"
max_connections_per_ip = 1
network = "Mainnet"
peerset_initial_target_size = 25
[rpc]
cookie_dir = "cache_dir"
debug_force_finished_sync = false
enable_cookie_auth = true
parallel_cpu_threads = 0
[state]
cache_dir = "cache_dir"
delete_old_database = true
ephemeral = false
[sync]
checkpoint_verify_concurrency_limit = 1000
download_concurrency_limit = 50
full_verify_concurrency_limit = 20
parallel_cpu_threads = 0
[tracing]
buffer_limit = 128000
force_use_color = false
use_color = true
use_journald = false