Compare commits

...

2 Commits

Author SHA1 Message Date
Alfredo Garcia ef2a7fdd5d
cargo release execute output for v0.16 (#149)
* chore: Release zcash_script version 0.1.16

* fix the date
2024-04-26 09:45:10 -03:00
Alfredo Garcia 06de015788
Bump v0.1.16 (#147)
* remove zcashd depend

* Squashed 'depend/zcash/' content from commit 1408e23f0

git-subtree-dir: depend/zcash
git-subtree-split: 1408e23f00fa49ca5f86d2c7ebeb5d120603aa4c

* delete cargo, update and apply patch

* update dependencies

* fix compiling issue by updating lib.rs

* update `cc`

* update `cxx-gen`

* add changeloig entry

---------

Co-authored-by: Conrado Gouvea <conradoplg@gmail.com>
2024-04-26 11:51:51 +02:00
95 changed files with 2806 additions and 2049 deletions

View File

@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] - ReleaseDate
## [0.1.16] - 2024-04-26
### Changed
- Update `depend/zcash` to version 5.9.0 which includes updated dependencies
## [0.1.15] - 2024-04-19
### Changed
@ -101,7 +106,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated `bindgen` to a non yanked version
<!-- next-url -->
[Unreleased]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.15...HEAD
[Unreleased]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.16...HEAD
[0.1.16]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.15...v0.1.16
[0.1.15]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.14...v0.1.15
[0.1.14]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.13...v0.1.14
[0.1.13]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.12...v0.1.13

115
Cargo.lock generated
View File

@ -257,12 +257,13 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.83"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
dependencies = [
"jobserver",
"libc",
"once_cell",
]
[[package]]
@ -424,9 +425,9 @@ dependencies = [
[[package]]
name = "cxx-gen"
version = "0.7.109"
version = "0.7.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1318697052dbc5a12f8e5e603441413d6096350c29b8361eb45a9c531be61dda"
checksum = "383ecb9f96a536a1c7a2a61c5786f583da84f9240da149d78d005a4413c9a71e"
dependencies = [
"codespan-reporting",
"proc-macro2",
@ -462,6 +463,15 @@ dependencies = [
"subtle",
]
[[package]]
name = "document-features"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95"
dependencies = [
"litrs",
]
[[package]]
name = "either"
version = "1.9.0"
@ -703,9 +713,9 @@ dependencies = [
[[package]]
name = "jobserver"
version = "0.1.26"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
dependencies = [
"libc",
]
@ -794,6 +804,12 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
[[package]]
name = "litrs"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
[[package]]
name = "log"
version = "0.4.20"
@ -921,9 +937,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.18.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "opaque-debug"
@ -933,9 +949,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "orchard"
version = "0.6.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d31e68534df32024dcc89a8390ec6d7bef65edd87d91b45cfb481a2eb2d77c5"
checksum = "1fb255c3ffdccd3c84fe9ebed72aef64fdc72e6a3e4180dd411002d47abaad42"
dependencies = [
"aes",
"bitvec",
@ -958,6 +974,8 @@ dependencies = [
"subtle",
"tracing",
"zcash_note_encryption",
"zcash_spec",
"zip32",
]
[[package]]
@ -1285,6 +1303,39 @@ dependencies = [
"wait-timeout",
]
[[package]]
name = "sapling-crypto"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02f4270033afcb0c74c5c7d59c73cfd1040367f67f224fe7ed9a919ae618f1b7"
dependencies = [
"aes",
"bellman",
"bitvec",
"blake2b_simd",
"blake2s_simd",
"bls12_381",
"byteorder",
"document-features",
"ff",
"fpe",
"group",
"hex",
"incrementalmerkletree",
"jubjub",
"lazy_static",
"memuse",
"proptest",
"rand",
"rand_core",
"redjubjub",
"subtle",
"tracing",
"zcash_note_encryption",
"zcash_spec",
"zip32",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -1788,17 +1839,15 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d17e4c94ca8d69d2fcf2be97522da5732a580eb2125cda3b150761952f8df8e6"
checksum = "9070e084570bb78aed4f8d71fd6254492e62c87a5d01e084183980e98117092d"
dependencies = [
"aes",
"bip0039",
"bitvec",
"blake2b_simd",
"blake2s_simd",
"bls12_381",
"byteorder",
"document-features",
"equihash",
"ff",
"fpe",
@ -1807,31 +1856,36 @@ dependencies = [
"hex",
"incrementalmerkletree",
"jubjub",
"lazy_static",
"memuse",
"nonempty",
"orchard",
"proptest",
"rand",
"rand_core",
"redjubjub",
"ripemd",
"sapling-crypto",
"secp256k1",
"sha2",
"subtle",
"tracing",
"zcash_address",
"zcash_encoding",
"zcash_note_encryption",
"zcash_spec",
"zip32",
]
[[package]]
name = "zcash_proofs"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df0c99f65a840ff256c106b28d67d702d9759d206112473d4982c92003262406"
checksum = "b8a02eb1f151d9b9a6e16408d2c55ff440bd2fb232b7377277146d0fa2df9bc8"
dependencies = [
"bellman",
"blake2b_simd",
"bls12_381",
"document-features",
"group",
"home",
"jubjub",
@ -1839,6 +1893,7 @@ dependencies = [
"lazy_static",
"rand_core",
"redjubjub",
"sapling-crypto",
"tracing",
"xdg",
"zcash_primitives",
@ -1846,7 +1901,7 @@ dependencies = [
[[package]]
name = "zcash_script"
version = "0.1.15"
version = "0.1.16"
dependencies = [
"bellman",
"bindgen",
@ -1871,6 +1926,8 @@ dependencies = [
"rand",
"rand_core",
"rayon",
"redjubjub",
"sapling-crypto",
"subtle",
"syn 1.0.109",
"tracing",
@ -1881,6 +1938,15 @@ dependencies = [
"zcash_proofs",
]
[[package]]
name = "zcash_spec"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7a3bf58b673cb3dacd8ae09ba345998923a197ab0da70d6239d8e8838949e9b"
dependencies = [
"blake2b_simd",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
@ -1920,3 +1986,14 @@ dependencies = [
"quote",
"syn 2.0.58",
]
[[package]]
name = "zip32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4226d0aee9c9407c27064dfeec9d7b281c917de3374e1e5a2e2cfad9e09de19e"
dependencies = [
"blake2b_simd",
"memuse",
"subtle",
]

View File

@ -1,6 +1,6 @@
[package]
name = "zcash_script"
version = "0.1.15"
version = "0.1.16"
authors = ["Tamas Blummer <tamas.blummer@gmail.com>", "Zcash Foundation <zebra@zfnd.org>"]
license = "Apache-2.0"
readme = "README.md"
@ -64,16 +64,18 @@ jubjub = "0.10"
libc = "0.2"
memuse = "0.2"
metrics = "0.21"
orchard = "0.6"
orchard = "0.7"
rand_core = "0.6"
rayon = "1.5"
redjubjub = "0.7"
sapling = { package = "sapling-crypto", version = "0.1", features = ["temporary-zcashd"] }
subtle = "2.2"
tracing = "0.1"
zcash_address = "0.3"
zcash_encoding = "0.2"
zcash_note_encryption = "0.4"
zcash_primitives = { version = "=0.13.0", features = ["temporary-zcashd", "transparent-inputs"] }
zcash_proofs = { version = "=0.13.0", features = ["directories"] }
zcash_primitives = { version = "=0.14.0", features = ["temporary-zcashd", "transparent-inputs"] }
zcash_proofs = { version = "=0.14.0", features = ["directories"] }
bridgetree = "0.4"
rand = "0.8"
@ -87,7 +89,7 @@ bindgen = ">= 0.64.0"
# These dependencies are shared with a lot of other Zebra dependencies,
# so they are configured to automatically upgrade to match Zebra.
# But we try to use the latest versions here, to catch any bugs in `zcash_script`'s CI.
cc = { version = "1.0.83", features = ["parallel"] }
cc = { version = "1.0.94", features = ["parallel"] }
# Treat minor versions with a zero major version as compatible (cargo doesn't by default).
cxx-gen = ">= 0.7.107"
syn = { version = "1.0.109", features = ["full", "printing"] }
@ -100,7 +102,7 @@ syn = { version = "1.0.109", features = ["full", "printing"] }
hex = ">= 0.4.3"
lazy_static = "1.4.0"
incrementalmerkletree = { version = "0.5", features = ["test-dependencies"] }
zcash_primitives = { version = "=0.13.0", features = ["temporary-zcashd", "transparent-inputs", "test-dependencies"] }
zcash_primitives = { version = "=0.14.0", features = ["temporary-zcashd", "transparent-inputs", "test-dependencies"] }
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"

View File

@ -0,0 +1,61 @@
name: 'gcs-download-cloud-storage'
description: 'Download files from a GCS bucket'
inputs:
path-prefix:
description: 'The bucket path inside which the source path is located'
required: true
source:
description: 'The path to the files to download'
required: true
destination:
description: 'The directory into which the files will be downloaded'
required: true
remove-first-if-exists:
description: 'Deletes the given path first (if it exists) before downloading files'
runs:
using: 'composite'
steps:
- name: Set up Cloud SDK
if: runner.os != 'Linux'
uses: 'google-github-actions/setup-gcloud@v2'
with:
version: '>= 390.0.0' # To use gsutil with google-github-actions/auth
# Use $RUNNER_TEMP instead of ${{ runner.temp }} to prevent the Bash used by Windows
# runners from treating backslashes in Windows paths as escape characters.
# https://github.com/orgs/community/discussions/25910
- name: Create temporary directory
shell: bash
run: |
rm -rf $RUNNER_TEMP/gcs-download
mkdir $RUNNER_TEMP/gcs-download
- name: Download source
shell: bash
run: >
gcloud storage
cp -r
gs://gh-zcash/${{ inputs.path-prefix }}/${{ inputs.source }}
$RUNNER_TEMP/gcs-download
- name: Remove the specified path if it exists
if: inputs.remove-first-if-exists != ''
shell: bash
run: rm -rf ${{ inputs.remove-first-if-exists }}
- name: Ensure the target directory exists
shell: bash
run: mkdir -p ${{ inputs.destination }}
- name: Move source to target [Unix]
if: runner.os != 'Windows'
shell: bash
run: mv $RUNNER_TEMP/gcs-download/* ${{ inputs.destination }}
# PowerShell's mv aliases to its Move-Item cmdlet which has glob support (unlike mv in
# Git Bash for whatever reason).
- name: Move source to target [Windows]
if: runner.os == 'Windows'
shell: pwsh
run: mv ${{ runner.temp }}/gcs-download/* ${{ inputs.destination }}

View File

@ -17,7 +17,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
id: toolchain
- run: rustup override set ${{steps.toolchain.outputs.name}}
- run: cargo install cargo-vet --version ~0.8
- run: cargo install cargo-vet --version ~0.9
- run: cargo vet --locked
cargo-deny:

View File

@ -2,28 +2,58 @@ name: CI
on:
pull_request:
pull_request_target:
types: [labeled]
paths-ignore:
- '.github/**'
push:
branches: master
jobs:
matrices:
setup:
name: Define CI matrix
runs-on: ubuntu-latest
strategy:
matrix:
cfg:
- data:
- name: Debian-bookworm
tier: 1
platform: Debian Bookworm
build_os: ubuntu-20.04-8cores
test_os: ubuntu-20.04
container: electriccoinco/debian-helper:bookworm
host: x86_64-pc-linux-gnu
- name: Debian-bullseye
tier: 1
platform: Debian bullseye
build_os: ubuntu-20.04-8cores
test_os: ubuntu-20.04
container: electriccoinco/debian-helper:bullseye
host: x86_64-pc-linux-gnu
- name: Debian-buster
tier: 1
platform: Debian buster
build_os: ubuntu-20.04-8cores
test_os: ubuntu-20.04
container: electriccoinco/debian-helper:buster
host: x86_64-pc-linux-gnu
- name: ubuntu-20.04
tier: 1
platform: Ubuntu 20.04
build_os: ubuntu-20.04-8cores
test_os: ubuntu-20.04
host: x86_64-pc-linux-gnu
- name: ubuntu-22.04
tier: 3
platform: Ubuntu 22.04
build_os: ubuntu-22.04-8cores
test_os: ubuntu-22.04
host: x86_64-pc-linux-gnu
- name: macos-11
tier: 3
@ -36,6 +66,7 @@ jobs:
coreutils
libtool
pkgconfig
host: x86_64-apple-darwin
- name: mingw32
tier: 3
@ -44,7 +75,7 @@ jobs:
test_os: windows-latest
cross_deps: >
mingw-w64
host: HOST=x86_64-w64-mingw32
host: x86_64-w64-mingw32
file_ext: ".exe"
- name: aarch64-linux
@ -53,29 +84,61 @@ jobs:
build_os: ubuntu-22.04-8cores
cross_deps: >
g++-aarch64-linux-gnu
host: HOST=aarch64-linux-gnu
host: aarch64-linux-gnu
outputs:
build_matrix: ${{ steps.set-matrices.outputs.build_matrix }}
build_names: ${{ steps.set-matrices.outputs.build_names }}
test_matrix: ${{ steps.set-matrices.outputs.test_matrix }}
test_names: ${{ steps.set-matrices.outputs.test_names }}
unix_test_matrix: ${{ steps.set-matrices.outputs.unix_test_matrix }}
unix_test_names: ${{ steps.set-matrices.outputs.unix_test_names }}
steps:
# Configure the build and test matrices. Notes:
# - The `*_names` lists of platforms are combined with job-specific lists to build
# strategy matrices. The `*_matrix` lists then augment the matrix with parameters
# for each platform.
# - We can only run tests on the subset of platforms that have a compatible runner
# (i.e. excluding cross-compiled platforms).
# - Some tests don't currently work on Windows platforms, so we have a Unix subset.
- id: set-matrices
env:
CFG: ${{ toJSON(matrix.cfg) }}
run: |
jq -r -n 'env.CFG | fromjson | @json "build_matrix=\(.data)"' >> $GITHUB_OUTPUT
jq -r -n 'env.CFG | fromjson | [.data[] | .name] | @json "build_names=\(.)"' >> $GITHUB_OUTPUT
jq -r -n 'env.CFG | fromjson | [.data[] | select(.test_os)] | @json "test_matrix=\(.)"' >> $GITHUB_OUTPUT
jq -r -n 'env.CFG | fromjson | [.data[] | select(.test_os) | .name] | @json "test_names=\(.)"' >> $GITHUB_OUTPUT
jq -r -n 'env.CFG | fromjson | [.data[] | select(.test_os and .test_os != "windows-latest")] | @json "unix_test_matrix=\(.)"' >> $GITHUB_OUTPUT
jq -r -n 'env.CFG | fromjson | [.data[] | select(.test_os and .test_os != "windows-latest") | .name] | @json "unix_test_names=\(.)"' >> $GITHUB_OUTPUT
- name: Download Sprout parameters
run: |
mkdir zcash-params
wget -c https://download.z.cash/downloads/sprout-groth16.params -O zcash-params/sprout-groth16.params
- name: Cache Sprout parameters
uses: actions/cache@v3
with:
path: zcash-params
key: zcash-params
restore-keys: |
zcash-params
build:
name: Build tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: matrices
needs: setup
runs-on: ${{ matrix.build_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier == 3 }}
strategy:
matrix:
include: ${{ fromJson(needs.matrices.outputs.build_matrix) }}
include: ${{ fromJson(needs.setup.outputs.build_matrix) }}
steps:
- uses: actions/checkout@v4
@ -122,41 +185,113 @@ jobs:
- name: Build zcashd
id: build
env:
HOST: ${{ matrix.host }}
run: >
${{ matrix.host }}
./zcutil/build.sh
-j"${{ steps.nproc.outputs.count }}"
- name: Upload zcashd artifact
uses: actions/upload-artifact@v3
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
name: zcashd-${{ matrix.name }}
path: |
${{ format('src/zcash-cli{0}', matrix.file_ext) }}
${{ format('src/zcashd{0}', matrix.file_ext) }}
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Upload zcashd artifact
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ${{ format('./src/zcashd{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload zcash-cli artifact
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ${{ format('./src/zcash-cli{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload zcashd-wallet-tool artifact
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ${{ format('./src/zcashd-wallet-tool{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload zcash-inspect artifact
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ${{ format('./src/zcash-inspect{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload zcash-tx artifact
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ${{ format('./src/zcash-tx{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload zcash-btest artifact
if: matrix.test_os != ''
uses: actions/upload-artifact@v3
uses: google-github-actions/upload-cloud-storage@v2
with:
name: zcash-btest-${{ matrix.name }}
path: ${{ format('src/test/test_bitcoin{0}', matrix.file_ext) }}
path: ${{ format('./src/test/test_bitcoin{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src/test
- name: Upload zcash-gtest artifact
if: matrix.test_os != ''
uses: actions/upload-artifact@v3
uses: google-github-actions/upload-cloud-storage@v2
with:
name: zcash-gtest-${{ matrix.name }}
path: ${{ format('src/zcash-gtest{0}', matrix.file_ext) }}
path: ${{ format('./src/zcash-gtest{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload src/test/buildenv.py
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ./src/test/buildenv.py
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src/test
- name: Upload src/secp256k1
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ./src/secp256k1
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload src/univalue
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ./src/univalue
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src
- name: Upload depends/${{ matrix.host }}/native/bin
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ./depends/${{ matrix.host }}/native/bin
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/depends/${{ matrix.host }}/native
- name: Upload depends/${{ matrix.host }}/lib
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ./depends/${{ matrix.host }}/lib
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/depends/${{ matrix.host }}
- name: Upload bench_bitcoin artifact
uses: google-github-actions/upload-cloud-storage@v2
with:
path: ${{ format('./src/bench/bench_bitcoin{0}', matrix.file_ext) }}
destination: gh-zcash/${{ github.run_id }}/${{ matrix.name }}/src/bench
bitrot:
name: Bitrot check tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [matrices, build]
name: Bitrot check tier ${{ matrix.tier }} platform ${{ matrix.platform }} flag '${{ matrix.configure_flag }}'
needs: [setup, build]
runs-on: ${{ matrix.build_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier == 3 }}
strategy:
matrix:
include: ${{ fromJson(needs.matrices.outputs.build_matrix) }}
name: ${{ fromJson(needs.setup.outputs.build_names) }}
configure_flag:
- '--with-libs'
- '--disable-wallet'
- '--disable-mining'
include: ${{ fromJson(needs.setup.outputs.build_matrix) }}
steps:
- uses: actions/checkout@v4
@ -201,84 +336,397 @@ jobs:
shell: bash
run: echo "count=$(nproc 2> /dev/null || sysctl -n hw.logicalcpu)" >> "$GITHUB_OUTPUT"
- name: Build zcashd with libraries enabled
- name: Build zcashd with the flag being checked
env:
CONFIGURE_FLAGS: "${{ matrix.configure_flag }}"
HOST: ${{ matrix.host }}
run: >
CONFIGURE_FLAGS="--with-libs"
${{ matrix.host }}
./zcutil/build.sh
-j"${{ steps.nproc.outputs.count }}"
- name: Build zcashd with wallet disabled
run: >
CONFIGURE_FLAGS="--disable-wallet"
${{ matrix.host }}
./zcutil/build.sh
-j"${{ steps.nproc.outputs.count }}"
- name: Build zcashd with mining disabled
run: >
CONFIGURE_FLAGS="--disable-mining"
${{ matrix.host }}
./zcutil/build.sh
-j"${{ steps.nproc.outputs.count }}"
test-btest:
name: Boost.Test tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [matrices, build]
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.matrices.outputs.test_matrix) }}
include: ${{ fromJson(needs.setup.outputs.test_matrix) }}
steps:
- name: Download zcash-btest artifact
uses: actions/download-artifact@v3
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
name: zcash-btest-${{ matrix.name }}
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download zcash-btest artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/test/test_bitcoin{0}', matrix.file_ext) }}
destination: ./
- name: Make artifact executable
if: runner.os != 'Windows'
run: chmod +x ${{ format('./test_bitcoin{0}', matrix.file_ext) }}
- name: Run Boost.Tests
run: ${{ format('./test_bitcoin{0}', matrix.file_ext) }} -p
test-gtest:
name: GoogleTest tier ${{ matrix.tier }} platform ${{ matrix.platform }} - shard ${{ matrix.gtest_shards }}
needs: [matrices, build]
name: GoogleTest tier ${{ matrix.tier }} platform ${{ matrix.platform }} - shard ${{ matrix.shard_index }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
name: ${{ fromJson(needs.matrices.outputs.test_names) }}
name: ${{ fromJson(needs.setup.outputs.test_names) }}
shard_index: [0, 1]
include: ${{ fromJson(needs.matrices.outputs.test_matrix) }}
include: ${{ fromJson(needs.setup.outputs.test_matrix) }}
steps:
- name: Download zcash-gtest artifact
uses: actions/download-artifact@v3
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
name: zcash-gtest-${{ matrix.name }}
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download zcash-gtest artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcash-gtest{0}', matrix.file_ext) }}
destination: ./
- name: Make artifact executable
if: runner.os != 'Windows'
run: chmod +x ${{ format('./zcash-gtest{0}', matrix.file_ext) }}
- name: Get environment variables
id: env
- name: Cache Sprout parameters
uses: actions/cache@v3
with:
path: zcash-params
key: zcash-params
restore-keys: |
zcash-params
- name: Download Sprout parameters
# In case the cache of Sprout parameters step fails
shell: bash
run: |
echo "appdata=$APPDATA" >> "$GITHUB_OUTPUT"
echo "home=$HOME" >> "$GITHUB_OUTPUT"
- name: Download Sprout parameters
uses: carlosperate/download-file-action@v2.0.1
with:
file-url: "https://download.z.cash/downloads/sprout-groth16.params"
location: >
${{
runner.os == 'Windows' && steps.env.outputs.appdata || steps.env.outputs.home
}}${{
runner.os == 'macOS' && '/Library/Application Support/' || '/'
}}${{
runner.os == 'Linux' && '.zcash-params' || 'ZcashParams'
}}
mkdir zcash-params || echo ""
curl -L -C - https://download.z.cash/downloads/sprout-groth16.params -o zcash-params/sprout-groth16.params
- name: Setup zcash-params
shell: bash
run: |
if [ "${{ runner.os }}" == "Windows" ]; then
mv zcash-params "$APPDATA/ZcashParams"
elif [ "${{ runner.os }}" == "macOS" ]; then
mv zcash-params "$HOME/Library/Application Support/ZcashParams"
elif [ "${{ runner.os }}" == "Linux" ]; then
mv zcash-params "$HOME/.zcash-params"
fi
- name: Run GoogleTests
env:
GTEST_TOTAL_SHARDS: 2
GTEST_SHARD_INDEX: ${{ matrix.shard_index }}
run: ${{ format('./zcash-gtest{0}', matrix.file_ext) }}
test-rust:
name: Rust test tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.setup.outputs.test_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Run Rust tests
run: cargo test
# Not designed for Windows
test-secp256k1:
name: secp256k1 tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.setup.outputs.unix_test_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download native/bin artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: depends/${{ matrix.host }}/native/bin
destination: ./depends/${{ matrix.host }}/native/
- name: Download src/secp256k1 artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: src/secp256k1
destination: ./src/
remove-first-if-exists: ./src/secp256k1
- name: Run secp256k1 test
shell: bash
run: python3 ./qa/zcash/full_test_suite.py secp256k1
env:
HOST: ${{ matrix.host }}
# Not designed for Windows
test-univalue:
name: univalue tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.setup.outputs.unix_test_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download native/bin artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: depends/${{ matrix.host }}/native/bin
destination: ./depends/${{ matrix.host }}/native/
- name: Download src/univalue artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: src/univalue
destination: ./src/
remove-first-if-exists: ./src/univalue
- name: Make artifact executable
if: runner.os != 'Windows'
run: chmod +x ./src/univalue/build-aux/install-sh
- name: Run univalue test
shell: bash
run: python3 ./qa/zcash/full_test_suite.py univalue
env:
HOST: ${{ matrix.host }}
# Not designed for Windows
test-util:
name: util-test tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.setup.outputs.unix_test_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download zcash-tx artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcash-tx{0}', matrix.file_ext) }}
destination: ./src/
- name: Download src/test/buildenv.py artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: src/test/buildenv.py
destination: ./src/test/
- name: Make artifact executable
if: runner.os != 'Windows'
run: chmod +x ${{ format('./src/zcash-tx{0}', matrix.file_ext) }}
- name: Run util-test test
shell: bash
run: python3 ./qa/zcash/full_test_suite.py util-test
env:
HOST: ${{ matrix.host }}
no-dot-so:
name: not-dot-so tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.setup.outputs.test_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download depends/${{ matrix.host }}/lib artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: depends/${{ matrix.host }}/lib
destination: ./depends/${{ matrix.host }}/
- name: Run no-dot-so test
run: python3 ./qa/zcash/full_test_suite.py no-dot-so
env:
HOST: ${{ matrix.host }}
# Not working in Windows
sec-hard:
name: sec-hard tier ${{ matrix.tier }} platform ${{ matrix.platform }}
needs: [setup, build]
runs-on: ${{ matrix.test_os }}
container:
image: ${{ matrix.container }}
env:
HOME: /root
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
continue-on-error: ${{ matrix.tier != 1 }}
strategy:
matrix:
include: ${{ fromJson(needs.setup.outputs.unix_test_matrix) }}
steps:
- uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Download ${{ format('src/zcash-inspect{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcash-inspect{0}', matrix.file_ext) }}
destination: ./src/
- name: Download ${{ format('src/bench/bench_bitcoin{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/bench/bench_bitcoin{0}', matrix.file_ext) }}
destination: ./src/bench/
- name: Download ${{ format('src/test/test_bitcoin{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/test/test_bitcoin{0}', matrix.file_ext) }}
destination: ./src/test/
- name: Download ${{ format('src/zcashd-wallet-tool{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcashd-wallet-tool{0}', matrix.file_ext) }}
destination: ./src/
- name: Download ${{ format('src/zcash-tx{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcash-tx{0}', matrix.file_ext) }}
destination: ./src/
- name: Download ${{ format('src/zcash-gtest{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcash-gtest{0}', matrix.file_ext) }}
destination: ./src/
- name: Download ${{ format('src/zcashd{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcashd{0}', matrix.file_ext) }}
destination: ./src/
- name: Download ${{ format('src/zcash-cli{0}', matrix.file_ext) }} artifact
uses: ./.github/actions/gcs-download-cloud-storage
with:
path-prefix: ${{ github.run_id }}/${{ matrix.name }}
source: ${{ format('src/zcash-cli{0}', matrix.file_ext) }}
destination: ./src/
- name: Make artifact executable
if: runner.os != 'Windows'
run: |
chmod +x ${{ format('./src/test/test_bitcoin{0}', matrix.file_ext) }}
chmod +x ${{ format('./src/bench/bench_bitcoin{0}', matrix.file_ext) }}
chmod +x ${{ format('./src/zcashd{0}', matrix.file_ext) }}
chmod +x ${{ format('./src/zcash-cli{0}', matrix.file_ext) }}
chmod +x ${{ format('./src/zcash-gtest{0}', matrix.file_ext) }}
chmod +x ${{ format('./src/zcashd-wallet-tool{0}', matrix.file_ext) }}
chmod +x ${{ format('./src/zcash-tx{0}', matrix.file_ext) }}
- name: Run sec-hard test
shell: bash
run: python3 ./qa/zcash/full_test_suite.py sec-hard
env:
HOST: ${{ matrix.host }}

View File

@ -0,0 +1,31 @@
name: Build and Push Docker Image to Docker Hub
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
jobs:
set_env:
name: Create version tag
runs-on: ubuntu-latest
outputs:
tags: ${{ steps.version_step.outputs.tags }}
steps:
- id: version_step
run: |
echo "tags=latest,${{ github.ref_name }},${{ github.sha }}" >> $GITHUB_OUTPUT
build_push:
uses: zcash/.github/.github/workflows/build-and-push-docker-hub.yaml@main
needs: set_env
with:
image_name: zcashd
image_tags: ${{ needs.set_env.outputs.tags }}
dockerfile: ./contrib/docker/Dockerfile
context: ./contrib/docker/
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_password: ${{ secrets.DOCKERHUB_PASSWORD }}
dockerhub_registry: ${{ secrets.DOCKERHUB_REGISTRY }}

View File

@ -30,18 +30,9 @@ dependencies. For further details see 'contrib/debian/copyright'.
Although almost all of the Zcash code is licensed under "permissive" open source
licenses, there are two dependencies that use "copyleft" open source licenses:
- Users and distributors should note that when built using the default build
options, zcashd depends on Oracle Berkeley DB 6.2.x, which is licensed under
the GNU Affero General Public License.
- Downstream code forks should note that zcashd depends on the 'orchard' crate,
which is licensed under the Bootstrap Open Source License.
A license exception is provided allowing some derived works that are linked or
combined with the 'orchard' crate to be copied or distributed under the original
licenses (in this case documented in 'contrib/debian/copyright'), provided that
the included portions of the 'orchard' code remain subject to BOSL.
See https://github.com/zcash/orchard/blob/main/COPYING for details of which
projects can make use of this exception.
licenses, users and distributors should note that when built using the default
build options, Zcash depends on Oracle Berkeley DB 6.2.x, which is licensed under
the GNU Affero General Public License.
Contributors should understand licensing implications before modifying the

660
depend/zcash/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,18 @@
Zcash 5.8.0
Zcash 5.9.0
<img align="right" width="120" height="80" src="doc/imgs/logo.png">
===========
What is Zcash?
--------------
[Zcash](https://z.cash/) is an implementation of the "Zerocash" protocol.
Initially based on Bitcoin's design, Zcash intends to offer a far
higher standard of privacy through a sophisticated zero-knowledge
proving scheme that preserves confidentiality of transaction
metadata. More technical details are available in our [Protocol
Specification](https://zips.z.cash/protocol/protocol.pdf).
[Zcash](https://z.cash/) is HTTPS for money.
Initially based on Bitcoin's design, Zcash has been developed from
the Zerocash protocol to offer a far higher standard of privacy and
anonymity. It uses a sophisticated zero-knowledge proving scheme to
preserve confidentiality and hide the connections between shielded
transactions. More technical details are available in our
[Protocol Specification](https://zips.z.cash/protocol/protocol.pdf).
## The `zcashd` Full Node

View File

@ -1,7 +1,7 @@
dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 5)
define(_CLIENT_VERSION_MINOR, 8)
define(_CLIENT_VERSION_MINOR, 9)
define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 50)
define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50)))

View File

@ -1,3 +1,15 @@
zcash (5.9.0) stable; urgency=medium
* 5.9.0 release.
-- Electric Coin Company <team@electriccoin.co> Fri, 19 Apr 2024 18:30:48 +0000
zcash (5.9.0~rc1) stable; urgency=medium
* 5.9.0-rc1 release.
-- Electric Coin Company <team@electriccoin.co> Wed, 17 Apr 2024 22:49:17 +0000
zcash (5.8.0) stable; urgency=medium
* 5.8.0 release.

View File

@ -13,10 +13,11 @@ Vcs-Browser: https://github.com/zcash/zcash
Package: zcash
Architecture: amd64
Depends: ${shlibs:Depends}
Description: Zcash libraries and tools
Based on Bitcoin's code, it intends to offer a far higher standard
of privacy and anonymity through a sophisticiated zero-knowledge
proving scheme which preserves confidentiality of transaction metadata.
Think of it as HTTPS for money.
This package provides the daemon, zcashd, and the CLI tool,
zcash-cli, to interact with the daemon.
Description: Zcash is HTTPS for money
Initially based on Bitcoin's design, Zcash has been developed from
the Zerocash protocol to offer a far higher standard of privacy and
anonymity. It uses a sophisticated zero-knowledge proving scheme to
preserve confidentiality and hide the connections between shielded
transactions.
This package provides the daemon, zcashd, and a CLI tool, zcash-cli,
to interact with the daemon.

View File

@ -171,10 +171,6 @@ License: CC0-1.0
Comment: Other contributors are Simon Truscott (@bobbleclank), Kévin Alexandre Boissonneault (@KABoissonneault),
and Björn Fahller (@rollbear).
Files: depends/*/vendored-sources/orchard/*
Copyright: 2020-2022 The Electric Coin Company
License: BOSL-1+ with Zcash exception
Files: depends/*/vendored-sources/sketches-ddsketch/*
Copyright: 2019-2020 Mike Heffner <mikeh@fesnel.com>
License: Apache-2.0
@ -2035,224 +2031,6 @@ License: Ring-BoringSSL
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
License: BOSL-1+ with Zcash exception
This package ("Original Work") is licensed under the terms of the Bootstrap Open
Source License, version 1.0, or at your option, any later version ("BOSL"). See
the file ./LICENSE-BOSL for the terms of the Bootstrap Open Source Licence,
version 1.0.
.
Only if this Original Work is included as part of the distribution of one of the
following (each, the "Project"):
.
- The Zcash projects published by the Electric Coin Company;
- The Zebra project published by the Zcash Foundation;
- A project that is designed to integrate with Zcash and provides additional
functionality or utility to the Zcash network and holders of the ZEC coin; or
- A blockchain that descends from the Zcash blockchain and that is forked
within 100 blocks of the current block height of the Zcash blockchain at the
time of the code fork;
.
then License is granted to use the Original Work under the BOSL as modified by
the following clarification and special exception. This exception applies only
to the Original Work when linked or combined with the Project and not to the
Original Work when linked, combined, or included in or with any other software
or project or on a standalone basis.
.
Under the terms of the BOSL, linking or combining this Original Work with
the Project creates a Derivative Work based upon the Original Work and the
terms of the BOSL thus apply to both the Original Work and that Derivative
Work. As a special exception to the BOSL, and to allow this Original Work to
be linked and combined with the Project without having to apply the BOSL to
the other portions of the Project, you are granted permission to link or
combine this Original Work with the Project and to copy and distribute the
resulting work ("Resulting Work") under the open source license applicable
to the Project ("Project License"), provided that any portions of this
Original Work included in the Resulting Work remain subject to the BOSL. For
clarity, you may continue to treat all other portions of the Project under
the Project License, provided that you comply with the BOSL with respect to
the Original Work. If you modify this Original Work, your version of the
Original Work must remain under the BOSL. You may also extend this exception
to your version, but you are not obligated to do so. If you do not wish to
do so, delete this exception statement from your version.
License: BOSL-1
=======================================================
Bootstrap Open Source Licence ("BOSL") v. 1.0
=======================================================
This Bootstrap Open Source Licence (the "License") applies to any original work
of authorship (the "Original Work") whose owner (the "Licensor") has placed the
following licensing notice adjacent to the copyright notice for the Original
Work:
.
*Licensed under the Bootstrap Open Source Licence version 1.0*
.
1. **Grant of Copyright License.** Licensor grants You a worldwide,
royalty-free, non-exclusive, sublicensable license, for the duration of the
copyright in the Original Work, to do the following:
.
a. to reproduce the Original Work in copies, either alone or as part of
a collective work;
.
b. to translate, adapt, alter, transform, modify, or arrange the
Original Work, thereby creating derivative works ("Derivative Works")
based upon the Original Work;
.
c. to distribute or communicate copies of the Original Work and
Derivative Works to the public, provided that prior to any such
distribution or communication You first place a machine-readable copy
of the Source Code of the Original Work and such Derivative Works that
You intend to distribute or communicate in an information repository
reasonably calculated to permit inexpensive and convenient access
thereto by the public (“Information Repository”) for as long as You
continue to distribute or communicate said copies, accompanied by an
irrevocable offer to license said copies to the public free of charge
under this License, said offer valid starting no later than 12 months
after You first distribute or communicate said copies;
.
d. to perform the Original Work publicly; and
.
e. to display the Original Work publicly.
.
2. **Grant of Patent License.** Licensor grants You a worldwide, royalty-free,
non-exclusive, sublicensable license, under patent claims owned or controlled
by the Licensor that are embodied in the Original Work as furnished by the
Licensor, for the duration of the patents, to make, use, sell, offer for sale,
have made, and import the Original Work and Derivative Works.
.
3. **Grant of Source Code License.** The "Source Code" for a work means the
preferred form of the work for making modifications to it and all available
documentation describing how to modify the work. Licensor agrees to provide a
machine-readable copy of the Source Code of the Original Work along with each
copy of the Original Work that Licensor distributes. Licensor reserves the
right to satisfy this obligation by placing a machine-readable copy of said
Source Code in an Information Repository for as long as Licensor continues to
distribute the Original Work.
.
4. **Exclusions From License Grant.** Neither the names of Licensor, nor the
names of any contributors to the Original Work, nor any of their trademarks or
service marks, may be used to endorse or promote products derived from this
Original Work without express prior permission of the Licensor. Except as
expressly stated herein, nothing in this License grants any license to
Licensor's trademarks, copyrights, patents, trade secrets or any other
intellectual property. No patent license is granted to make, use, sell, offer
for sale, have made, or import embodiments of any patent claims other than the
licensed claims defined in Section 2. No license is granted to the trademarks
of Licensor even if such marks are included in the Original Work. Nothing in
this License shall be interpreted to prohibit Licensor from licensing under
terms different from this License any Original Work that Licensor otherwise
would have a right to license.
.
5. **External Deployment.** The term "External Deployment" means the use,
distribution, or communication of the Original Work or Derivative Works in any
way such that the Original Work or Derivative Works may be used by anyone other
than You, whether those works are distributed or communicated to those persons
or made available as an application intended for use over a network. As an
express condition for the grants of license hereunder, You must treat any
External Deployment by You of the Original Work or a Derivative Work as a
distribution under section 1(c).
.
6. **Attribution Rights.** You must retain, in the Source Code of any
Derivative Works that You create, all copyright, patent, or trademark notices
from the Source Code of the Original Work, as well as any notices of licensing
and any descriptive text identified therein as an "Attribution Notice." You
must cause the Source Code for any Derivative Works that You create to carry a
prominent Attribution Notice reasonably calculated to inform recipients that
You have modified the Original Work.
.
7. **Warranty of Provenance and Disclaimer of Warranty.** Licensor warrants
that the copyright in and to the Original Work and the patent rights granted
herein by Licensor are owned by the Licensor or are sublicensed to You under
the terms of this License with the permission of the contributor(s) of those
copyrights and patent rights. Except as expressly stated in the immediately
preceding sentence, the Original Work is provided under this License on an "AS
IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without
limitation, the warranties of non-infringement, merchantability or fitness for
a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS
WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this
License. No license to the Original Work is granted by this License except
under this disclaimer.
.
8. **Limitation of Liability.** Under no circumstances and under no legal
theory, whether in tort (including negligence), contract, or otherwise, shall
the Licensor be liable to anyone for any indirect, special, incidental, or
consequential damages of any character arising as a result of this License or
the use of the Original Work including, without limitation, damages for loss of
goodwill, work stoppage, computer failure or malfunction, or any and all other
commercial damages or losses. This limitation of liability shall not apply to
the extent applicable law prohibits such limitation.
.
9. **Acceptance and Termination.** If, at any time, You expressly assented to
this License, that assent indicates your clear and irrevocable acceptance of
this License and all of its terms and conditions. If You distribute or
communicate copies of the Original Work or a Derivative Work, You must make a
reasonable effort under the circumstances to obtain the express assent of
recipients to the terms of this License. This License conditions your rights to
undertake the activities listed in Section 1, including your right to create
Derivative Works based upon the Original Work, and doing so without honoring
these terms and conditions is prohibited by copyright law and international
treaty. Nothing in this License is intended to affect copyright exceptions and
limitations (including 'fair use' or 'fair dealing'). This License shall
terminate immediately and You may no longer exercise any of the rights granted
to You by this License upon your failure to honor the conditions in Section
1(c).
.
10. **Termination for Patent Action.** This License shall terminate
automatically and You may no longer exercise any of the rights granted to You
by this License as of the date You commence an action, including a cross-claim
or counterclaim, against Licensor or any licensee alleging that the Original
Work infringes a patent. This termination provision shall not apply for an
action alleging patent infringement by combinations of the Original Work with
other software or hardware.
.
11. **Jurisdiction, Venue and Governing Law.** Any action or suit relating to
this License may be brought only in the courts of a jurisdiction wherein the
Licensor resides or in which Licensor conducts its primary business, and under
the laws of that jurisdiction excluding its conflict-of-law provisions. The
application of the United Nations Convention on Contracts for the International
Sale of Goods is expressly excluded. Any use of the Original Work outside the
scope of this License or after its termination shall be subject to the
requirements and penalties of copyright or patent law in the appropriate
jurisdiction. This section shall survive the termination of this License.
.
12. **Attorneys' Fees.** In any action to enforce the terms of this License or
seeking damages relating thereto, the prevailing party shall be entitled to
recover its costs and expenses, including, without limitation, reasonable
attorneys' fees and costs incurred in connection with such action, including
any appeal of such action. This section shall survive the termination of this
License.
.
13. **Miscellaneous.** If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent necessary to
make it enforceable.
.
14. **Definition of "You" in This License.** "You" throughout this License,
whether in upper or lower case, means an individual or a legal entity
exercising rights under, and complying with all of the terms of, this License.
For legal entities, "You" includes any entity that controls, is controlled by,
or is under common control with you. For purposes of this definition, "control"
means (i) the power, direct or indirect, to cause the direction or management
of such entity, whether by contract or otherwise, or (ii) ownership of fifty
percent (50%) or more of the outstanding shares, or (iii) beneficial ownership
of such entity.
.
15. **Right to Use.** You may use the Original Work in all ways not otherwise
restricted or conditioned by this License or by law, and Licensor promises not
to interfere with or be responsible for such uses by You.
.
16. **Modification of This License.** This License is Copyright © 2021-2022 Electric Coin Company.
Permission is granted to copy, distribute, or communicate this
License without modification. Nothing in this License permits You to modify
this License as applied to the Original Work or to Derivative Works. However,
You may modify the text of this License and copy, distribute or communicate
your modified version (the "Modified License") and apply it to other original
works of authorship subject to the following conditions: (i) You may not
indicate in any way that your Modified License is the "Bootstrap Open Source
Licence" or "BOSL" and you may not use those names in the name of your Modified
License; and (ii) You must replace the notice specified in the first paragraph
above with the notice "Licensed under <insert your license name here>" or with
a notice of your own that is not confusingly similar to the notice in this
License.
License: Unicode-DFS-2016
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
.

View File

@ -1,10 +1,11 @@
---
name: "zcash-5.8.0"
name: "zcash-5.9.0"
enable_cache: true
distro: "debian"
suites:
- "buster"
- "bookworm"
- "bullseye"
- "buster"
architectures:
- "amd64"
packages:
@ -24,7 +25,8 @@ packages:
- "m4"
- "ncurses-dev"
- "pkg-config"
- "python"
- "python3"
- "python-is-python3"
- "unzip"
- "wget"
- "zlib1g-dev"

View File

@ -1,10 +1,11 @@
---
name: "zcash-5.8.0"
name: "zcash-5.9.0"
enable_cache: true
distro: "debian"
suites:
- "buster"
- "bookworm"
- "bullseye"
- "buster"
architectures:
- "amd64"
packages:
@ -24,7 +25,8 @@ packages:
- "m4"
- "ncurses-dev"
- "pkg-config"
- "python"
- "python3"
- "python-is-python3"
- "unzip"
- "wget"
- "zlib1g-dev"

View File

@ -1,5 +1,6 @@
# Configuration file for cargo-deny
[graph]
targets = [
{ triple = "aarch64-unknown-linux-gnu" },
{ triple = "x86_64-apple-darwin" },
@ -9,12 +10,11 @@ targets = [
]
[licenses]
unlicensed = "deny"
version = 2
allow = [
"Apache-2.0",
"MIT",
]
copyleft = "deny"
# Each entry in this list should have a corresponding `contrib/debian/copyright`
# entry for `Files: depends/*/vendored-sources/CRATE_NAME/*` (or the relevant
# subset of files). The reverse might not be true however: `cargo-deny` only
@ -25,7 +25,6 @@ copyleft = "deny"
exceptions = [
{ name = "arrayref", allow = ["BSD-2-Clause"] },
{ name = "curve25519-dalek", allow = ["BSD-3-Clause"] },
{ name = "orchard", allow = ["LicenseRef-BOSL-1.0-or-later-with-Zcash-exception"] },
{ name = "ring", allow = ["LicenseRef-ring"] },
{ name = "secp256k1", allow = ["CC0-1.0"] },
{ name = "secp256k1-sys", allow = ["CC0-1.0"] },
@ -35,13 +34,6 @@ exceptions = [
{ name = "untrusted", allow = ["ISC"] },
]
[[licenses.clarify]]
name = "orchard"
expression = "LicenseRef-BOSL-1.0-or-later-with-Zcash-exception"
license-files = [
{ path = "LICENSE-BOSL", hash = 0xf2d16f6e },
]
[[licenses.clarify]]
name = "ring"
expression = "LicenseRef-ring"

View File

@ -1,8 +1,8 @@
package=native_ccache
$(package)_version=4.9
$(package)_version=4.9.1
$(package)_download_path=https://github.com/ccache/ccache/releases/download/v$($(package)_version)
$(package)_file_name=ccache-$($(package)_version).tar.gz
$(package)_sha256_hash=866b2223d59333640f0e7a003cbb85b32d9ca3c9445bd9e3cf142942e69dd3ec
$(package)_sha256_hash=12834ecaaaf2db069dda1d1d991f91c19e3274cc04a471af5b64195def17e90f
$(package)_build_subdir=build
$(package)_dependencies=native_cmake native_zstd

View File

@ -1,8 +1,8 @@
package=native_cmake
$(package)_version=3.28.1
$(package)_version=3.29.2
$(package)_download_path=https://github.com/Kitware/CMake/releases/download/v$($(package)_version)
$(package)_file_name=cmake-$($(package)_version).tar.gz
$(package)_sha256_hash=15e94f83e647f7d620a140a7a5da76349fc47a1bfed66d0f5cdee8e7344079ad
$(package)_sha256_hash=36db4b6926aab741ba6e4b2ea2d99c9193222132308b4dc824d4123cb730352e
define $(package)_set_vars
$(package)_config_opts += -DCMAKE_BUILD_TYPE:STRING=Release

View File

@ -1,8 +1,8 @@
package=native_zstd
$(package)_version=1.5.5
$(package)_version=1.5.6
$(package)_download_path=https://github.com/facebook/zstd/releases/download/v$($(package)_version)
$(package)_file_name=zstd-$($(package)_version).tar.gz
$(package)_sha256_hash=9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4
$(package)_sha256_hash=8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1
$(package)_build_subdir=build/cmake
$(package)_dependencies=native_cmake

View File

@ -1145,7 +1145,7 @@ EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files

View File

@ -1,7 +1,7 @@
Zcash Contributors
==================
Jack Grigg (1416)
Jack Grigg (1430)
Kris Nuttycombe (702)
Simon Liu (460)
Sean Bowe (409)
@ -22,7 +22,7 @@ sasha (80)
Cory Fields (78)
Matt Corallo (62)
Nathan Wilcox (57)
Daira Emma Hopwood (51)
Daira Emma Hopwood (54)
practicalswift (43)
Dimitris Apostolou (43)
Kevin Gallagher (38)
@ -37,6 +37,7 @@ Suhas Daftuar (20)
furszy (18)
Marius Kjærstad (18)
Jonathan "Duke" Leto (18)
Yasser Isa (17)
syd (16)
Patick Strateman (16)
Charlie O'Keefe (16)
@ -69,6 +70,7 @@ Alex Wied (7)
David Mercer (6)
Daniel Kraft (6)
Daniel Cousens (6)
Daira-Emma Hopwood (6)
Casey Rodarmor (6)
jnewbery (5)
ca333 (5)
@ -77,10 +79,10 @@ Johnathan Corgan (5)
George Tankersley (5)
Gavin Andresen (5)
Gareth Davies (5)
Conrado Gouvea (5)
sandakersmann (4)
instagibbs (4)
gladcow (4)
Yasser Isa (4)
WO (4)
Sjors Provoost (4)
Nate Wilcox (4)
@ -102,12 +104,12 @@ Jason Davies (3)
Ethan Heilman (3)
Eric Lombrozo (3)
Danny Willems (3)
Conrado Gouvea (3)
Anthony Towns (3)
Alfie John (3)
Aditya Kulkarni (3)
ANISH M (3)
whythat (2)
shuoer86 (2)
rofl0r (2)
ptschip (2)
noname45688@gmail.com (2)

View File

@ -17,6 +17,7 @@ be removed from tier 1. These dates are subject to change.
| ----------------------- | ------------ | -------------- |
| `x86_64-pc-linux-gnu` | Debian 10 | June 2024 |
| | Debian 11 | June 2026 |
| | Debian 12 | June 2028 |
| | Ubuntu 20.04 | April 2025 |
## Tier 2

View File

@ -42,8 +42,7 @@ time, and may shift due to changes in network solution power.
<!-- RELEASE_SCRIPT_START_MARKER - If you make changes here, check make-release.py -->
| `zcashd` version | Release date | Halt height | End of Support |
| ---------------- | ------------ | ----------- | -------------- |
| 5.7.0-rc1 | 2023-09-22 | 2365300 | 2024-01-12 |
| 5.7.0 | 2023-09-28 | 2372200 | 2024-01-18 |
| 5.8.0-rc1 | 2023-12-21 | 2468300 | 2024-04-11 |
| 5.8.0 | 2024-01-02 | 2482200 | 2024-04-23 |
| 5.9.0-rc1 | 2024-04-17 | 2603900 | 2024-08-07 |
| 5.9.0 | 2024-04-19 | 2606000 | 2024-08-09 |
<!-- RELEASE_SCRIPT_END_MARKER -->

View File

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1.
.TH ZCASH-CLI "1" "January 2024" "zcash-cli v5.8.0" "User Commands"
.TH ZCASH-CLI "1" "April 2024" "zcash-cli v5.9.0" "User Commands"
.SH NAME
zcash-cli \- manual page for zcash-cli v5.8.0
zcash-cli \- manual page for zcash-cli v5.9.0
.SH DESCRIPTION
Zcash RPC client version v5.8.0
Zcash RPC client version v5.9.0
.PP
In order to ensure you are adequately protecting your privacy when using Zcash,
please see <https://z.cash/support/security/>.

View File

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1.
.TH ZCASH-TX "1" "January 2024" "zcash-tx v5.8.0" "User Commands"
.TH ZCASH-TX "1" "April 2024" "zcash-tx v5.9.0" "User Commands"
.SH NAME
zcash-tx \- manual page for zcash-tx v5.8.0
zcash-tx \- manual page for zcash-tx v5.9.0
.SH DESCRIPTION
Zcash zcash\-tx utility version v5.8.0
Zcash zcash\-tx utility version v5.9.0
.SS "Usage:"
.TP
zcash\-tx [options] <hex\-tx> [commands]

View File

@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1.
.TH ZCASHD-WALLET-TOOL "1" "January 2024" "zcashd-wallet-tool v5.8.0" "User Commands"
.TH ZCASHD-WALLET-TOOL "1" "April 2024" "zcashd-wallet-tool v5.9.0" "User Commands"
.SH NAME
zcashd-wallet-tool \- manual page for zcashd-wallet-tool v5.8.0
zcashd-wallet-tool \- manual page for zcashd-wallet-tool v5.9.0
.SH SYNOPSIS
.B zcashd-wallet-tool
[\fI\,OPTIONS\/\fR]

View File

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1.
.TH ZCASHD "1" "January 2024" "zcashd v5.8.0" "User Commands"
.TH ZCASHD "1" "April 2024" "zcashd v5.9.0" "User Commands"
.SH NAME
zcashd \- manual page for zcashd v5.8.0
zcashd \- manual page for zcashd v5.9.0
.SH DESCRIPTION
Zcash Daemon version v5.8.0
Zcash Daemon version v5.9.0
.PP
In order to ensure you are adequately protecting your privacy when using Zcash,
please see <https://z.cash/support/security/>.

View File

@ -0,0 +1,64 @@
This is a maintenance release that updates dependencies and sets a new
end-of-service height to help ensure continuity of services.
Notable changes
===============
License documentation has been updated to account for the `orchard` crate
now being licensed under "MIT OR Apache-2.0".
Platform Support
----------------
- Debian 11 (Bookworm) is now a Tier 1 platform.
Changelog
=========
Conrado Gouvea (2):
make cache.cpp compile with MSVC
Update src/zcash/cache.h
Daira Emma Hopwood (3):
Lead with "Zcash is HTTPS for money" in both the README and the Debian package description. (This also fixes a typo in the latter.)
Change my name in Cargo.toml and remove old email addresses for Ying Tong Lai, Greg Pfeil, and Steven Smith.
Remove references to the BOSL license, which will no longer be used by any dependency as of the next release.
Daira-Emma Hopwood (6):
Update or postpone dependencies for zcashd 5.9.0.
deny.toml: remove license exception for orchard.
deny.toml: migrate to version 2 to avoid some warnings.
Additional updated and postponed dependencies for zcashd 5.9.0.
* cargo update * cargo update -p home@0.5.9 --precise 0.5.5
Update audits.
Jack Grigg (9):
CI: Migrate to `{upload, download}-artifact@v4`
CI: Fix name for gtest job
CI: Run bitrot build jobs in parallel
CI: Run Rust tests
rust: Migrate to `zcash_primitives 0.14.0`
depends: Postpone LLVM 18.1.4
docs: Document Debian 12 as a Tier 1 platform
make-release.py: Versioning changes for 5.9.0-rc1.
make-release.py: Updated manpages for 5.9.0-rc1.
Yasser Isa (13):
CI: Specify `HOST` for every build instead of just cross-compiles
CI: Cache Sprout parameters during setup phase
CI: Store build artifacts in GCS instead of GitHub
CI: Add `no-dot-so` lint
CI: Add `sec-hard` test
CI: Add remaining unit tests
add pull_request_target in the CI
Revert "Update the CI to include `pull_request_target`"
ADD support to Bookworm
Create docker-release.yaml in Github Actions
Allow running CI from a fork
Debian CI in Github Actions
fix CI - cache sprout params
shuoer86 (2):
Fix typos
Fix typos

View File

@ -0,0 +1,79 @@
This is a maintenance release that updates dependencies and sets a new
end-of-service height to help ensure continuity of services.
Notable changes
===============
License documentation has been updated to account for the `orchard` crate
now being licensed under "MIT OR Apache-2.0".
Platform Support
----------------
- Debian 11 (Bookworm) is now a Tier 1 platform.
- Intel macOS will be formally downgraded to a Tier 3 platform in the next
release. Previously it has informally been at both Tier 1 (because builds and
tests were run in CI) and Tier 3 (because no packages were provided). However,
we are currently unable to update the Clang and Rust compilers due to there
being no Clang release built for Intel macOS from LLVM 16 onwards. Combined
with the fact that the Intel Macbook was discontinued in 2021, this decision
means that we will no longer be building `zcashd` natively on Intel macOS in
CI for testing purposes. We will not be removing build system support (so
builds may still function, and community patches to fix issues are welcomed).
Changelog
=========
Conrado Gouvea (2):
make cache.cpp compile with MSVC
Update src/zcash/cache.h
Daira Emma Hopwood (3):
Lead with "Zcash is HTTPS for money" in both the README and the Debian package description. (This also fixes a typo in the latter.)
Change my name in Cargo.toml and remove old email addresses for Ying Tong Lai, Greg Pfeil, and Steven Smith.
Remove references to the BOSL license, which will no longer be used by any dependency as of the next release.
Daira-Emma Hopwood (6):
Update or postpone dependencies for zcashd 5.9.0.
deny.toml: remove license exception for orchard.
deny.toml: migrate to version 2 to avoid some warnings.
Additional updated and postponed dependencies for zcashd 5.9.0.
* cargo update * cargo update -p home@0.5.9 --precise 0.5.5
Update audits.
Jack Grigg (14):
CI: Migrate to `{upload, download}-artifact@v4`
CI: Fix name for gtest job
CI: Run bitrot build jobs in parallel
CI: Run Rust tests
rust: Migrate to `zcash_primitives 0.14.0`
depends: Postpone LLVM 18.1.4
docs: Document Debian 12 as a Tier 1 platform
make-release.py: Versioning changes for 5.9.0-rc1.
make-release.py: Updated manpages for 5.9.0-rc1.
make-release.py: Updated release notes and changelog for 5.9.0-rc1.
make-release.py: Updated book for 5.9.0-rc1.
Document that Intel macOS will be formally moved to Tier 3 in 5.10.0
make-release.py: Versioning changes for 5.9.0.
make-release.py: Updated manpages for 5.9.0.
Yasser Isa (13):
CI: Specify `HOST` for every build instead of just cross-compiles
CI: Cache Sprout parameters during setup phase
CI: Store build artifacts in GCS instead of GitHub
CI: Add `no-dot-so` lint
CI: Add `sec-hard` test
CI: Add remaining unit tests
add pull_request_target in the CI
Revert "Update the CI to include `pull_request_target`"
ADD support to Bookworm
Create docker-release.yaml in Github Actions
Allow running CI from a fork
Debian CI in Github Actions
fix CI - cache sprout params
shuoer86 (2):
Fix typos
Fix typos

View File

@ -190,7 +190,7 @@ def main():
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface')
parser.add_argument('--deterministic', '-d', action='store_true', help='make the output a bit closer to deterministic in order to compare runs.')
parser.add_argument('--exclude', '-x', help='specify a comma-seperated-list of scripts to exclude. Do not include the .py extension in the name.')
parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude. Do not include the .py extension in the name.')
parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests')
parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).')
parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit')

View File

@ -237,7 +237,7 @@ class FinalOrchardRootTest(BitcoinTestFramework):
assert new_treestate["sapling"]["commitments"]["finalRoot"] != treestate["sapling"]["commitments"]["finalRoot"]
assert new_treestate["sapling"]["commitments"]["finalState"] != treestate["sapling"]["commitments"]["finalState"]
assert_equal(len(new_treestate["sapling"]["commitments"]["finalRoot"]), 64)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 70)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 134)
treestate = new_treestate
# Mine a block with an Orchard shielded recipient and verify the final Orchard root changes

View File

@ -122,8 +122,8 @@ class FinalSaplingRootTest(BitcoinTestFramework):
# Verify there is a Sapling output description (its commitment was added to tree)
result = self.nodes[0].getrawtransaction(mytxid, 1)
assert_equal(len(result["vShieldedOutput"]), 1)
assert_equal(blk["trees"]["sapling"]["size"], 1)
assert_equal(len(result["vShieldedOutput"]), 2) # Non-coinbase bundles are padded
assert_equal(blk["trees"]["sapling"]["size"], 2)
# Since there is a now sapling shielded input in the blockchain,
# the sapling values should have changed
@ -133,7 +133,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert new_treestate["sapling"]["commitments"]["finalRoot"] != treestate["sapling"]["commitments"]["finalRoot"]
assert new_treestate["sapling"]["commitments"]["finalState"] != treestate["sapling"]["commitments"]["finalState"]
assert_equal(len(new_treestate["sapling"]["commitments"]["finalRoot"]), 64)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 70)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 134)
treestate = new_treestate
# Mine an empty block and verify the final Sapling root does not change
@ -142,7 +142,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
self.sync_all()
blk = self.nodes[0].getblock("202")
assert_equal(root, blk["finalsaplingroot"])
assert_equal(blk["trees"]["sapling"]["size"], 1)
assert_equal(blk["trees"]["sapling"]["size"], 2)
# Mine a block with a transparent tx and verify the final Sapling root does not change
taddr1 = self.nodes[1].getnewaddress()
@ -171,7 +171,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert_equal(len(blk["tx"]), 2)
assert_equal(self.nodes[0].z_getbalance(zaddr0), Decimal("37.66"))
assert_equal(root, blk["finalsaplingroot"])
assert_equal(blk["trees"]["sapling"]["size"], 1)
assert_equal(blk["trees"]["sapling"]["size"], 2)
new_treestate = self.nodes[0].z_gettreestate(str(-1))
assert_equal(new_treestate["sapling"]["commitments"]["finalRoot"], root)
@ -200,14 +200,14 @@ class FinalSaplingRootTest(BitcoinTestFramework):
# Verify there is a Sapling output description (its commitment was added to tree)
result = self.nodes[0].getrawtransaction(mytxid, 1)
assert_equal(len(result["vShieldedOutput"]), 2) # there is Sapling shielded change
assert_equal(blk["trees"]["sapling"]["size"], 3)
assert_equal(blk["trees"]["sapling"]["size"], 4)
new_treestate = self.nodes[0].z_gettreestate(str(-1))
assert_equal(new_treestate["sprout"], treestate["sprout"])
assert new_treestate["sapling"]["commitments"]["finalRoot"] != treestate["sapling"]["commitments"]["finalRoot"]
assert new_treestate["sapling"]["commitments"]["finalState"] != treestate["sapling"]["commitments"]["finalState"]
assert_equal(len(new_treestate["sapling"]["commitments"]["finalRoot"]), 64)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 136)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 200)
treestate = new_treestate
# Mine a block with a Sapling shielded sender and transparent recipient.
@ -221,16 +221,19 @@ class FinalSaplingRootTest(BitcoinTestFramework):
self.nodes[0].generate(1)
self.sync_all()
assert_equal(len(self.nodes[0].getblock("206")["tx"]), 2)
blk = self.nodes[0].getblock("206")
assert_equal(len(blk["tx"]), 2)
assert_equal(mytxid, blk["tx"][1])
assert_equal(self.nodes[0].z_getbalance(taddr2), Decimal("2.34"))
assert_equal(self.nodes[1].z_getbalance(saplingAddr1), 0)
# Verify the final Sapling root changes (because the Sapling bundle was padded
# with 2 dummy outputs).
blk = self.nodes[0].getblock("206")
print(self.nodes[0].getrawtransaction(blk["tx"][0]))
print(self.nodes[0].getrawtransaction(blk["tx"][1]))
root = blk["finalsaplingroot"]
assert root != self.nodes[0].getblock("205")["finalsaplingroot"]
assert_equal(blk["trees"]["sapling"]["size"], 5)
assert_equal(blk["trees"]["sapling"]["size"], 6)
# Verify there are two Sapling output descriptions.
result = self.nodes[0].getrawtransaction(mytxid, 1)
@ -241,7 +244,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert new_treestate["sapling"]["commitments"]["finalRoot"] != treestate["sapling"]["commitments"]["finalRoot"]
assert new_treestate["sapling"]["commitments"]["finalState"] != treestate["sapling"]["commitments"]["finalState"]
assert_equal(len(new_treestate["sapling"]["commitments"]["finalRoot"]), 64)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 138)
assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 202)
treestate = new_treestate
# Activate NU5; more testing should be added once we can mine orchard transactions.

View File

@ -84,7 +84,7 @@ class KeyPoolTest(BitcoinTestFramework):
nodes[0].generate(1)
try:
nodes[0].generate(1)
raise AssertionError('Keypool should be exhausted after three addesses')
raise AssertionError('Keypool should be exhausted after three addresses')
except JSONRPCException as e:
assert_equal(e.error['code'], -12)

View File

@ -30,11 +30,21 @@ criteria = "safe-to-deploy"
delta = "0.8.6 -> 0.8.7"
notes = "Build-time `stdsimd` detection is replaced with a nightly-only feature flag."
[[audits.ahash]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.8.7 -> 0.8.11"
[[audits.aho-corasick]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.1.1 -> 1.1.2"
[[audits.aho-corasick]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.1.2 -> 1.1.3"
[[audits.allocator-api2]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -52,6 +62,11 @@ criteria = "safe-to-deploy"
delta = "0.2.15 -> 0.2.16"
notes = "Change to `unsafe` block is to fix the `Drop` impl of `Box` to drop its value."
[[audits.allocator-api2]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.16 -> 0.2.18"
[[audits.anyhow]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -105,6 +120,11 @@ Build script changes are to refactor the existing probe into a separate file
changes in the build environment.
"""
[[audits.anyhow]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.79 -> 1.0.82"
[[audits.arrayref]]
who = "Sean Bowe <ewillbefull@gmail.com>"
criteria = "safe-to-deploy"
@ -127,6 +147,12 @@ then loaded. These appear to all derive from existing paths that themselves were
being mmapped and loaded.
"""
[[audits.backtrace]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.3.69 -> 0.3.71"
notes = "This crate inherently requires a lot of `unsafe` code, but the changes look plausible."
[[audits.base64]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -137,6 +163,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.21.4 -> 0.21.5"
[[audits.base64]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.21.5 -> 0.21.7"
[[audits.bech32]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -204,12 +235,22 @@ criteria = "safe-to-deploy"
delta = "0.7.1 -> 0.8.0"
notes = "I previously reviewed the crypto-sensitive portions of these changes as well."
[[audits.bs58]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.5.0 -> 0.5.1"
[[audits.bumpalo]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
delta = "3.11.1 -> 3.12.0"
notes = "Changes to `unsafe` code are to replace `mem::forget` uses with `ManuallyDrop`."
[[audits.bumpalo]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "3.15.4 -> 3.16.0"
[[audits.byte-slice-cast]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -246,6 +287,32 @@ notes = """
almost identically to the existing `unsafe impl BufMut for &mut [u8]`.
"""
[[audits.bytes]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.5.0 -> 1.6.0"
notes = """
There is significant use of `unsafe` code, but safety requirements are well documented
and appear correct as far as I can see.
"""
[[audits.cc]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.83 -> 1.0.94"
notes = """
The optimization to use `buffer.set_len(buffer.capacity())` in `command_helpers::StderrForwarder::forward_available`
doesn't look panic-safe: if `stderr.read` panics and that panic is caught by a caller of `forward_available`, then
the inner buffer of `StderrForwarder` will contain uninitialized data. This looks difficult to trigger in practice,
but I have opened an issue <https://github.com/rust-lang/cc-rs/issues/1036>.
`parallel::async_executor` contains `unsafe` pinning code but it looks reasonable. Similarly for the `unsafe`
initialization code in `parallel::job_token::JobTokenServer` and file operations in `parallel::stderr`.
This crate executes commands, and my review is likely not sufficient to detect subtle backdoors.
I did not review the use of library handles in the `com` package on Windows.
"""
[[audits.chacha20]]
who = "Jack Grigg <jack@z.cash>"
criteria = ["crypto-reviewed", "safe-to-deploy"]
@ -345,6 +412,11 @@ LoongArch64 CPU feature detection support. This and the supporting macro code is
the same as the existing Linux code for AArch64.
"""
[[audits.cpufeatures]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.11 -> 0.2.12"
[[audits.crossbeam-channel]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -376,6 +448,12 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.8.3 -> 0.8.4"
[[audits.crossbeam-deque]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.8.4 -> 0.8.5"
notes = "Changes to `unsafe` code look okay."
[[audits.crossbeam-epoch]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -403,6 +481,11 @@ Changes to `unsafe` code are to replace manual pointer logic with equivalent
`unsafe` stdlib methods, now that MSRV is high enough to use them.
"""
[[audits.crossbeam-epoch]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.9.17 -> 0.9.18"
[[audits.crossbeam-utils]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -455,6 +538,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = ["safe-to-deploy", "crypto-reviewed"]
delta = "4.1.0 -> 4.1.1"
[[audits.curve25519-dalek]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "4.1.1 -> 4.1.2"
[[audits.curve25519-dalek-derive]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = ["safe-to-deploy", "crypto-reviewed"]
@ -675,6 +763,12 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.0.111 -> 1.0.113"
[[audits.der]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.7.8 -> 0.7.9"
notes = "The change to ignore RUSTSEC-2023-0071 is correct for this crate."
[[audits.deranged]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -760,6 +854,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.8.1 -> 1.9.0"
[[audits.either]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.9.0 -> 1.11.0"
[[audits.equivalent]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -785,6 +884,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "2.0.0 -> 2.0.1"
[[audits.fastrand]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "2.0.1 -> 2.0.2"
[[audits.ff]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1037,11 +1141,21 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.3.1 -> 0.3.2"
[[audits.hermit-abi]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.3.3 -> 0.3.9"
[[audits.http]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.2.8 -> 0.2.9"
[[audits.http]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.11 -> 0.2.12"
[[audits.http]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -1171,6 +1285,11 @@ notes = """
MDN documentation.
"""
[[audits.js-sys]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.3.66 -> 0.3.69"
[[audits.jubjub]]
who = "Sean Bowe <ewillbefull@gmail.com>"
criteria = "safe-to-deploy"
@ -1221,6 +1340,11 @@ criteria = "safe-to-deploy"
delta = "0.2.7 -> 0.2.8"
notes = "Forces some intermediate values to not have too much precision on the x87 FPU."
[[audits.libredox]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.0.1 -> 0.1.3"
[[audits.link-cplusplus]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1231,6 +1355,12 @@ who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
delta = "1.0.7 -> 1.0.8"
[[audits.linux-raw-sys]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.4.12 -> 0.4.13"
notes = "Low-level OS interface crate, so `unsafe` code is expected."
[[audits.lock_api]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1253,6 +1383,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.4.19 -> 0.4.20"
[[audits.log]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.4.20 -> 0.4.21"
[[audits.maybe-rayon]]
who = "Sean Bowe <ewillbefull@gmail.com>"
criteria = "safe-to-deploy"
@ -1273,6 +1408,11 @@ comparison between `u8` pointers. The new tail code matches the existing head
code (but adapted to `u16` and `u8` reads, instead of `u32`).
"""
[[audits.memchr]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "2.7.1 -> 2.7.2"
[[audits.memoffset]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -1330,6 +1470,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.15.0 -> 0.15.1"
[[audits.miniz_oxide]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.7.1 -> 0.7.2"
[[audits.mio]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1371,6 +1516,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.8.6 -> 0.8.8"
[[audits.mio]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.8.10 -> 0.8.11"
[[audits.nix]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1390,6 +1540,11 @@ Most of the `unsafe` changes are cleaning up their usage:
A new unsafe trait method `SockaddrLike::set_length` is added; it's impls look fine.
"""
[[audits.num-conv]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
version = "0.1.0"
[[audits.num-integer]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1427,6 +1582,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.32.0 -> 0.32.1"
[[audits.object]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.32.1 -> 0.32.2"
[[audits.once_cell]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1436,6 +1596,11 @@ Small refactor that reduces the overall amount of `unsafe` code. The new strict
approach looks reasonable.
"""
[[audits.opaque-debug]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.3.0 -> 0.3.1"
[[audits.pairing]]
who = "Sean Bowe <ewillbefull@gmail.com>"
criteria = "safe-to-deploy"
@ -1568,6 +1733,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.2.9 -> 0.2.13"
[[audits.pin-project-lite]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.13 -> 0.2.14"
[[audits.platforms]]
who = "Daira Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
@ -1593,6 +1763,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "3.2.0 -> 3.3.0"
[[audits.platforms]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "3.3.0 -> 3.4.0"
[[audits.poly1305]]
who = "Daira Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
@ -1761,6 +1936,11 @@ criteria = "safe-to-deploy"
delta = "0.4.3 -> 0.4.4"
notes = "Switches from `redox_syscall` crate to `libredox` crate for syscalls."
[[audits.redox_users]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.4.4 -> 0.4.5"
[[audits.regex]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1776,6 +1956,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.9.5 -> 1.10.2"
[[audits.regex]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.10.2 -> 1.10.4"
[[audits.regex-automata]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -1785,6 +1970,11 @@ There were additions to an `unsafe` trait, but the new code itself doesn't use
any `unsafe` functions.
"""
[[audits.regex-automata]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.4.3 -> 0.4.6"
[[audits.regex-syntax]]
who = "Sean Bowe <ewillbefull@gmail.com>"
criteria = "safe-to-deploy"
@ -1800,6 +1990,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.7.5 -> 0.8.2"
[[audits.regex-syntax]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.8.2 -> 0.8.3"
[[audits.rustc-demangle]]
who = "Sean Bowe <ewillbefull@gmail.com>"
criteria = "safe-to-deploy"
@ -1824,6 +2019,12 @@ execute arbitrary code. But when this crate is used within a build script, `$RUS
be set correctly by `cargo`.
"""
[[audits.rustix]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.38.28 -> 0.38.32"
notes = "Cursory review."
[[audits.ryu]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -1839,6 +2040,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.0.15 -> 1.0.16"
[[audits.ryu]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.16 -> 1.0.17"
[[audits.scopeguard]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -1860,6 +2066,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.0.19 -> 1.0.20"
[[audits.semver]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.20 -> 1.0.22"
[[audits.serde]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -1978,6 +2189,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.0.108 -> 1.0.110"
[[audits.serde_json]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.110 -> 1.0.116"
[[audits.sha2]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -2025,6 +2241,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.2.0 -> 0.2.1"
[[audits.sketches-ddsketch]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.1 -> 0.2.2"
[[audits.socket2]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -2043,6 +2264,11 @@ Adds support for Sony Vita targets. New `unsafe` blocks are for Vita-specific
`libc` calls to `getsockopt` and `setsockopt` for non-blocking behaviour.
"""
[[audits.socket2]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.5.5 -> 0.5.6"
[[audits.syn]]
who = "Daira Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
@ -2109,6 +2335,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "2.0.43 -> 2.0.46"
[[audits.syn]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "2.0.46 -> 2.0.59"
[[audits.tempfile]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -2130,6 +2361,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "3.8.1 -> 3.9.0"
[[audits.tempfile]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "3.9.0 -> 3.10.1"
[[audits.terminfo]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -2174,6 +2410,11 @@ Build script changes are to refactor the existing probe into a separate file
changes in the build environment.
"""
[[audits.thiserror]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.56 -> 1.0.58"
[[audits.thiserror-impl]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -2206,6 +2447,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.0.52 -> 1.0.56"
[[audits.thiserror-impl]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.0.56 -> 1.0.58"
[[audits.thread_local]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -2216,6 +2462,15 @@ New `unsafe` usage:
- Setting and getting a `#[thread_local] static mut Option<Thread>` on nightly.
"""
[[audits.thread_local]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.1.7 -> 1.1.8"
notes = """
Adds `unsafe` code that makes an assumption that `ptr::null_mut::<Entry<T>>()` is a valid representation
of an `AtomicPtr<Entry<T>>`, but this is likely a correct assumption.
"""
[[audits.time]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -2235,6 +2490,12 @@ Removes one `unsafe` block by repurposing a constructor containing a more
general invocation of the same `unsafe` function.
"""
[[audits.time]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.3.31 -> 0.3.36"
notes = "Some use of `unsafe` code but its safety requirements are documented and look okay."
[[audits.time-core]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -2289,6 +2550,11 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.2.15 -> 0.2.16"
[[audits.time-macros]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.16 -> 0.2.18"
[[audits.tinyvec_macros]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -2300,6 +2566,12 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "1.35.0 -> 1.35.1"
[[audits.tokio]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "1.35.1 -> 1.37.0"
notes = "Cursory review, but new and changed uses of `unsafe` code look fine, as far as I can see."
[[audits.toml_datetime]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -2468,11 +2740,26 @@ Migrates to `try-lock 0.2.4` to replace some unsafe APIs that were not marked
`unsafe` (but that were being used safely).
"""
[[audits.wasm-bindgen-backend]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.89 -> 0.2.92"
[[audits.wasm-bindgen-macro]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.2.87 -> 0.2.89"
[[audits.wasm-bindgen-macro]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.89 -> 0.2.92"
[[audits.wasm-bindgen-macro-support]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
version = "0.2.92"
[[audits.wasm-bindgen-macro-support]]
who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
@ -2494,6 +2781,16 @@ who = "Jack Grigg <jack@electriccoin.co>"
criteria = "safe-to-deploy"
delta = "0.2.87 -> 0.2.89"
[[audits.wasm-bindgen-shared]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.2.89 -> 0.2.92"
[[audits.web-sys]]
who = "Daira-Emma Hopwood <daira@jacaranda.org>"
criteria = "safe-to-deploy"
delta = "0.3.66 -> 0.3.69"
[[audits.which]]
who = "Jack Grigg <jack@z.cash>"
criteria = "safe-to-deploy"
@ -2594,7 +2891,7 @@ end = "2024-09-21"
[[trusted.halo2_legacy_pdqsort]]
criteria = ["safe-to-deploy", "crypto-reviewed"]
user-id = 199950 # Daira Hopwood (daira)
user-id = 199950 # Daira Emma Hopwood (daira)
start = "2023-02-24"
end = "2024-09-21"
@ -2634,6 +2931,12 @@ user-id = 1244 # ebfull
start = "2022-10-19"
end = "2024-09-21"
[[trusted.sapling-crypto]]
criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"]
user-id = 6289 # str4d
start = "2024-01-26"
end = "2025-03-18"
[[trusted.windows-sys]]
criteria = "safe-to-deploy"
user-id = 64539 # Kenny Kerr (kennykerr)
@ -2694,6 +2997,12 @@ user-id = 1244 # ebfull
start = "2022-10-19"
end = "2024-09-21"
[[trusted.zcash_address]]
criteria = "safe-to-deploy"
user-id = 6289 # str4d
start = "2021-03-07"
end = "2025-03-18"
[[trusted.zcash_encoding]]
criteria = "safe-to-deploy"
user-id = 1244 # ebfull
@ -2706,6 +3015,12 @@ user-id = 1244 # ebfull
start = "2020-03-04"
end = "2024-09-21"
[[trusted.zcash_history]]
criteria = "safe-to-deploy"
user-id = 6289 # str4d
start = "2024-03-01"
end = "2025-03-18"
[[trusted.zcash_note_encryption]]
criteria = ["safe-to-deploy", "crypto-reviewed"]
user-id = 169181 # Kris Nuttycombe (nuttycom)
@ -2729,3 +3044,21 @@ criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"]
user-id = 6289 # str4d
start = "2021-03-26"
end = "2024-09-21"
[[trusted.zcash_protocol]]
criteria = "safe-to-deploy"
user-id = 169181 # Kris Nuttycombe (nuttycom)
start = "2024-01-27"
end = "2025-04-16"
[[trusted.zcash_spec]]
criteria = ["safe-to-deploy", "crypto-reviewed", "license-reviewed"]
user-id = 6289 # str4d
start = "2023-12-07"
end = "2025-03-18"
[[trusted.zip32]]
criteria = "safe-to-deploy"
user-id = 6289 # str4d
start = "2023-12-06"
end = "2025-03-18"

View File

@ -2,7 +2,7 @@
# cargo-vet config file
[cargo-vet]
version = "0.8"
version = "0.9"
[imports.bytecode-alliance]
url = "https://raw.githubusercontent.com/bytecodealliance/wasmtime/main/supply-chain/audits.toml"
@ -91,10 +91,6 @@ criteria = "safe-to-deploy"
version = "0.5.0"
criteria = "safe-to-deploy"
[[exemptions.byte-slice-cast]]
version = "1.2.1"
criteria = "safe-to-deploy"
[[exemptions.byteorder]]
version = "1.4.3"
criteria = "safe-to-deploy"
@ -195,16 +191,12 @@ criteria = "safe-to-deploy"
version = "3.0.0"
criteria = "safe-to-deploy"
[[exemptions.equivalent]]
version = "1.0.0"
criteria = "safe-to-deploy"
[[exemptions.ff]]
version = "0.12.0"
criteria = "safe-to-deploy"
[[exemptions.fixed-hash]]
version = "0.7.0"
version = "0.8.0"
criteria = "safe-to-deploy"
[[exemptions.fpe]]
@ -279,30 +271,14 @@ criteria = "safe-to-deploy"
version = "0.14.25"
criteria = "safe-to-deploy"
[[exemptions.impl-codec]]
version = "0.6.0"
criteria = "safe-to-deploy"
[[exemptions.impl-trait-for-tuples]]
version = "0.2.2"
criteria = "safe-to-deploy"
[[exemptions.indexmap]]
version = "1.8.1"
criteria = "safe-to-deploy"
[[exemptions.indexmap]]
version = "2.0.0"
criteria = "safe-to-deploy"
[[exemptions.ipnet]]
version = "2.5.0"
criteria = "safe-to-deploy"
[[exemptions.itoa]]
version = "1.0.2"
criteria = "safe-to-deploy"
[[exemptions.js-sys]]
version = "0.3.60"
criteria = "safe-to-deploy"
@ -363,10 +339,6 @@ criteria = "safe-to-deploy"
version = "0.26.1"
criteria = "safe-to-deploy"
[[exemptions.nom]]
version = "7.1.1"
criteria = "safe-to-deploy"
[[exemptions.nonempty]]
version = "0.7.0"
criteria = "safe-to-deploy"
@ -387,14 +359,6 @@ criteria = "safe-to-deploy"
version = "0.22.0"
criteria = "safe-to-deploy"
[[exemptions.parity-scale-codec]]
version = "3.6.1"
criteria = "safe-to-deploy"
[[exemptions.parity-scale-codec-derive]]
version = "3.6.5"
criteria = "safe-to-deploy"
[[exemptions.password-hash]]
version = "0.3.2"
criteria = "safe-to-deploy"
@ -444,11 +408,7 @@ version = "0.2.16"
criteria = "safe-to-deploy"
[[exemptions.primitive-types]]
version = "0.11.1"
criteria = "safe-to-deploy"
[[exemptions.proc-macro-crate]]
version = "1.2.1"
version = "0.12.2"
criteria = "safe-to-deploy"
[[exemptions.proptest]]
@ -479,10 +439,6 @@ criteria = "safe-to-deploy"
version = "0.3.0"
criteria = "safe-to-deploy"
[[exemptions.redox_syscall]]
version = "0.4.1"
criteria = "safe-to-deploy"
[[exemptions.redox_users]]
version = "0.4.3"
criteria = "safe-to-deploy"
@ -515,10 +471,6 @@ criteria = "safe-to-deploy"
version = "0.1.3"
criteria = "safe-to-deploy"
[[exemptions.rustc-hex]]
version = "2.1.0"
criteria = "safe-to-deploy"
[[exemptions.rustix]]
version = "0.38.28"
criteria = "safe-to-deploy"
@ -543,14 +495,6 @@ criteria = "safe-to-deploy"
version = "0.8.0"
criteria = "safe-to-deploy"
[[exemptions.serde]]
version = "1.0.136"
criteria = "safe-to-deploy"
[[exemptions.serde_derive]]
version = "1.0.136"
criteria = "safe-to-deploy"
[[exemptions.serde_json]]
version = "1.0.81"
criteria = "safe-to-deploy"
@ -579,10 +523,6 @@ criteria = "safe-to-deploy"
version = "0.7.3"
criteria = "safe-to-deploy"
[[exemptions.static_assertions]]
version = "1.1.0"
criteria = "safe-to-deploy"
[[exemptions.subtle]]
version = "2.4.1"
criteria = "safe-to-deploy"
@ -611,10 +551,6 @@ criteria = "safe-to-deploy"
version = "1.35.0"
criteria = "safe-to-deploy"
[[exemptions.toml_edit]]
version = "0.19.15"
criteria = "safe-to-deploy"
[[exemptions.tower-service]]
version = "0.3.2"
criteria = "safe-to-deploy"
@ -656,7 +592,7 @@ version = "0.11.0+wasi-snapshot-preview1"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen]]
version = "0.2.89"
version = "0.2.92"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen-backend]]
@ -667,10 +603,6 @@ criteria = "safe-to-deploy"
version = "0.2.87"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen-macro-support]]
version = "0.2.87"
criteria = "safe-to-deploy"
[[exemptions.web-sys]]
version = "0.3.66"
criteria = "safe-to-deploy"
@ -691,8 +623,8 @@ criteria = "safe-to-deploy"
version = "0.4.0"
criteria = "safe-to-deploy"
[[exemptions.winnow]]
version = "0.5.31"
[[exemptions.windows_i686_gnullvm]]
version = "0.52.5"
criteria = "safe-to-deploy"
[[exemptions.wyz]]

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,12 @@ def get_arch_dir():
# Just try the first one; there will only be one in CI
return arch_dirs[0]
# Not MacOS, try Windows
arch_dirs = glob(os.path.join(depends_dir, 'x86_64-w64-mingw32*'))
if arch_dirs:
# Just try the first one; there will only be one in CI
return arch_dirs[0]
print("!!! cannot find architecture dir under depends/ !!!")
return None
@ -88,7 +94,22 @@ def check_security_hardening():
ret = True
# PIE, RELRO, Canary, and NX are tested by make check-security.
ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0
if os.path.exists(repofile('src/Makefile')):
ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0
else:
# Equivalent to make check-security (this is just for CI purpose)
bin_programs = ['src/zcashd', 'src/zcash-cli', 'src/zcash-tx', 'src/bench/bench_bitcoin'] # Replace with actual values
bin_scripts = ['src/zcash-inspect', 'src/zcashd-wallet-tool'] # Replace with actual values
print(f"Checking binary security of {bin_programs + bin_scripts}...")
for program in bin_programs:
command = [repofile('contrib/devtools/security-check.py'), repofile(program)]
ret &= subprocess.call(command) == 0
for script in bin_scripts:
command = [repofile('contrib/devtools/security-check.py'), '--allow-no-canary', repofile(script)]
ret &= subprocess.call(command) == 0
# The remaining checks are only for ELF binaries
# Assume that if zcashd is an ELF binary, they all are

View File

@ -5,53 +5,86 @@
#
# Boost 1.84.0 causes gtests to fail on macOS.
boost 1.84.0 2024-02-01
native_b2 1.84.0 2024-02-01
boost 1.84.0 2024-06-15
boost 1.85.0 2024-06-15
native_b2 1.84.0 2024-06-15
native_b2 1.85.0 2024-06-15
# Clang and Rust are currently pinned to LLVM 15
libcxx 15.0.7 2024-03-15
libcxx 16.0.0 2024-03-15
libcxx 16.0.1 2024-03-15
libcxx 16.0.2 2024-03-15
libcxx 16.0.2 2024-03-15
libcxx 16.0.3 2024-03-15
libcxx 16.0.4 2024-03-15
libcxx 16.0.5 2024-03-15
libcxx 16.0.6 2024-03-15
libcxx 17.0.0 2024-03-15
libcxx 17.0.1 2024-03-15
libcxx 17.0.2 2024-03-15
libcxx 17.0.3 2024-03-15
libcxx 17.0.4 2024-03-15
libcxx 17.0.5 2024-03-15
libcxx 17.0.6 2024-03-15
native_clang 15.0.7 2024-03-15
native_clang 16.0.0 2024-03-15
native_clang 16.0.1 2024-03-15
native_clang 16.0.2 2024-03-15
native_clang 16.0.3 2024-03-15
native_clang 16.0.4 2024-03-15
native_clang 16.0.5 2024-03-15
native_clang 16.0.6 2024-03-15
native_clang 17.0.0 2024-03-15
native_clang 17.0.1 2024-03-15
native_clang 17.0.2 2024-03-15
native_clang 17.0.3 2024-03-15
native_clang 17.0.4 2024-03-15
native_clang 17.0.5 2024-03-15
native_clang 17.0.6 2024-03-15
native_rust 1.70.0 2024-03-15
native_rust 1.71.0 2024-03-15
native_rust 1.71.1 2024-03-15
native_rust 1.72.0 2024-03-15
native_rust 1.72.1 2024-03-15
native_rust 1.73.0 2024-03-15
native_rust 1.74.0 2024-03-15
native_rust 1.74.1 2024-03-15
native_rust 1.75.0 2024-03-15
libcxx 15.0.7 2024-06-15
libcxx 16.0.0 2024-06-15
libcxx 16.0.1 2024-06-15
libcxx 16.0.2 2024-06-15
libcxx 16.0.2 2024-06-15
libcxx 16.0.3 2024-06-15
libcxx 16.0.4 2024-06-15
libcxx 16.0.5 2024-06-15
libcxx 16.0.6 2024-06-15
libcxx 17.0.0 2024-06-15
libcxx 17.0.1 2024-06-15
libcxx 17.0.2 2024-06-15
libcxx 17.0.3 2024-06-15
libcxx 17.0.4 2024-06-15
libcxx 17.0.5 2024-06-15
libcxx 17.0.6 2024-06-15
libcxx 18.1.0 2024-06-15
libcxx 18.1.1 2024-06-15
libcxx 18.1.2 2024-06-15
libcxx 18.1.3 2024-06-15
libcxx 18.1.4 2024-06-15
native_clang 15.0.7 2024-06-15
native_clang 16.0.0 2024-06-15
native_clang 16.0.1 2024-06-15
native_clang 16.0.2 2024-06-15
native_clang 16.0.3 2024-06-15
native_clang 16.0.4 2024-06-15
native_clang 16.0.5 2024-06-15
native_clang 16.0.6 2024-06-15
native_clang 17.0.0 2024-06-15
native_clang 17.0.1 2024-06-15
native_clang 17.0.2 2024-06-15
native_clang 17.0.3 2024-06-15
native_clang 17.0.4 2024-06-15
native_clang 17.0.5 2024-06-15
native_clang 17.0.6 2024-06-15
native_clang 18.1.0 2024-06-15
native_clang 18.1.1 2024-06-15
native_clang 18.1.2 2024-06-15
native_clang 18.1.3 2024-06-15
native_clang 18.1.4 2024-06-15
native_rust 1.70.0 2024-06-15
native_rust 1.71.0 2024-06-15
native_rust 1.71.1 2024-06-15
native_rust 1.72.0 2024-06-15
native_rust 1.72.1 2024-06-15
native_rust 1.73.0 2024-06-15
native_rust 1.74.0 2024-06-15
native_rust 1.74.1 2024-06-15
native_rust 1.75.0 2024-06-15
native_rust 1.76.0 2024-06-15
native_rust 1.77.0 2024-06-15
native_rust 1.77.1 2024-06-15
native_rust 1.77.2 2024-06-15
native_cxxbridge 1.0.114 2024-06-15
native_cxxbridge 1.0.115 2024-06-15
native_cxxbridge 1.0.116 2024-06-15
native_cxxbridge 1.0.117 2024-06-15
native_cxxbridge 1.0.118 2024-06-15
native_cxxbridge 1.0.119 2024-06-15
native_cxxbridge 1.0.120 2024-06-15
native_cxxbridge 1.0.121 2024-06-15
rustcxx 1.0.114 2024-06-15
rustcxx 1.0.115 2024-06-15
rustcxx 1.0.116 2024-06-15
rustcxx 1.0.117 2024-06-15
rustcxx 1.0.118 2024-06-15
rustcxx 1.0.119 2024-06-15
rustcxx 1.0.120 2024-06-15
rustcxx 1.0.121 2024-06-15
# We follow upstream Bitcoin Core's LevelDB updates
leveldb 1.23 2024-03-15
leveldb 1.23 2024-06-15
# We're never updating to this version
bdb 18.1.40 2025-03-01

View File

@ -16,7 +16,7 @@
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
#define CLIENT_VERSION_MAJOR 5
#define CLIENT_VERSION_MINOR 8
#define CLIENT_VERSION_MINOR 9
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 50

View File

@ -13,7 +13,7 @@
// Per https://zips.z.cash/zip-0200
// Shut down nodes running this version of code, 16 weeks' worth of blocks after the estimated
// release block height. A warning is shown during the 14 days' worth of blocks prior to shut down.
static const int APPROX_RELEASE_HEIGHT = 2353176;
static const int APPROX_RELEASE_HEIGHT = 2476976;
static const int RELEASE_TO_DEPRECATION_WEEKS = 16;
static const int EXPECTED_BLOCKS_PER_HOUR = 3600 / Consensus::POST_BLOSSOM_POW_TARGET_SPACING;
static_assert(EXPECTED_BLOCKS_PER_HOUR == 48, "The value of Consensus::POST_BLOSSOM_POW_TARGET_SPACING was chosen such that this assertion holds.");

View File

@ -325,6 +325,8 @@ TEST(ChecktransactionTests, BadTxnsTxouttotalToolargeOutputs) {
CheckTransactionWithoutProofVerification(tx, state);
}
// TODO: The new Sapling bundle API prevents us from constructing this case.
/*
TEST(ChecktransactionTests, ValueBalanceNonZero) {
CMutableTransaction mtx = GetValidTransaction(NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId);
mtx.saplingBundle = sapling::test_only_invalid_bundle(0, 0, 10);
@ -333,8 +335,9 @@ TEST(ChecktransactionTests, ValueBalanceNonZero) {
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-valuebalance-nonzero", false, "")).Times(1);
CheckTransactionWithoutProofVerification(tx, state);
EXPECT_FALSE(CheckTransactionWithoutProofVerification(tx, state));
}
*/
TEST(ChecktransactionTests, ValueBalanceOverflowsTotal) {
CMutableTransaction mtx = GetValidTransaction(NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId);
@ -1152,7 +1155,8 @@ TEST(ChecktransactionTests, HeartwoodAcceptsSaplingShieldedCoinbase) {
RegtestActivateHeartwood(false, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
auto chainparams = Params();
auto builder = sapling::new_builder(*chainparams.RustNetwork(), 10);
auto saplingAnchor = SaplingMerkleTree::empty_root().GetRawBytes();
auto builder = sapling::new_builder(*chainparams.RustNetwork(), 10, saplingAnchor, true);
builder->add_recipient(
uint256().GetRawBytes(),
libzcash::SaplingSpendingKey::random().default_address().GetRawBytes(),
@ -1167,7 +1171,7 @@ TEST(ChecktransactionTests, HeartwoodAcceptsSaplingShieldedCoinbase) {
mtx.vin.resize(1);
mtx.vin[0].prevout.SetNull();
mtx.vJoinSplit.resize(0);
mtx.saplingBundle = sapling::apply_bundle_signatures(sapling::build_bundle(std::move(builder), 10), {});
mtx.saplingBundle = sapling::apply_bundle_signatures(sapling::build_bundle(std::move(builder)), {});
auto outputs = mtx.saplingBundle.GetDetails().outputs();
auto& odesc = outputs[0];
@ -1256,10 +1260,12 @@ TEST(ChecktransactionTests, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
mtx.vin[0].prevout.SetNull();
mtx.vin[0].scriptSig << 123;
mtx.vJoinSplit.resize(0);
mtx.saplingBundle = sapling::test_only_invalid_bundle(0, 0, -1000);
mtx.saplingBundle = sapling::test_only_invalid_bundle(0, 1, -1000);
// Coinbase transaction should fail non-contextual checks with no shielded
// outputs and non-zero valueBalanceSapling.
// TODO: The new Sapling bundle API prevents us from constructing this case.
/*
{
CTransaction tx(mtx);
EXPECT_TRUE(tx.IsCoinBase());
@ -1268,15 +1274,17 @@ TEST(ChecktransactionTests, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-valuebalance-nonzero", false, "")).Times(1);
EXPECT_FALSE(CheckTransactionWithoutProofVerification(tx, state));
}
*/
// Add a Sapling output.
auto builder = sapling::new_builder(*chainparams.RustNetwork(), 10);
auto saplingAnchor = SaplingMerkleTree::empty_root().GetRawBytes();
auto builder = sapling::new_builder(*chainparams.RustNetwork(), 10, saplingAnchor, true);
builder->add_recipient(
uint256().GetRawBytes(),
libzcash::SaplingSpendingKey::random().default_address().GetRawBytes(),
1000,
libzcash::Memo::ToBytes(std::nullopt));
mtx.saplingBundle = sapling::apply_bundle_signatures(sapling::build_bundle(std::move(builder), 10), {});
mtx.saplingBundle = sapling::apply_bundle_signatures(sapling::build_bundle(std::move(builder)), {});
CTransaction tx(mtx);
EXPECT_TRUE(tx.IsCoinBase());
@ -1376,9 +1384,15 @@ TEST(ChecktransactionTests, InvalidOrchardShieldedCoinbase) {
mtx.nConsensusBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_NU5].nBranchId;
// Make it an invalid shielded coinbase, by creating an all-dummy Orchard bundle.
RawHDSeed seed(32, 0);
auto to = libzcash::OrchardSpendingKey::ForAccount(seed, 133, 0)
.ToFullViewingKey()
.GetChangeAddress();
mtx.vin.resize(1);
mtx.vin[0].prevout.SetNull();
mtx.orchardBundle = orchard::Builder(false, true, uint256())
auto builder = orchard::Builder(true, uint256());
builder.AddOutput(std::nullopt, to, 0, std::nullopt);
mtx.orchardBundle = builder
.Build().value()
.ProveAndSign({}, uint256()).value();
@ -1405,7 +1419,7 @@ TEST(ChecktransactionTests, NU5AcceptsOrchardShieldedCoinbase) {
auto chainparams = Params();
uint256 orchardAnchor;
auto builder = orchard::Builder(false, true, orchardAnchor);
auto builder = orchard::Builder(true, orchardAnchor);
// Shielded coinbase outputs must be recoverable with an all-zeroes ovk.
RawHDSeed rawSeed(32, 0);
@ -1527,7 +1541,7 @@ TEST(ChecktransactionTests, NU5EnforcesOrchardRulesOnShieldedCoinbase) {
auto chainparams = Params();
uint256 orchardAnchor;
auto builder = orchard::Builder(false, true, orchardAnchor);
auto builder = orchard::Builder(true, orchardAnchor);
// Shielded coinbase outputs must be recoverable with an all-zeroes ovk.
RawHDSeed rawSeed(32, 0);

View File

@ -448,11 +448,14 @@ public:
mutableTxV5.saplingBundle = sapling::test_only_invalid_bundle(1, 0, 0);
saplingNullifier = uint256::FromRawBytes(mutableTxV5.saplingBundle.GetDetails().spends()[0].nullifier());
// The Orchard bundle builder always pads to two Actions, so we can just
// use an empty builder to create a dummy Orchard bundle.
RawHDSeed seed(32, 0);
auto to = libzcash::OrchardSpendingKey::ForAccount(seed, 133, 0)
.ToFullViewingKey()
.GetChangeAddress();
uint256 orchardAnchor;
uint256 dataToBeSigned;
auto builder = orchard::Builder(true, true, orchardAnchor);
auto builder = orchard::Builder(false, orchardAnchor);
builder.AddOutput(std::nullopt, to, 0, std::nullopt);
mutableTxV5.orchardBundle = builder.Build().value().ProveAndSign({}, dataToBeSigned).value();
orchardNullifier = mutableTxV5.orchardBundle.GetNullifiers().at(0);

View File

@ -23,7 +23,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionTransparent)
auto scriptPubKey = GetScriptForDestination(tsk.GetPubKey().GetID());
CTxDestination taddr = tsk.GetPubKey().GetID();
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, SaplingMerkleTree::empty_root(), &keystore);
builder.SetFee(10000);
builder.AddTransparentInput(
COutPoint(uint256S("7777777777777777777777777777777777777777777777777777777777777777"), 0),
@ -64,7 +64,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionSaplingToSapling)
auto pa = extfvk.DefaultAddress();
auto testNote = GetTestSaplingNote(pa, 50000);
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.SetFee(10000);
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(fvk.ovk, pa, 5000, {});
@ -73,7 +73,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionSaplingToSapling)
// 1 vShieldedSpend + 2 vShieldedOutput
EXPECT_EQ(1, tx.GetSaplingSpendsCount());
EXPECT_EQ(2, tx.GetSaplingOutputsCount());
EXPECT_EQ(400 + 2520, RecursiveDynamicUsage(tx));
EXPECT_EQ(400 + 32 + 2520, RecursiveDynamicUsage(tx));
RegtestDeactivateSapling();
}
@ -89,7 +89,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionTransparentToSapling)
auto scriptPubKey = GetScriptForDestination(tsk.GetPubKey().GetID());
auto sk = libzcash::SaplingSpendingKey::random();
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, SaplingMerkleTree::empty_root(), &keystore);
builder.SetFee(10000);
builder.AddTransparentInput(
COutPoint(uint256S("7777777777777777777777777777777777777777777777777777777777777777"), 0),
@ -97,10 +97,10 @@ TEST(RecursiveDynamicUsageTests, TestTransactionTransparentToSapling)
builder.AddSaplingOutput(sk.full_viewing_key().ovk, sk.default_address(), 40000, {});
auto tx = builder.Build().GetTxOrThrow();
// 1 vin + 1 vShieldedOutput
// 1 vin + 2 vShieldedOutput
EXPECT_EQ(0, tx.GetSaplingSpendsCount());
EXPECT_EQ(1, tx.GetSaplingOutputsCount());
EXPECT_EQ((96 + 128) + 1200, RecursiveDynamicUsage(tx));
EXPECT_EQ(2, tx.GetSaplingOutputsCount());
EXPECT_EQ((96 + 128) + 2280, RecursiveDynamicUsage(tx));
RegtestDeactivateSapling();
}
@ -117,7 +117,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionSaplingToTransparent)
auto sk = GetTestMasterSaplingSpendingKey();
auto testNote = GetTestSaplingNote(sk.ToXFVK().DefaultAddress(), 50000);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root(), &keystore);
builder.SetFee(10000);
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddTransparentOutput(taddr, 40000);
@ -126,7 +126,7 @@ TEST(RecursiveDynamicUsageTests, TestTransactionSaplingToTransparent)
// 1 vShieldedSpend + 2 vShieldedOutput + 1 vout
EXPECT_EQ(1, tx.GetSaplingSpendsCount());
EXPECT_EQ(2, tx.GetSaplingOutputsCount());
EXPECT_EQ(400 + 2520 + 64, RecursiveDynamicUsage(tx));
EXPECT_EQ(400 + 2520 + 64 + 32, RecursiveDynamicUsage(tx));
RegtestDeactivateSapling();
}

View File

@ -20,7 +20,7 @@ TEST(Keys, EncodeAndDecodeSapling)
auto m = GetTestMasterSaplingSpendingKey();
for (uint32_t i = 0; i < 1000; i++) {
auto sk = m.Derive(i);
auto sk = m.Derive(i | HARDENED_KEY_LIMIT);
{
std::string sk_string = keyIO.EncodeSpendingKey(sk);
EXPECT_EQ(

View File

@ -124,7 +124,7 @@ TEST(MempoolLimitTests, MempoolCostAndEvictionWeight)
// Default fee
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(fvk.ovk, pa, 25000, {});
@ -135,7 +135,7 @@ TEST(MempoolLimitTests, MempoolCostAndEvictionWeight)
// Lower than standard fee
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(fvk.ovk, pa, 25000, {});
static_assert(MINIMUM_FEE == 10000);
@ -148,7 +148,7 @@ TEST(MempoolLimitTests, MempoolCostAndEvictionWeight)
// Larger Tx
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
for (int i = 0; i < 10; i++) {
builder.AddSaplingOutput(fvk.ovk, pa, 1000, {});

View File

@ -40,7 +40,7 @@ TEST(TransactionBuilder, TransparentToSapling)
// Create a shielding transaction from transparent to Sapling
// 0.00005 t-ZEC in, 0.00004 z-ZEC out, default fee
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, SaplingMerkleTree::empty_root(), &keystore);
builder.AddTransparentInput(COutPoint(uint256S("1234"), 0), scriptPubKey, 5000);
builder.AddSaplingOutput(fvk_from.ovk, pk, 4000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -49,7 +49,7 @@ TEST(TransactionBuilder, TransparentToSapling)
EXPECT_EQ(tx.vout.size(), 0);
EXPECT_EQ(tx.vJoinSplit.size(), 0);
EXPECT_EQ(tx.GetSaplingSpendsCount(), 0);
EXPECT_EQ(tx.GetSaplingOutputsCount(), 1);
EXPECT_EQ(tx.GetSaplingOutputsCount(), 2);
EXPECT_EQ(tx.GetValueBalanceSapling(), -4000);
CValidationState state;
@ -74,7 +74,7 @@ TEST(TransactionBuilder, SaplingToSapling) {
// Create a Sapling-only transaction
// 0.00004 z-ZEC in, 0.000025 z-ZEC out, default fee, 0.000005 z-ZEC change
auto builder = TransactionBuilder(Params(), 2, std::nullopt);
auto builder = TransactionBuilder(Params(), 2, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
// Check that trying to add a different anchor fails
@ -119,7 +119,7 @@ TEST(TransactionBuilder, SaplingToSprout) {
// - 0.00004 Sapling-ZEC in - 0.000025 Sprout-ZEC out
// - 0.000005 Sapling-ZEC change
// - default t-ZEC fee
auto builder = TransactionBuilder(Params(), 2, std::nullopt, nullptr);
auto builder = TransactionBuilder(Params(), 2, std::nullopt, testNote.tree.root(), nullptr);
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSproutOutput(sproutAddr, 2500, std::nullopt);
auto tx = builder.Build().GetTxOrThrow();
@ -173,7 +173,7 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) {
// - 0.00005 Sprout-ZEC change
// - 0.00005 Sapling-ZEC out
// - 0.00005 t-ZEC fee
auto builder = TransactionBuilder(Params(), 2, std::nullopt, nullptr, &view);
auto builder = TransactionBuilder(Params(), 2, std::nullopt, SaplingMerkleTree::empty_root(), nullptr, &view);
builder.SetFee(5000);
builder.AddSproutInput(sproutSk, sproutNote, sproutWitness);
builder.AddSproutOutput(sproutAddr, 6000, std::nullopt);
@ -193,7 +193,7 @@ TEST(TransactionBuilder, SproutToSproutAndSapling) {
EXPECT_EQ(tx.vJoinSplit[2].vpub_old, 0);
EXPECT_EQ(tx.vJoinSplit[2].vpub_new, 10000);
EXPECT_EQ(tx.GetSaplingSpendsCount(), 0);
EXPECT_EQ(tx.GetSaplingOutputsCount(), 1);
EXPECT_EQ(tx.GetSaplingOutputsCount(), 2);
EXPECT_EQ(tx.GetValueBalanceSapling(), -5000);
CValidationState state;
@ -247,7 +247,7 @@ TEST(TransactionBuilder, TransparentToOrchard)
// Create a shielding transaction from transparent to Orchard
// 0.00005 t-ZEC in, 0.00004 z-ZEC out, default fee
auto builder = TransactionBuilder(Params(), 1, orchardAnchor, &keystore);
auto builder = TransactionBuilder(Params(), 1, orchardAnchor, SaplingMerkleTree::empty_root(), &keystore);
builder.AddTransparentInput(COutPoint(uint256S("1234"), 0), scriptPubKey, 5000);
builder.AddOrchardOutput(std::nullopt, recipient, 4000, std::nullopt);
auto maybeTx = builder.Build();
@ -279,7 +279,7 @@ TEST(TransactionBuilder, ThrowsOnTransparentInputWithoutKeyStore)
SelectParams(CBaseChainParams::REGTEST);
const Consensus::Params& consensusParams = Params().GetConsensus();
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, SaplingMerkleTree::empty_root());
ASSERT_THROW(builder.AddTransparentInput(COutPoint(), CScript(), 1), std::runtime_error);
}
@ -290,7 +290,7 @@ TEST(TransactionBuilder, RejectsInvalidTransparentOutput)
// Default CTxDestination type is an invalid address
CTxDestination taddr;
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, SaplingMerkleTree::empty_root());
ASSERT_THROW(builder.AddTransparentOutput(taddr, 50), UniValue);
}
@ -317,13 +317,13 @@ TEST(TransactionBuilder, FailsWithNegativeChange)
// Fail if there is only a Sapling output
// 0.00005 z-ZEC out, default fee
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingOutput(fvk.ovk, pa, 5000, {});
EXPECT_EQ("Change cannot be negative: -0.00006 ZEC", builder.Build().GetError());
// Fail if there is only a transparent output
// 0.00005 t-ZEC out, default fee
builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root(), &keystore);
builder.AddTransparentOutput(taddr, 5000);
EXPECT_EQ("Change cannot be negative: -0.00006 ZEC", builder.Build().GetError());
@ -368,17 +368,18 @@ TEST(TransactionBuilder, ChangeOutput)
auto scriptPubKey = GetScriptForDestination(tkeyid);
auto fakeCoin = COutPoint(uint256S("7777777777777777777777777777777777777777777777777777777777777777"), 0);
auto saplingAnchor = SaplingMerkleTree::empty_root();
// No change address and no Sapling spends
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, saplingAnchor, &keystore);
builder.AddTransparentInput(fakeCoin, scriptPubKey, 2500);
EXPECT_EQ("Could not determine change address", builder.Build().GetError());
}
// Change to the same address as the first Sapling spend
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root(), &keystore);
builder.AddTransparentInput(fakeCoin, scriptPubKey, 2500);
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
auto tx = builder.Build().GetTxOrThrow();
@ -393,7 +394,7 @@ TEST(TransactionBuilder, ChangeOutput)
// Change to a Sapling address
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, saplingAnchor, &keystore);
builder.AddTransparentInput(fakeCoin, scriptPubKey, 2500);
builder.SendChangeTo(zChangeAddr, fvkOut.ovk);
auto tx = builder.Build().GetTxOrThrow();
@ -402,13 +403,13 @@ TEST(TransactionBuilder, ChangeOutput)
EXPECT_EQ(tx.vout.size(), 0);
EXPECT_EQ(tx.vJoinSplit.size(), 0);
EXPECT_EQ(tx.GetSaplingSpendsCount(), 0);
EXPECT_EQ(tx.GetSaplingOutputsCount(), 1);
EXPECT_EQ(tx.GetSaplingOutputsCount(), 2);
EXPECT_EQ(tx.GetValueBalanceSapling(), -1500);
}
// Change to a transparent address
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, saplingAnchor, &keystore);
builder.AddTransparentInput(fakeCoin, scriptPubKey, 2500);
builder.SendChangeTo(tkeyid, {});
auto tx = builder.Build().GetTxOrThrow();
@ -442,7 +443,7 @@ TEST(TransactionBuilder, SetFee)
// Default fee
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(fvk.ovk, pa, 25000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -458,7 +459,7 @@ TEST(TransactionBuilder, SetFee)
// Configured fee
{
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(fvk.ovk, pa, 25000, {});
builder.SetFee(20000);
@ -487,7 +488,8 @@ TEST(TransactionBuilder, CheckSaplingTxVersion)
auto pk = sk.ToXFVK().DefaultAddress();
// Cannot add Sapling outputs to a non-Sapling transaction
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
SaplingMerkleTree tree;
auto builder = TransactionBuilder(Params(), 1, std::nullopt, tree.root());
try {
builder.AddSaplingOutput(uint256(), pk, 12345, {});
} catch (std::runtime_error const & err) {
@ -498,7 +500,6 @@ TEST(TransactionBuilder, CheckSaplingTxVersion)
// Cannot add Sapling spends to a non-Sapling transaction
libzcash::SaplingNote note(pk, 50000, libzcash::Zip212Enabled::BeforeZip212);
SaplingMerkleTree tree;
try {
builder.AddSaplingSpend(sk, note, tree.witness());
} catch (std::runtime_error const & err) {

View File

@ -208,7 +208,7 @@ TEST(Validation, ContextualCheckInputsDetectsOldBranchId) {
// Create a transparent transaction that spends the coin, targeting
// a height during the Overwinter epoch.
auto builder = TransactionBuilder(params, 15, std::nullopt, &keystore);
auto builder = TransactionBuilder(params, 15, std::nullopt, SaplingMerkleTree::empty_root(), &keystore);
builder.AddTransparentInput(utxo, scriptPubKey, coinValue);
builder.AddTransparentOutput(destination, 4000);
auto tx = builder.Build().GetTxOrThrow();

View File

@ -3,7 +3,7 @@
#include <zcash/address/zip32.h>
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/sapling_zip32.py
// From https://github.com/zcash/zcash-test-vectors/blob/master/zcash_test_vectors/sapling/zip32.py
// Sapling consistently uses little-endian encoding, but uint256S takes its input in
// big-endian byte order, so the test vectors below are byte-reversed.
TEST(ZIP32, TestVectors) {
@ -35,102 +35,95 @@ TEST(ZIP32, TestVectors) {
m.ToXFVK().DefaultAddress().d,
testing::ElementsAreArray({ 0xd8, 0x62, 0x1b, 0x98, 0x1c, 0xf3, 0x00, 0xe9, 0xd4, 0xcc, 0x89 }));
auto m_1 = m.Derive(1);
EXPECT_EQ(m_1.depth, 1);
EXPECT_EQ(m_1.parentFVKTag, 0x3a71c214);
EXPECT_EQ(m_1.childIndex, 1);
auto m_1h = m.Derive(1 | HARDENED_KEY_LIMIT);
EXPECT_EQ(m_1h.depth, 1);
EXPECT_EQ(m_1h.parentFVKTag, 0x3a71c214);
EXPECT_EQ(m_1h.childIndex, 1 | HARDENED_KEY_LIMIT);
EXPECT_EQ(
m_1.chaincode,
uint256S("e6bcda05678a43fad229334ef0b795a590e7c50590baf0d9b9031a690c114701"));
m_1h.chaincode,
uint256S("dbaeca68fd2ef8b45ec23ee91bd694aa2759e010c668bb3e066b20a845aacc6f"));
EXPECT_EQ(
m_1.expsk.ask,
uint256S("0c357a2655b4b8d761794095df5cb402d3ba4a428cf6a88e7c2816a597c12b28"));
m_1h.expsk.ask,
uint256S("04bd31e1a6218db693ff0802f029043ec20f3b0b8b148cdc04be7afb2ee9f7d5"));
EXPECT_EQ(
m_1.expsk.nsk,
uint256S("01ba6bff1018fd4eac04da7e3f2c6be9c229e662c5c4d1d6fc1ecafd8829a3e7"));
m_1h.expsk.nsk,
uint256S("0a75e557f6fcbf672e0134d4ec2d51a3f358659b4b5c46f303e6cb22687c2a37"));
EXPECT_EQ(
m_1.expsk.ovk,
uint256S("7474a4c518551bd82f14a7f7365a8ffa403c50cfeffedf026ada8688fc81135f"));
m_1h.expsk.ovk,
uint256S("691c33ec470a1697ca37ceb237bb7f1691d2a833543514cf1f8c343319763025"));
EXPECT_EQ(
m_1.dk,
uint256S("dcb4c170d878510e96c4a74192d7eecde9c9912b00b99a12ec91d7a232e84de0"));
m_1h.dk,
uint256S("26d53444cbe2e9929f619d810a0d05ae0deece0a72c3a7e3df9a5fd60f4088f2"));
EXPECT_THAT(
m_1.ToXFVK().DefaultAddress().d,
testing::ElementsAreArray({ 0x8b, 0x41, 0x38, 0x32, 0x0d, 0xfa, 0xfd, 0x7b, 0x39, 0x97, 0x81 }));
m_1h.ToXFVK().DefaultAddress().d,
testing::ElementsAreArray({ 0xbc, 0xc3, 0x23, 0xe8, 0xda, 0x39, 0xb4, 0x96, 0xc0, 0x50, 0x51 }));
auto m_1_2h = m_1.Derive(2 | HARDENED_KEY_LIMIT);
EXPECT_EQ(m_1_2h.depth, 2);
EXPECT_EQ(m_1_2h.parentFVKTag, 0x079e99db);
EXPECT_EQ(m_1_2h.childIndex, 2 | HARDENED_KEY_LIMIT);
auto m_1h_2h = m_1h.Derive(2 | HARDENED_KEY_LIMIT);
EXPECT_EQ(m_1h_2h.depth, 2);
EXPECT_EQ(m_1h_2h.parentFVKTag, 0xcb238476);
EXPECT_EQ(m_1h_2h.childIndex, 2 | HARDENED_KEY_LIMIT);
EXPECT_EQ(
m_1_2h.chaincode,
uint256S("35d4a883737742ca41a4baa92323bdb3c93dcb3b462a26b039971bedf415ce97"));
m_1h_2h.chaincode,
uint256S("daf7be6f80503ab34f14f236da9de2cf540ae3c100f520607980d0756c087944"));
EXPECT_EQ(
m_1_2h.expsk.ask,
uint256S("0dc6e4fe846bda925c82e632980434e17b51dac81fc4821fa71334ee3c11e88b"));
m_1h_2h.expsk.ask,
uint256S("06512f33a6f9ae4b42fd71f9cfa08d3727522dd3089cad596fc3139eb65df37f"));
EXPECT_EQ(
m_1_2h.expsk.nsk,
uint256S("0c99a63a275c1c66734761cfb9c62fe9bd1b953f579123d3d0e769c59d057837"));
m_1h_2h.expsk.nsk,
uint256S("00debf5999f564a3e05a0d418cf40714399a32c1bdc98ba2eb4439a0e46e9c77"));
EXPECT_EQ(
m_1_2h.expsk.ovk,
uint256S("bc1328fc5eb693e18875c5149d06953b11d39447ebd6e38c023c22962e1881cf"));
m_1h_2h.expsk.ovk,
uint256S("ac85619305763dc29b67b75e305e5323bda7d6a530736a88417f90bf0171fcd9"));
EXPECT_EQ(
m_1_2h.dk,
uint256S("377bb062dce7e0dcd8a0054d0ca4b4d1481b3710bfa1df12ca46ff9e9fa1eda3"));
m_1h_2h.dk,
uint256S("d148325ff6faa682558de97a9fec61dd8dc10a96d0cd214bc531e0869a9e69e4"));
EXPECT_THAT(
m_1_2h.ToXFVK().DefaultAddress().d,
testing::ElementsAreArray({ 0xe8, 0xd0, 0x37, 0x93, 0xcd, 0xd2, 0xba, 0xcc, 0x9c, 0x70, 0x41 }));
m_1h_2h.ToXFVK().DefaultAddress().d,
testing::ElementsAreArray({ 0x98, 0x82, 0x40, 0xce, 0xa4, 0xdb, 0xc3, 0x0a, 0x73, 0x75, 0x50 }));
auto m_1_2hv = m_1_2h.ToXFVK();
auto m_1_2hv = m_1h_2h.ToXFVK();
EXPECT_EQ(m_1_2hv.depth, 2);
EXPECT_EQ(m_1_2hv.parentFVKTag, 0x079e99db);
EXPECT_EQ(m_1_2hv.parentFVKTag, 0xcb238476);
EXPECT_EQ(m_1_2hv.childIndex, 2 | HARDENED_KEY_LIMIT);
EXPECT_EQ(
m_1_2hv.chaincode,
uint256S("35d4a883737742ca41a4baa92323bdb3c93dcb3b462a26b039971bedf415ce97"));
uint256S("daf7be6f80503ab34f14f236da9de2cf540ae3c100f520607980d0756c087944"));
EXPECT_EQ(
m_1_2hv.fvk.ak,
uint256S("4138cffdf7200e52d4e9f4384481b4a4c4d070493a5e401e4ffa850f5a92c5a6"));
uint256S("4eab7275725c76ee4247ae8d941d4b53682e39da641785e097377144953f859a"));
EXPECT_EQ(
m_1_2hv.fvk.nk,
uint256S("11eee22577304f660cc036bc84b3fc88d1ec50ae8a4d657beb6b211659304e30"));
uint256S("be4f5d4f36018511d23a1b9a9c87af8c6dbd20212da84121c1ce884f8aa266f1"));
EXPECT_EQ(
m_1_2hv.fvk.ovk,
uint256S("bc1328fc5eb693e18875c5149d06953b11d39447ebd6e38c023c22962e1881cf"));
uint256S("ac85619305763dc29b67b75e305e5323bda7d6a530736a88417f90bf0171fcd9"));
EXPECT_EQ(
m_1_2hv.dk,
uint256S("377bb062dce7e0dcd8a0054d0ca4b4d1481b3710bfa1df12ca46ff9e9fa1eda3"));
EXPECT_EQ(m_1_2hv.DefaultAddress(), m_1_2h.ToXFVK().DefaultAddress());
uint256S("d148325ff6faa682558de97a9fec61dd8dc10a96d0cd214bc531e0869a9e69e4"));
EXPECT_EQ(m_1_2hv.DefaultAddress(), m_1h_2h.ToXFVK().DefaultAddress());
// Hardened derivation from an xfvk fails
EXPECT_FALSE(m_1_2hv.Derive(3 | HARDENED_KEY_LIMIT));
// Non-hardened derivation succeeds
auto maybe_m_1_2hv_3 = m_1_2hv.Derive(3);
EXPECT_TRUE(maybe_m_1_2hv_3);
auto m_1_2hv_3 = maybe_m_1_2hv_3.value();
EXPECT_EQ(m_1_2hv_3.depth, 3);
EXPECT_EQ(m_1_2hv_3.parentFVKTag, 0x7583c148);
EXPECT_EQ(m_1_2hv_3.childIndex, 3);
auto m_1h_2h_3h = m_1h_2h.Derive(3 | HARDENED_KEY_LIMIT);
EXPECT_EQ(m_1h_2h_3h.depth, 3);
EXPECT_EQ(m_1h_2h_3h.parentFVKTag, 0x2b2ddc0b);
EXPECT_EQ(m_1h_2h_3h.childIndex, 3 | HARDENED_KEY_LIMIT);
EXPECT_EQ(
m_1_2hv_3.chaincode,
uint256S("e8e7d6a74a5a1c05be41baec7998d91f7b3603a4c0af495b0d43ba81cf7b938d"));
m_1h_2h_3h.chaincode,
uint256S("4bc7bd5b38fcbdb259be013bef298c8de263e4c32ccb2bcdd2ce90762d01dc33"));
EXPECT_EQ(
m_1_2hv_3.fvk.ak,
uint256S("a3a697bdda9d648d32a97553de4754b2fac866d726d3f2c436259c507bc585b1"));
m_1h_2h_3h.expsk.ask,
uint256S("07afec4df829ace083d68145103c50692f331c4690cf52f13759e3214dd29345"));
EXPECT_EQ(
m_1_2hv_3.fvk.nk,
uint256S("4f66c0814b769963f3bf1bc001270b50edabb27de042fc8a5607d2029e0488db"));
m_1h_2h_3h.expsk.nsk,
uint256S("0bbba7ff6efab6fbabb5b727ed3d55e40efa0de858f8c0e357503f12c27ec81a"));
EXPECT_EQ(
m_1_2hv_3.fvk.ovk,
uint256S("f61a699934dc78441324ef628b4b4721611571e8ee3bd591eb3d4b1cfae0b969"));
m_1h_2h_3h.expsk.ovk,
uint256S("e39e4b1b9c5c1b31988beffb515522a95de718afa880e36c9d2ebef20cea361e"));
EXPECT_EQ(
m_1_2hv_3.dk,
uint256S("6ee53b1261f2c9c0f7359ab236f87b52a0f1b0ce43305cdad92ebb63c350cbbe"));
m_1h_2h_3h.dk,
uint256S("6abb7b109c7270edaa3a36dc140d3f70bf8cd271b69d606f5aadf3a4596cfc57"));
EXPECT_THAT(
m_1_2hv_3.DefaultAddress().d,
testing::ElementsAreArray({ 0x03, 0x0f, 0xfb, 0x26, 0x3a, 0x93, 0x9e, 0x23, 0x0e, 0x96, 0xdd }));
m_1h_2h_3h.ToXFVK().DefaultAddress().d,
testing::ElementsAreArray({ 0x5a, 0x75, 0xbe, 0x14, 0x00, 0x53, 0x0b, 0x4b, 0x7a, 0xdd, 0x52 }));
}
TEST(ZIP32, ParseHDKeypathAccount) {

View File

@ -79,9 +79,15 @@ template<> void AppendRandomLeaf(OrchardMerkleFrontier &tree) {
// fortunately the tests only require that the tree root change.
// TODO: Remove the need to create proofs by having a testing-only way to
// append a random leaf to OrchardMerkleFrontier.
RawHDSeed seed(32, 0);
auto to = libzcash::OrchardSpendingKey::ForAccount(seed, 133, 0)
.ToFullViewingKey()
.GetChangeAddress();
uint256 orchardAnchor;
uint256 dataToBeSigned;
auto builder = orchard::Builder(true, true, orchardAnchor);
// TODO: Create bundle.
auto builder = orchard::Builder(false, orchardAnchor);
builder.AddOutput(std::nullopt, to, 0, std::nullopt);
auto bundle = builder.Build().value().ProveAndSign({}, dataToBeSigned).value();
tree.AppendBundle(bundle);
}

View File

@ -173,7 +173,7 @@ public:
void ComputeBindingSig(rust::Box<sapling::Builder> saplingBuilder, std::optional<orchard::UnauthorizedBundle> orchardBundle) const {
auto consensusBranchId = CurrentEpochBranchId(nHeight, chainparams.GetConsensus());
auto saplingBundle = sapling::build_bundle(std::move(saplingBuilder), nHeight);
auto saplingBundle = sapling::build_bundle(std::move(saplingBuilder));
// Empty output script.
uint256 dataToBeSigned;
@ -213,13 +213,14 @@ public:
// Create Orchard output
void operator()(const libzcash::OrchardRawAddress &to) const {
auto saplingBuilder = sapling::new_builder(*chainparams.RustNetwork(), nHeight);
std::array<uint8_t, 32> saplingAnchor;
auto saplingBuilder = sapling::new_builder(*chainparams.RustNetwork(), nHeight, saplingAnchor, true);
// `enableSpends` must be set to `false` for coinbase transactions. This
// means the Orchard anchor is unconstrained, so we set it to the empty
// tree root via a null (all zeroes) uint256.
uint256 orchardAnchor;
auto builder = orchard::Builder(false, true, orchardAnchor);
auto builder = orchard::Builder(true, orchardAnchor);
// Shielded coinbase outputs must be recoverable with an all-zeroes ovk.
uint256 ovk;
@ -249,7 +250,8 @@ public:
// Create Sapling output
void operator()(const libzcash::SaplingPaymentAddress &pa) const {
auto saplingBuilder = sapling::new_builder(*chainparams.RustNetwork(), nHeight);
std::array<uint8_t, 32> saplingAnchor;
auto saplingBuilder = sapling::new_builder(*chainparams.RustNetwork(), nHeight, saplingAnchor, true);
auto miner_reward = SetFoundersRewardAndGetMinerValue(*saplingBuilder);
@ -265,7 +267,8 @@ public:
// Create transparent output
void operator()(const boost::shared_ptr<CReserveScript> &coinbaseScript) const {
// Add the FR output and fetch the miner's output value.
auto saplingBuilder = sapling::new_builder(*chainparams.RustNetwork(), nHeight);
std::array<uint8_t, 32> saplingAnchor;
auto saplingBuilder = sapling::new_builder(*chainparams.RustNetwork(), nHeight, saplingAnchor, true);
// Miner output will be vout[0]; Founders' Reward & funding stream outputs
// will follow.

View File

@ -9,7 +9,7 @@ use serde::{
use zcash_primitives::{
consensus::Network,
legacy::Script,
transaction::components::{transparent, Amount, TxOut},
transaction::components::{amount::NonNegativeAmount, transparent, TxOut},
zip32::AccountId,
};
@ -67,7 +67,9 @@ impl<'de> Visitor<'de> for JsonAccountIdVisitor {
{
u32::try_from(v)
.map_err(|_| E::custom(format!("u32 out of range: {}", v)))
.map(AccountId::from)
.and_then(|a| {
AccountId::try_from(a).map_err(|e| E::custom(format!("AccountId invalid: {}", e)))
})
.map(JsonAccountId)
}
@ -77,7 +79,9 @@ impl<'de> Visitor<'de> for JsonAccountIdVisitor {
{
u32::try_from(v)
.map_err(|_| E::custom(format!("u32 out of range: {}", v)))
.map(AccountId::from)
.and_then(|a| {
AccountId::try_from(a).map_err(|e| E::custom(format!("AccountId invalid: {}", e)))
})
.map(JsonAccountId)
}
@ -87,7 +91,9 @@ impl<'de> Visitor<'de> for JsonAccountIdVisitor {
{
u32::try_from(v)
.map_err(|_| E::custom(format!("u32 out of range: {}", v)))
.map(AccountId::from)
.and_then(|a| {
AccountId::try_from(a).map_err(|e| E::custom(format!("AccountId invalid: {}", e)))
})
.map(JsonAccountId)
}
@ -97,7 +103,9 @@ impl<'de> Visitor<'de> for JsonAccountIdVisitor {
{
u32::try_from(v)
.map_err(|_| E::custom(format!("u32 out of range: {}", v)))
.map(AccountId::from)
.and_then(|a| {
AccountId::try_from(a).map_err(|e| E::custom(format!("AccountId invalid: {}", e)))
})
.map(JsonAccountId)
}
}
@ -162,7 +170,7 @@ impl fmt::Display for ZUint256 {
}
#[derive(Clone, Debug)]
struct ZOutputValue(Amount);
struct ZOutputValue(NonNegativeAmount);
struct ZOutputValueVisitor;
@ -177,9 +185,11 @@ impl<'de> Visitor<'de> for ZOutputValueVisitor {
where
E: serde::de::Error,
{
Amount::from_u64(v).map(ZOutputValue).map_err(|()| {
serde::de::Error::invalid_type(Unexpected::Unsigned(v), &"a valid zatoshi amount")
})
NonNegativeAmount::from_u64(v)
.map(ZOutputValue)
.map_err(|()| {
serde::de::Error::invalid_type(Unexpected::Unsigned(v), &"a valid zatoshi amount")
})
}
}

View File

@ -36,7 +36,7 @@ pub(crate) fn inspect_mnemonic(
let orchard_fvk = match orchard::keys::SpendingKey::from_zip32_seed(
&seed,
network.coin_type(),
account.into(),
account,
) {
Ok(sk) => Some(orchard::keys::FullViewingKey::from(&sk)),
Err(e) => {
@ -49,13 +49,13 @@ pub(crate) fn inspect_mnemonic(
};
eprintln!(" - Sapling:");
let sapling_master = zip32::ExtendedSpendingKey::master(&seed);
let sapling_extsk = zip32::ExtendedSpendingKey::from_path(
let sapling_master = sapling::zip32::ExtendedSpendingKey::master(&seed);
let sapling_extsk = sapling::zip32::ExtendedSpendingKey::from_path(
&sapling_master,
&[
zip32::ChildIndex::Hardened(32),
zip32::ChildIndex::Hardened(network.coin_type()),
zip32::ChildIndex::Hardened(account.into()),
zip32::ChildIndex::hardened(32),
zip32::ChildIndex::hardened(network.coin_type()),
account.into(),
],
);
#[allow(deprecated)]
@ -106,8 +106,8 @@ pub(crate) fn inspect_mnemonic(
Ok(addr) => eprintln!(
" - Default address: {}",
match addr {
TransparentAddress::PublicKey(data) => ZcashAddress::from_transparent_p2pkh(addr_net, data),
TransparentAddress::Script(_) => unreachable!(),
TransparentAddress::PublicKeyHash(data) => ZcashAddress::from_transparent_p2pkh(addr_net, data),
TransparentAddress::ScriptHash(_) => unreachable!(),
}.encode(),
),
Err(e) => eprintln!(

View File

@ -98,8 +98,9 @@ fn inspect_bytes(bytes: Vec<u8>, context: Option<Context>) {
block::inspect(&block, context);
} else if let Some(header) = complete(&bytes, |r| BlockHeader::read(r)) {
block::inspect_header(&header, context);
} else if let Some(tx) = complete(&bytes, |r| Transaction::read(r, BranchId::Sprout)) {
} else if let Some(tx) = complete(&bytes, |r| Transaction::read(r, BranchId::Nu5)) {
// TODO: Take the branch ID used above from the context if present.
// https://github.com/zcash/zcash/issues/6831
transaction::inspect(tx, context);
} else {
// It's not a known variable-length format. check fixed-length data formats.

View File

@ -6,6 +6,7 @@ use std::{
use bellman::groth16;
use group::GroupEncoding;
use orchard::note_encryption::OrchardDomain;
use sapling::{note_encryption::SaplingDomain, SaplingVerificationContext};
use secp256k1::{Secp256k1, VerifyOnly};
use zcash_address::{
unified::{self, Encoding},
@ -14,18 +15,16 @@ use zcash_address::{
use zcash_note_encryption::try_output_recovery_with_ovk;
#[allow(deprecated)]
use zcash_primitives::{
consensus::BlockHeight,
consensus::{sapling_zip212_enforcement, BlockHeight},
legacy::{keys::pubkey_to_address, Script, TransparentAddress},
memo::{Memo, MemoBytes},
sapling::note_encryption::SaplingDomain,
transaction::{
components::{sapling, transparent, Amount},
components::{amount::NonNegativeAmount, transparent},
sighash::{signature_hash, SignableInput, TransparentAuthorizingContext},
txid::TxIdDigester,
Authorization, Transaction, TransactionData, TxId, TxVersion,
},
};
use zcash_proofs::sapling::SaplingVerificationContext;
use crate::{
context::{Context, ZTxOut},
@ -106,7 +105,7 @@ impl transparent::Authorization for TransparentAuth {
}
impl TransparentAuthorizingContext for TransparentAuth {
fn input_amounts(&self) -> Vec<Amount> {
fn input_amounts(&self) -> Vec<NonNegativeAmount> {
self.all_prev_outputs
.iter()
.map(|prevout| prevout.value)
@ -143,7 +142,7 @@ pub(crate) struct PrecomputedAuth;
impl Authorization for PrecomputedAuth {
type TransparentAuth = TransparentAuth;
type SaplingAuth = sapling::Authorized;
type SaplingAuth = sapling::bundle::Authorized;
type OrchardAuth = orchard::bundle::Authorized;
}
@ -231,7 +230,7 @@ pub(crate) fn inspect(tx: Transaction, context: Option<Context>) {
txin.prevout.n()
);
match coin.recipient_address() {
Some(addr @ TransparentAddress::PublicKey(_)) => {
Some(addr @ TransparentAddress::PublicKeyHash(_)) => {
// Format is [sig_and_type_len] || sig || [hash_type] || [pubkey_len] || pubkey
// where [x] encodes a single byte.
let sig_and_type_len = txin.script_sig.0.first().map(|l| *l as usize);
@ -311,7 +310,7 @@ pub(crate) fn inspect(tx: Transaction, context: Option<Context>) {
}
}
// TODO: Check P2SH structure.
Some(TransparentAddress::Script(_)) => {
Some(TransparentAddress::ScriptHash(_)) => {
eprintln!(" 🔎 \"transparentcoins\"[{}] is a P2SH coin.", i);
}
// TODO: Check arbitrary scripts.
@ -376,7 +375,7 @@ pub(crate) fn inspect(tx: Transaction, context: Option<Context>) {
assert!(!(bundle.shielded_spends().is_empty() && bundle.shielded_outputs().is_empty()));
// TODO: Separate into checking proofs, signatures, and other structural details.
let mut ctx = SaplingVerificationContext::new(true);
let mut ctx = SaplingVerificationContext::new();
if !bundle.shielded_spends().is_empty() {
eprintln!(" - {} Sapling Spend(s)", bundle.shielded_spends().len());
@ -386,7 +385,7 @@ pub(crate) fn inspect(tx: Transaction, context: Option<Context>) {
spend.cv(),
*spend.anchor(),
&spend.nullifier().0,
spend.rk().clone(),
*spend.rk(),
sighash.as_ref(),
*spend.spend_auth_sig(),
groth16::Proof::read(&spend.zkproof()[..]).unwrap(),
@ -411,8 +410,11 @@ pub(crate) fn inspect(tx: Transaction, context: Option<Context>) {
.and_then(|ctx| ctx.network().zip(ctx.addr_network()))
{
if let Some((note, addr, memo)) = try_output_recovery_with_ovk(
&SaplingDomain::for_height(params, height.unwrap()),
&zcash_primitives::keys::OutgoingViewingKey([0; 32]),
&SaplingDomain::new(sapling_zip212_enforcement(
&params,
height.unwrap(),
)),
&sapling::keys::OutgoingViewingKey([0; 32]),
output,
output.cv(),
output.out_ciphertext(),
@ -426,6 +428,7 @@ pub(crate) fn inspect(tx: Transaction, context: Option<Context>) {
eprintln!(" - {}", zaddr);
eprintln!(" - {}", render_value(note.value().inner()));
}
let memo = MemoBytes::from_bytes(&memo).expect("correct length");
eprintln!(" - {}", render_memo(memo));
} else {
eprintln!(

View File

@ -35,8 +35,7 @@ void orchard_spend_info_free(OrchardSpendInfoPtr* ptr);
///
/// If `anchor` is `null`, the root of the empty Orchard commitment tree is used.
OrchardBuilderPtr* orchard_builder_new(
bool spends_enabled,
bool outputs_enabled,
bool coinbase,
const unsigned char* anchor);
/// Frees an Orchard builder returned from `orchard_builder_new`.

View File

@ -9,7 +9,6 @@ use zcash_address::{
unified::{self, Container, Encoding},
Network, ToAddress, TryFromAddress, ZcashAddress,
};
use zcash_primitives::sapling;
pub type UnifiedAddressObj = NonNull<c_void>;
pub type AddOrchardReceiverCb =

View File

@ -185,11 +185,15 @@ pub(crate) mod ffi {
type SaplingBuilder;
#[cxx_name = "new_builder"]
fn new_sapling_builder(network: &Network, height: u32) -> Box<SaplingBuilder>;
fn new_sapling_builder(
network: &Network,
height: u32,
anchor: [u8; 32],
coinbase: bool,
) -> Result<Box<SaplingBuilder>>;
fn add_spend(
self: &mut SaplingBuilder,
extsk: &[u8],
diversifier: [u8; 11],
recipient: [u8; 43],
value: u64,
rcm: [u8; 32],
@ -205,7 +209,6 @@ pub(crate) mod ffi {
#[cxx_name = "build_bundle"]
fn build_sapling_bundle(
builder: Box<SaplingBuilder>,
target_height: u32,
) -> Result<Box<SaplingUnauthorizedBundle>>;
#[cxx_name = "UnauthorizedBundle"]

View File

@ -6,8 +6,8 @@ use incrementalmerkletree::Hashable;
use libc::size_t;
use orchard::keys::SpendingKey;
use orchard::{
builder::{Builder, InProgress, Unauthorized, Unproven},
bundle::{Authorized, Flags},
builder::{Builder, BundleType, InProgress, Unauthorized, Unproven},
bundle::Authorized,
keys::{FullViewingKey, OutgoingViewingKey},
tree::{MerkleHashOrchard, MerklePath},
value::NoteValue,
@ -18,7 +18,7 @@ use tracing::error;
use zcash_primitives::{
consensus::BranchId,
transaction::{
components::{sapling, Amount},
components::Amount,
sighash::{signature_hash, SignableInput},
txid::TxIdDigester,
Authorization, Transaction, TransactionData,
@ -55,18 +55,16 @@ pub extern "C" fn orchard_spend_info_free(spend_info: *mut OrchardSpendInfo) {
}
#[no_mangle]
pub extern "C" fn orchard_builder_new(
spends_enabled: bool,
outputs_enabled: bool,
anchor: *const [u8; 32],
) -> *mut Builder {
pub extern "C" fn orchard_builder_new(coinbase: bool, anchor: *const [u8; 32]) -> *mut Builder {
let bundle_type = if coinbase {
BundleType::Coinbase
} else {
BundleType::DEFAULT
};
let anchor = unsafe { anchor.as_ref() }
.map(|a| orchard::Anchor::from_bytes(*a).unwrap())
.unwrap_or_else(|| MerkleHashOrchard::empty_root(32.into()).into());
Box::into_raw(Box::new(Builder::new(
Flags::from_parts(spends_enabled, outputs_enabled),
anchor,
)))
Box::into_raw(Box::new(Builder::new(bundle_type, anchor)))
}
#[no_mangle]
@ -106,7 +104,7 @@ pub extern "C" fn orchard_builder_add_recipient(
let value = NoteValue::from_raw(value);
let memo = unsafe { memo.as_ref() }.copied();
match builder.add_recipient(ovk, *recipient, value, memo) {
match builder.add_output(ovk, *recipient, value, memo) {
Ok(()) => true,
Err(e) => {
error!("Failed to add Orchard recipient: {}", e);
@ -132,8 +130,15 @@ pub extern "C" fn orchard_builder_build(
}
let builder = unsafe { Box::from_raw(builder) };
match builder.build(OsRng) {
Ok(bundle) => Box::into_raw(Box::new(bundle)),
match builder.build::<Amount>(OsRng) {
Ok(Some((bundle, _))) => Box::into_raw(Box::new(bundle)),
Ok(None) => {
// The C++ side only calls `orchard_builder_build` when it expects the
// resulting bundle to be non-empty (either at least one Orchard output for
// coinbase transactions, or a potentially-empty bundle that gets padded).
error!("Tried to build empty Orchard bundle");
ptr::null_mut()
}
Err(e) => {
error!("Failed to build Orchard bundle: {:?}", e);
ptr::null_mut()
@ -232,7 +237,8 @@ pub(crate) fn shielded_signature_digest(
struct Signable {}
impl Authorization for Signable {
type TransparentAuth = TransparentAuth;
type SaplingAuth = sapling::builder::Unauthorized;
type SaplingAuth =
sapling::builder::InProgress<sapling::builder::Proven, sapling::builder::Unsigned>;
type OrchardAuth = InProgress<Unproven, Unauthorized>;
}

View File

@ -5,12 +5,9 @@ use std::io::{self, Read, Write};
use bridgetree::{BridgeTree, Checkpoint, MerkleBridge};
use incrementalmerkletree::{Address, Hashable, Level, Position};
use zcash_encoding::{Optional, Vector};
use zcash_primitives::{
merkle_tree::{
read_address, read_leu64_usize, read_nonempty_frontier_v1, read_position, write_address,
write_nonempty_frontier_v1, write_position, write_usize_leu64, HashSer,
},
sapling::NOTE_COMMITMENT_TREE_DEPTH,
use zcash_primitives::merkle_tree::{
read_address, read_leu64_usize, read_nonempty_frontier_v1, read_position, write_address,
write_nonempty_frontier_v1, write_position, write_usize_leu64, HashSer,
};
pub const SER_V1: u8 = 1;
@ -252,9 +249,9 @@ pub fn write_checkpoint_v3<W: Write>(
/// ids should always be treated as opaque, totally ordered identifiers without additional
/// semantics.
#[allow(clippy::redundant_closure)]
pub fn read_tree<H: Hashable + HashSer + Ord + Clone, R: Read>(
pub fn read_tree<H: Hashable + HashSer + Ord + Clone, const DEPTH: u8, R: Read>(
mut reader: R,
) -> io::Result<BridgeTree<H, u32, NOTE_COMMITMENT_TREE_DEPTH>> {
) -> io::Result<BridgeTree<H, u32, DEPTH>> {
let tree_version = reader.read_u8()?;
let prior_bridges = Vector::read(&mut reader, |r| read_bridge(r, tree_version))?;
let current_bridge = Optional::read(&mut reader, |r| read_bridge(r, tree_version))?;
@ -309,9 +306,9 @@ pub fn read_tree<H: Hashable + HashSer + Ord + Clone, R: Read>(
})
}
pub fn write_tree<H: Hashable + HashSer + Ord, W: Write>(
pub fn write_tree<H: Hashable + HashSer + Ord, const DEPTH: u8, W: Write>(
mut writer: W,
tree: &BridgeTree<H, u32, NOTE_COMMITMENT_TREE_DEPTH>,
tree: &BridgeTree<H, u32, DEPTH>,
) -> io::Result<()> {
writer.write_u8(SER_V3)?;
Vector::write(&mut writer, tree.prior_bridges(), |w, b| write_bridge(w, b))?;

View File

@ -2,8 +2,8 @@ use std::ffi::OsString;
use std::path::PathBuf;
use std::sync::Once;
use bellman::groth16::Parameters;
use bls12_381::Bls12;
use sapling::circuit::{OutputParameters, SpendParameters};
use tracing::info;
use crate::{
@ -51,17 +51,18 @@ fn zksnark_params(sprout_path: String, load_proving_keys: bool) {
// Load params
let (sapling_spend_params, sapling_output_params) = {
let (spend_buf, output_buf) = wagyu_zcash_parameters::load_sapling_parameters();
let spend_params = Parameters::<Bls12>::read(&spend_buf[..], false)
.expect("couldn't deserialize Sapling spend parameters");
let output_params = Parameters::<Bls12>::read(&output_buf[..], false)
.expect("couldn't deserialize Sapling spend parameters");
(spend_params, output_params)
(
SpendParameters::read(&spend_buf[..], false)
.expect("Failed to read Sapling Spend parameters"),
OutputParameters::read(&output_buf[..], false)
.expect("Failed to read Sapling Output parameters"),
)
};
// We need to clone these because we aren't necessarily storing the proving
// parameters in memory.
let sapling_spend_vk = sapling_spend_params.vk.clone();
let sapling_output_vk = sapling_output_params.vk.clone();
let sapling_spend_vk = sapling_spend_params.verifying_key();
let sapling_output_vk = sapling_output_params.verifying_key();
// Generate Orchard parameters.
info!(target: "main", "Loading Orchard parameters");

View File

@ -19,7 +19,10 @@
// See https://github.com/rust-lang/rfcs/pull/2585 for more background.
#![allow(clippy::not_unsafe_ptr_arg_deref)]
use bellman::groth16::{self, Parameters, PreparedVerifyingKey};
use ::sapling::circuit::{
OutputParameters, OutputVerifyingKey, SpendParameters, SpendVerifyingKey,
};
use bellman::groth16::PreparedVerifyingKey;
use bls12_381::Bls12;
use std::path::PathBuf;
use subtle::CtOption;
@ -61,12 +64,12 @@ mod test_harness_ffi;
#[cfg(test)]
mod tests;
static mut SAPLING_SPEND_VK: Option<groth16::VerifyingKey<Bls12>> = None;
static mut SAPLING_OUTPUT_VK: Option<groth16::VerifyingKey<Bls12>> = None;
static mut SAPLING_SPEND_VK: Option<SpendVerifyingKey> = None;
static mut SAPLING_OUTPUT_VK: Option<OutputVerifyingKey> = None;
static mut SPROUT_GROTH16_VK: Option<PreparedVerifyingKey<Bls12>> = None;
static mut SAPLING_SPEND_PARAMS: Option<Parameters<Bls12>> = None;
static mut SAPLING_OUTPUT_PARAMS: Option<Parameters<Bls12>> = None;
static mut SAPLING_SPEND_PARAMS: Option<SpendParameters> = None;
static mut SAPLING_OUTPUT_PARAMS: Option<OutputParameters> = None;
static mut SPROUT_GROTH16_PARAMS_PATH: Option<PathBuf> = None;
static mut ORCHARD_PK: Option<orchard::circuit::ProvingKey> = None;

View File

@ -5,9 +5,9 @@ use incrementalmerkletree::{
Hashable, Level,
};
use orchard::tree::MerkleHashOrchard;
use zcash_primitives::{
merkle_tree::{read_frontier_v1, write_commitment_tree, write_frontier_v1, HashSer},
sapling::NOTE_COMMITMENT_TREE_DEPTH,
use sapling::NOTE_COMMITMENT_TREE_DEPTH;
use zcash_primitives::merkle_tree::{
read_frontier_v1, write_commitment_tree, write_frontier_v1, HashSer,
};
use crate::{bridge::ffi, orchard_bundle, streams::CppStream, wallet::Wallet};

View File

@ -1,19 +1,15 @@
use std::convert::TryInto;
use sapling::{
keys::OutgoingViewingKey,
note_encryption::{PreparedIncomingViewingKey, SaplingDomain},
value::ValueCommitment,
SaplingIvk,
};
use zcash_note_encryption::{
try_output_recovery_with_ovk, Domain, EphemeralKeyBytes, ShieldedOutput, ENC_CIPHERTEXT_SIZE,
};
use zcash_primitives::{
consensus::BlockHeight,
keys::OutgoingViewingKey,
memo::MemoBytes,
sapling::{
self,
note_encryption::{PreparedIncomingViewingKey, SaplingDomain},
value::ValueCommitment,
SaplingIvk,
},
};
use zcash_primitives::consensus::{sapling_zip212_enforcement, BlockHeight};
use crate::{bridge::ffi::SaplingShieldedOutput, params::Network};
@ -35,10 +31,9 @@ pub(crate) fn try_sapling_note_decryption(
.ok_or("Invalid Sapling ivk passed to wallet::try_sapling_note_decryption()")?;
let (note, recipient, memo) = sapling::note_encryption::try_sapling_note_decryption(
network,
BlockHeight::from_u32(height),
&ivk,
&output,
sapling_zip212_enforcement(network, BlockHeight::from_u32(height)),
)
.ok_or("Decryption failed")?;
@ -64,7 +59,10 @@ pub(crate) fn try_sapling_output_recovery(
ovk: [u8; 32],
output: SaplingShieldedOutput,
) -> Result<Box<DecryptedSaplingOutput>, &'static str> {
let domain = SaplingDomain::for_height(*network, BlockHeight::from_u32(height));
let domain = SaplingDomain::new(sapling_zip212_enforcement(
network,
BlockHeight::from_u32(height),
));
let cv = Option::from(ValueCommitment::from_bytes_not_small_order(&output.cv))
.ok_or("Invalid output.cv passed to wallet::try_sapling_note_decryption()")?;
@ -94,12 +92,12 @@ pub(crate) fn parse_and_prepare_sapling_ivk(
.into()
}
impl ShieldedOutput<SaplingDomain<Network>, ENC_CIPHERTEXT_SIZE> for SaplingShieldedOutput {
impl ShieldedOutput<SaplingDomain, ENC_CIPHERTEXT_SIZE> for SaplingShieldedOutput {
fn ephemeral_key(&self) -> EphemeralKeyBytes {
EphemeralKeyBytes(self.ephemeral_key)
}
fn cmstar_bytes(&self) -> <SaplingDomain<Network> as Domain>::ExtractedCommitmentBytes {
fn cmstar_bytes(&self) -> <SaplingDomain as Domain>::ExtractedCommitmentBytes {
self.cmu
}
@ -112,7 +110,7 @@ impl ShieldedOutput<SaplingDomain<Network>, ENC_CIPHERTEXT_SIZE> for SaplingShie
pub(crate) struct DecryptedSaplingOutput {
note: sapling::Note,
recipient: sapling::PaymentAddress,
memo: MemoBytes,
memo: [u8; 512],
}
impl DecryptedSaplingOutput {
@ -140,6 +138,6 @@ impl DecryptedSaplingOutput {
}
pub(crate) fn memo(&self) -> [u8; 512] {
*self.memo.as_array()
self.memo
}
}

View File

@ -1,3 +1,4 @@
use std::convert::TryInto;
use std::io::{Read, Write};
use std::slice;
use tracing::error;
@ -160,7 +161,7 @@ pub extern "C" fn orchard_incoming_viewing_key_decrypt_diversifier(
match key.diversifier_index(addr) {
Some(j) => {
j_ret.copy_from_slice(j.to_bytes());
j_ret.copy_from_slice(j.as_bytes());
true
}
None => false,
@ -327,7 +328,8 @@ pub extern "C" fn orchard_spending_key_for_account(
account_id: u32,
) -> *mut SpendingKey {
let seed = unsafe { slice::from_raw_parts(seed, seed_len) };
SpendingKey::from_zip32_seed(seed, bip44_coin_type, account_id)
let account = account_id.try_into().expect("account_id should be a u31");
SpendingKey::from_zip32_seed(seed, bip44_coin_type, account)
.map(|key| Box::into_raw(Box::new(key)))
.unwrap_or(std::ptr::null_mut())
}

View File

@ -2,37 +2,35 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
use std::convert::TryInto;
use std::io::{self, Read, Write};
use std::convert::{TryFrom, TryInto};
use std::io;
use std::mem;
use bellman::groth16::{prepare_verifying_key, Proof};
use bellman::groth16::Proof;
use bls12_381::Bls12;
use group::GroupEncoding;
use incrementalmerkletree::MerklePath;
use memuse::DynamicUsage;
use rand_core::OsRng;
use zcash_encoding::Vector;
use rand_core::{OsRng, RngCore};
use sapling::{
builder::BundleType,
circuit::{self, OutputParameters, SpendParameters},
keys::{OutgoingViewingKey, SpendAuthorizingKey},
note::ExtractedNoteCommitment,
prover::{OutputProver, SpendProver},
value::{NoteValue, ValueCommitTrapdoor, ValueCommitment},
zip32::ExtendedSpendingKey,
Anchor, Diversifier, MerklePath, Note, PaymentAddress, ProofGenerationKey, Rseed,
SaplingVerificationContext,
};
use zcash_primitives::{
keys::OutgoingViewingKey,
consensus::sapling_zip212_enforcement,
memo::MemoBytes,
merkle_tree::merkle_path_from_slice,
sapling::{
note::ExtractedNoteCommitment,
prover::TxProver,
redjubjub::{self, Signature},
value::{NoteValue, ValueCommitment},
Diversifier, Node, Note, PaymentAddress, ProofGenerationKey, Rseed,
NOTE_COMMITMENT_TREE_DEPTH,
},
transaction::{
components::{sapling, Amount},
components::{sapling as sapling_serialization, Amount},
txid::{BlockTxCommitmentDigester, TxIdDigester},
Authorized, Transaction, TransactionDigest,
},
zip32::ExtendedSpendingKey,
};
use zcash_proofs::sapling::{
self as sapling_proofs, SaplingProvingContext, SaplingVerificationContext,
};
use super::GROTH_PROOF_SIZE;
@ -50,10 +48,10 @@ mod zip32;
const SAPLING_TREE_DEPTH: usize = 32;
pub(crate) struct Spend(sapling::SpendDescription<sapling::Authorized>);
pub(crate) struct Spend(sapling::bundle::SpendDescription<sapling::bundle::Authorized>);
pub(crate) fn parse_v4_sapling_spend(bytes: &[u8]) -> Result<Box<Spend>, String> {
sapling::SpendDescription::read(&mut io::Cursor::new(bytes))
sapling_serialization::temporary_zcashd_read_spend_v4(&mut io::Cursor::new(bytes))
.map(Spend)
.map(Box::new)
.map_err(|e| format!("{}", e))
@ -73,7 +71,7 @@ impl Spend {
}
pub(crate) fn rk(&self) -> [u8; 32] {
self.0.rk().0.to_bytes()
(*self.0.rk()).into()
}
pub(crate) fn zkproof(&self) -> [u8; 192] {
@ -81,19 +79,14 @@ impl Spend {
}
pub(crate) fn spend_auth_sig(&self) -> [u8; 64] {
let mut ret = [0; 64];
self.0
.spend_auth_sig()
.write(&mut ret[..])
.expect("correct length");
ret
(*self.0.spend_auth_sig()).into()
}
}
pub(crate) struct Output(sapling::OutputDescription<[u8; 192]>);
pub(crate) struct Output(sapling::bundle::OutputDescription<[u8; 192]>);
pub(crate) fn parse_v4_sapling_output(bytes: &[u8]) -> Result<Box<Output>, String> {
sapling::OutputDescription::read(&mut io::Cursor::new(bytes))
sapling_serialization::temporary_zcashd_read_output_v4(&mut io::Cursor::new(bytes))
.map(Output)
.map(Box::new)
.map_err(|e| format!("{}", e))
@ -125,14 +118,13 @@ impl Output {
}
pub(crate) fn serialize_v4(&self, writer: &mut CppStream<'_>) -> Result<(), String> {
self.0
.write_v4(writer)
sapling_serialization::temporary_zcashd_write_output_v4(writer, &self.0)
.map_err(|e| format!("Failed to write v4 Sapling Output Description: {}", e))
}
}
#[derive(Clone)]
pub(crate) struct Bundle(pub(crate) Option<sapling::Bundle<sapling::Authorized>>);
pub(crate) struct Bundle(pub(crate) Option<sapling::Bundle<sapling::bundle::Authorized, Amount>>);
pub(crate) fn none_sapling_bundle() -> Box<Bundle> {
Box::new(Bundle(None))
@ -159,37 +151,15 @@ impl Bundle {
pub(crate) fn serialize_v4_components(
&self,
mut writer: &mut CppStream<'_>,
writer: &mut CppStream<'_>,
has_sapling: bool,
) -> Result<(), String> {
if has_sapling {
let mut write_v4 = || {
writer.write_all(
&self
.0
.as_ref()
.map_or(Amount::zero(), |b| *b.value_balance())
.to_i64_le_bytes(),
)?;
Vector::write(
&mut writer,
self.0.as_ref().map_or(&[], |b| b.shielded_spends()),
|w, e| e.write_v4(w),
)?;
Vector::write(
&mut writer,
self.0.as_ref().map_or(&[], |b| b.shielded_outputs()),
|w, e| e.write_v4(w),
)
};
write_v4().map_err(|e| format!("{}", e))?;
} else if self.0.is_some() {
return Err(
"Sapling components may not be present if Sapling is not active.".to_string(),
);
}
Ok(())
sapling_serialization::temporary_zcashd_write_v4_components(
writer,
self.0.as_ref(),
has_sapling,
)
.map_err(|e| format!("{}", e))
}
/// Serializes an authorized Sapling bundle to the given stream.
@ -200,7 +170,7 @@ impl Bundle {
.map_err(|e| format!("Failed to serialize Sapling bundle: {}", e))
}
pub(crate) fn inner(&self) -> Option<&sapling::Bundle<sapling::Authorized>> {
pub(crate) fn inner(&self) -> Option<&sapling::Bundle<sapling::bundle::Authorized, Amount>> {
self.0.as_ref()
}
@ -264,14 +234,11 @@ impl Bundle {
///
/// Panics if the bundle is not present.
pub(crate) fn binding_sig(&self) -> [u8; 64] {
let mut ret = [0; 64];
self.inner()
.expect("Bundle actions should have been checked to be non-empty")
.authorization()
.binding_sig
.write(&mut ret[..])
.expect("correct length");
ret
.into()
}
fn commitment<D: TransactionDigest<Authorized>>(&self, digester: D) -> D::SaplingDigest {
@ -281,8 +248,8 @@ impl Bundle {
pub(crate) struct BundleAssembler {
value_balance: Amount,
shielded_spends: Vec<sapling::SpendDescription<sapling::Authorized>>,
shielded_outputs: Vec<sapling::OutputDescription<[u8; 192]>>, // GROTH_PROOF_SIZE
shielded_spends: Vec<sapling::bundle::SpendDescription<sapling::bundle::Authorized>>,
shielded_outputs: Vec<sapling::bundle::OutputDescription<[u8; 192]>>, // GROTH_PROOF_SIZE
}
pub(crate) fn new_bundle_assembler() -> Box<BundleAssembler> {
@ -303,27 +270,11 @@ pub(crate) fn parse_v4_sapling_components(
impl BundleAssembler {
pub(crate) fn parse_v4_components(
mut reader: &mut CppStream<'_>,
reader: &mut CppStream<'_>,
has_sapling: bool,
) -> io::Result<Box<Self>> {
let (value_balance, shielded_spends, shielded_outputs) = if has_sapling {
let vb = {
let mut tmp = [0; 8];
reader.read_exact(&mut tmp)?;
Amount::from_i64_le_bytes(tmp).map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "valueBalance out of range")
})?
};
#[allow(clippy::redundant_closure)]
let ss: Vec<sapling::SpendDescription<sapling::Authorized>> =
Vector::read(&mut reader, |r| sapling::SpendDescription::read(r))?;
#[allow(clippy::redundant_closure)]
let so: Vec<sapling::OutputDescription<sapling::GrothProofBytes>> =
Vector::read(&mut reader, |r| sapling::OutputDescription::read(r))?;
(vb, ss, so)
} else {
(Amount::zero(), vec![], vec![])
};
let (value_balance, shielded_spends, shielded_outputs) =
sapling_serialization::temporary_zcashd_read_v4_components(reader, has_sapling)?;
Ok(Box::new(Self {
value_balance,
@ -342,125 +293,119 @@ pub(crate) fn finish_bundle_assembly(
assembler: Box<BundleAssembler>,
binding_sig: [u8; 64],
) -> Box<Bundle> {
let binding_sig = redjubjub::Signature::read(&binding_sig[..]).expect("parsed elsewhere");
let binding_sig = redjubjub::Signature::from(binding_sig);
Box::new(Bundle(Some(sapling::Bundle::temporary_zcashd_from_parts(
Box::new(Bundle(sapling::Bundle::from_parts(
assembler.shielded_spends,
assembler.shielded_outputs,
assembler.value_balance,
sapling::Authorized { binding_sig },
))))
sapling::bundle::Authorized { binding_sig },
)))
}
pub(crate) struct StaticTxProver;
impl TxProver for StaticTxProver {
type SaplingProvingContext = SaplingProvingContext;
impl SpendProver for StaticTxProver {
type Proof = Proof<Bls12>;
fn new_sapling_proving_context(&self) -> Self::SaplingProvingContext {
SaplingProvingContext::new()
}
fn spend_proof(
&self,
ctx: &mut Self::SaplingProvingContext,
fn prepare_circuit(
proof_generation_key: ProofGenerationKey,
diversifier: Diversifier,
rseed: Rseed,
ar: jubjub::Fr,
value: u64,
value: NoteValue,
alpha: jubjub::Fr,
rcv: ValueCommitTrapdoor,
anchor: bls12_381::Scalar,
merkle_path: MerklePath<Node, NOTE_COMMITMENT_TREE_DEPTH>,
) -> Result<
(
[u8; GROTH_PROOF_SIZE],
ValueCommitment,
redjubjub::PublicKey,
),
(),
> {
let (proof, cv, rk) = ctx.spend_proof(
merkle_path: MerklePath,
) -> Option<circuit::Spend> {
SpendParameters::prepare_circuit(
proof_generation_key,
diversifier,
rseed,
ar,
value,
alpha,
rcv,
anchor,
merkle_path,
unsafe { SAPLING_SPEND_PARAMS.as_ref() }
.expect("Parameters not loaded: SAPLING_SPEND_PARAMS should have been initialized"),
&prepare_verifying_key(
unsafe { SAPLING_SPEND_VK.as_ref() }
.expect("Parameters not loaded: SAPLING_SPEND_VK should have been initialized"),
),
)?;
let mut zkproof = [0u8; GROTH_PROOF_SIZE];
proof
.write(&mut zkproof[..])
.expect("should be able to serialize a proof");
Ok((zkproof, cv, rk))
)
}
fn output_proof(
&self,
ctx: &mut Self::SaplingProvingContext,
esk: jubjub::Fr,
payment_address: PaymentAddress,
rcm: jubjub::Fr,
value: u64,
) -> ([u8; GROTH_PROOF_SIZE], ValueCommitment) {
let (proof, cv) = ctx.output_proof(
esk,
payment_address,
rcm,
value,
unsafe { SAPLING_OUTPUT_PARAMS.as_ref() }.expect(
"Parameters not loaded: SAPLING_OUTPUT_PARAMS should have been initialized",
),
);
let mut zkproof = [0u8; GROTH_PROOF_SIZE];
proof
.write(&mut zkproof[..])
.expect("should be able to serialize a proof");
(zkproof, cv)
fn create_proof<R: RngCore>(&self, circuit: circuit::Spend, rng: &mut R) -> Self::Proof {
unsafe { SAPLING_SPEND_PARAMS.as_ref() }
.expect("Parameters not loaded: SAPLING_SPEND_PARAMS should have been initialized")
.create_proof(circuit, rng)
}
fn binding_sig(
&self,
ctx: &mut Self::SaplingProvingContext,
value_balance: zcash_primitives::transaction::components::Amount,
sighash: &[u8; 32],
) -> Result<redjubjub::Signature, ()> {
ctx.binding_sig(value_balance, sighash)
fn encode_proof(proof: Self::Proof) -> sapling::bundle::GrothProofBytes {
SpendParameters::encode_proof(proof)
}
}
pub(crate) struct SaplingBuilder(sapling::builder::SaplingBuilder<Network>);
impl OutputProver for StaticTxProver {
type Proof = Proof<Bls12>;
pub(crate) fn new_sapling_builder(network: &Network, target_height: u32) -> Box<SaplingBuilder> {
Box::new(SaplingBuilder(sapling::builder::SaplingBuilder::new(
*network,
target_height.into(),
)))
fn prepare_circuit(
esk: jubjub::Fr,
payment_address: PaymentAddress,
rcm: jubjub::Fr,
value: NoteValue,
rcv: ValueCommitTrapdoor,
) -> circuit::Output {
OutputParameters::prepare_circuit(esk, payment_address, rcm, value, rcv)
}
fn create_proof<R: RngCore>(&self, circuit: circuit::Output, rng: &mut R) -> Self::Proof {
unsafe { SAPLING_OUTPUT_PARAMS.as_ref() }
.expect("Parameters not loaded: SAPLING_OUTPUT_PARAMS should have been initialized")
.create_proof(circuit, rng)
}
fn encode_proof(proof: Self::Proof) -> sapling::bundle::GrothProofBytes {
OutputParameters::encode_proof(proof)
}
}
pub(crate) struct SaplingBuilder {
builder: sapling::builder::Builder,
signing_keys: Vec<SpendAuthorizingKey>,
}
pub(crate) fn new_sapling_builder(
network: &Network,
target_height: u32,
anchor: [u8; 32],
coinbase: bool,
) -> Result<Box<SaplingBuilder>, String> {
let bundle_type = if coinbase {
BundleType::Coinbase
} else {
BundleType::DEFAULT
};
let anchor = Option::from(Anchor::from_bytes(anchor))
.ok_or_else(|| "Invalid Sapling anchor".to_owned())?;
Ok(Box::new(SaplingBuilder {
builder: sapling::builder::Builder::new(
sapling_zip212_enforcement(network, target_height.into()),
bundle_type,
anchor,
),
signing_keys: vec![],
}))
}
#[allow(clippy::boxed_local)]
pub(crate) fn build_sapling_bundle(
builder: Box<SaplingBuilder>,
target_height: u32,
) -> Result<Box<SaplingUnauthorizedBundle>, String> {
builder.build(target_height).map(Box::new)
builder.build().map(Box::new)
}
impl SaplingBuilder {
pub(crate) fn add_spend(
&mut self,
extsk: &[u8],
diversifier: [u8; 11],
recipient: [u8; 43],
value: u64,
rcm: [u8; 32],
@ -468,7 +413,6 @@ impl SaplingBuilder {
) -> Result<(), String> {
let extsk =
ExtendedSpendingKey::from_bytes(extsk).map_err(|_| "Invalid ExtSK".to_owned())?;
let diversifier = Diversifier(diversifier);
let recipient =
PaymentAddress::from_bytes(&recipient).ok_or("Invalid recipient address")?;
let value = NoteValue::from_raw(value);
@ -481,9 +425,12 @@ impl SaplingBuilder {
let merkle_path = merkle_path_from_slice(&merkle_path)
.map_err(|e| format!("Invalid Sapling Merkle path: {}", e))?;
self.0
.add_spend(OsRng, extsk, diversifier, note, merkle_path)
.map_err(|e| format!("Failed to add Sapling spend: {}", e))
self.builder
.add_spend(&extsk, note, merkle_path)
.map_err(|e| format!("Failed to add Sapling spend: {}", e))?;
self.signing_keys.push(extsk.expsk.ask);
Ok(())
}
pub(crate) fn add_recipient(
@ -496,28 +443,39 @@ impl SaplingBuilder {
let ovk = Some(OutgoingViewingKey(ovk));
let to = PaymentAddress::from_bytes(&to).ok_or("Invalid recipient address")?;
let value = NoteValue::from_raw(value);
let memo = MemoBytes::from_bytes(&memo).map_err(|e| format!("Invalid memo: {}", e))?;
let _ = MemoBytes::from_bytes(&memo).map_err(|e| format!("Invalid memo: {}", e))?;
self.0
.add_output(OsRng, ovk, to, value, memo)
self.builder
.add_output(ovk, to, value, Some(memo))
.map_err(|e| format!("Failed to add Sapling recipient: {}", e))
}
fn build(self, target_height: u32) -> Result<SaplingUnauthorizedBundle, String> {
fn build(self) -> Result<SaplingUnauthorizedBundle, String> {
let Self {
builder,
signing_keys,
} = self;
let prover = crate::sapling::StaticTxProver;
let mut ctx = prover.new_sapling_proving_context();
let rng = OsRng;
let bundle = self
.0
.build(&prover, &mut ctx, rng, target_height.into(), None)
.map_err(|e| format!("Failed to build Sapling bundle: {}", e))?;
Ok(SaplingUnauthorizedBundle { bundle, ctx })
let bundle = builder
.build::<StaticTxProver, StaticTxProver, _, Amount>(rng)
.map_err(|e| format!("Failed to build Sapling bundle: {}", e))?
.map(|(bundle, _)| bundle.create_proofs(&prover, &prover, rng, ()));
Ok(SaplingUnauthorizedBundle {
bundle,
signing_keys,
})
}
}
pub(crate) struct SaplingUnauthorizedBundle {
pub(crate) bundle: Option<sapling::Bundle<sapling::builder::Unauthorized>>,
ctx: SaplingProvingContext,
pub(crate) bundle: Option<
sapling::Bundle<
sapling::builder::InProgress<sapling::builder::Proven, sapling::builder::Unsigned>,
Amount,
>,
>,
signing_keys: Vec<SpendAuthorizingKey>,
}
pub(crate) fn apply_sapling_bundle_signatures(
@ -529,12 +487,14 @@ pub(crate) fn apply_sapling_bundle_signatures(
impl SaplingUnauthorizedBundle {
fn apply_signatures(self, sighash_bytes: [u8; 32]) -> Result<crate::sapling::Bundle, String> {
let SaplingUnauthorizedBundle { bundle, mut ctx } = self;
let SaplingUnauthorizedBundle {
bundle,
signing_keys,
} = self;
let authorized = if let Some(bundle) = bundle {
let prover = crate::sapling::StaticTxProver;
let (authorized, _) = bundle
.apply_signatures(&prover, &mut ctx, &mut OsRng, &sighash_bytes)
let authorized = bundle
.apply_signatures(OsRng, sighash_bytes, &signing_keys)
.map_err(|e| format!("Failed to apply signatures to Sapling bundle: {}", e))?;
Some(authorized)
} else {
@ -548,10 +508,7 @@ impl SaplingUnauthorizedBundle {
pub(crate) struct Verifier(SaplingVerificationContext);
pub(crate) fn init_verifier() -> Box<Verifier> {
// We consider ZIP 216 active all of the time because blocks prior to NU5
// activation (on mainnet and testnet) did not contain Sapling transactions
// that violated its canonicity rule.
Box::new(Verifier(SaplingVerificationContext::new(true)))
Box::new(Verifier(SaplingVerificationContext::new()))
}
impl Verifier {
@ -580,16 +537,13 @@ impl Verifier {
};
// Deserialize rk
let rk = match redjubjub::PublicKey::read(&rk[..]) {
let rk = match redjubjub::VerificationKey::try_from(*rk) {
Ok(p) => p,
Err(_) => return false,
};
// Deserialize the signature
let spend_auth_sig = match Signature::read(&spend_auth_sig[..]) {
Ok(sig) => sig,
Err(_) => return false,
};
let spend_auth_sig = redjubjub::Signature::from(*spend_auth_sig);
// Deserialize the proof
let zkproof = match Proof::read(&zkproof[..]) {
@ -605,10 +559,9 @@ impl Verifier {
sighash_value,
spend_auth_sig,
zkproof,
&prepare_verifying_key(
unsafe { SAPLING_SPEND_VK.as_ref() }
.expect("Parameters not loaded: SAPLING_SPEND_VK should have been initialized"),
),
&unsafe { SAPLING_SPEND_VK.as_ref() }
.expect("Parameters not loaded: SAPLING_SPEND_VK should have been initialized")
.prepare(),
)
}
@ -648,11 +601,9 @@ impl Verifier {
cmu,
epk,
zkproof,
&prepare_verifying_key(
unsafe { SAPLING_OUTPUT_VK.as_ref() }.expect(
"Parameters not loaded: SAPLING_OUTPUT_VK should have been initialized",
),
),
&unsafe { SAPLING_OUTPUT_VK.as_ref() }
.expect("Parameters not loaded: SAPLING_OUTPUT_VK should have been initialized")
.prepare(),
)
}
@ -668,10 +619,7 @@ impl Verifier {
};
// Deserialize the signature
let binding_sig = match Signature::read(&binding_sig[..]) {
Ok(sig) => sig,
Err(_) => return false,
};
let binding_sig = redjubjub::Signature::from(*binding_sig);
self.0
.final_check(value_balance, sighash_value, binding_sig)
@ -679,7 +627,7 @@ impl Verifier {
}
struct BatchValidatorInner {
validator: sapling_proofs::BatchValidator,
validator: sapling::BatchValidator,
queued_entries: CacheEntries,
}
@ -687,7 +635,7 @@ pub(crate) struct BatchValidator(Option<BatchValidatorInner>);
pub(crate) fn init_batch_validator(cache_store: bool) -> Box<BatchValidator> {
Box::new(BatchValidator(Some(BatchValidatorInner {
validator: sapling_proofs::BatchValidator::new(),
validator: sapling::BatchValidator::new(),
queued_entries: CacheEntries::new(cache_store),
})))
}

View File

@ -5,16 +5,14 @@ use group::{cofactor::CofactorGroup, GroupEncoding};
use incrementalmerkletree::Hashable;
use rand_core::{OsRng, RngCore};
use zcash_primitives::{
use sapling::{
constants::{CRH_IVK_PERSONALIZATION, PROOF_GENERATION_KEY_GENERATOR, SPENDING_KEY_GENERATOR},
merkle_tree::HashSer,
sapling::{
merkle_hash,
note::{ExtractedNoteCommitment, NoteCommitment},
value::NoteValue,
Diversifier, Node, Note, NullifierDerivingKey, PaymentAddress, Rseed,
},
merkle_hash,
note::{ExtractedNoteCommitment, NoteCommitment},
value::NoteValue,
Diversifier, Node, Note, NullifierDerivingKey, PaymentAddress, Rseed,
};
use zcash_primitives::merkle_tree::HashSer;
use crate::de_ct;

View File

@ -1,7 +1,9 @@
use zcash_primitives::{
sapling::{keys::FullViewingKey, Diversifier},
zip32::{self, sapling_address, sapling_derive_internal_fvk, sapling_find_address},
use sapling::{
keys::FullViewingKey,
zip32::{sapling_address, sapling_derive_internal_fvk, sapling_find_address},
Diversifier,
};
use zcash_primitives::zip32;
#[cxx::bridge]
mod ffi {
@ -20,7 +22,6 @@ mod ffi {
fn xsk_master(seed: &[u8]) -> [u8; 169];
fn xsk_derive(xsk_parent: &[u8; 169], i: u32) -> [u8; 169];
fn xsk_derive_internal(xsk_external: &[u8; 169]) -> [u8; 169];
fn xfvk_derive(xfvk_parent: &[u8; 169], i: u32) -> Result<[u8; 169]>;
fn derive_internal_fvk(fvk: &[u8; 96], dk: [u8; 32]) -> FfiFullViewingKey;
fn address(fvk: &[u8; 96], dk: [u8; 32], j: [u8; 11]) -> Result<[u8; 43]>;
fn find_address(fvk: &[u8; 96], dk: [u8; 32], j: [u8; 11]) -> Result<FfiPaymentAddress>;
@ -30,7 +31,7 @@ mod ffi {
/// Derives the master ExtendedSpendingKey from a seed.
fn xsk_master(seed: &[u8]) -> [u8; 169] {
let xsk = zip32::ExtendedSpendingKey::master(seed);
let xsk = sapling::zip32::ExtendedSpendingKey::master(seed);
let mut xsk_master = [0; 169];
xsk.write(&mut xsk_master[..])
@ -40,9 +41,9 @@ fn xsk_master(seed: &[u8]) -> [u8; 169] {
/// Derive a child ExtendedSpendingKey from a parent.
fn xsk_derive(xsk_parent: &[u8; 169], i: u32) -> [u8; 169] {
let xsk_parent =
zip32::ExtendedSpendingKey::read(&xsk_parent[..]).expect("valid ExtendedSpendingKey");
let i = zip32::ChildIndex::from_index(i);
let xsk_parent = sapling::zip32::ExtendedSpendingKey::read(&xsk_parent[..])
.expect("valid ExtendedSpendingKey");
let i = zip32::ChildIndex::from_index(i).expect("non-hardened derivation is unsupported");
let xsk = xsk_parent.derive_child(i);
@ -55,8 +56,8 @@ fn xsk_derive(xsk_parent: &[u8; 169], i: u32) -> [u8; 169] {
/// Derive the Sapling internal spending key from the external extended
/// spending key
fn xsk_derive_internal(xsk_external: &[u8; 169]) -> [u8; 169] {
let xsk_external =
zip32::ExtendedSpendingKey::read(&xsk_external[..]).expect("valid ExtendedSpendingKey");
let xsk_external = sapling::zip32::ExtendedSpendingKey::read(&xsk_external[..])
.expect("valid ExtendedSpendingKey");
let xsk_internal = xsk_external.derive_internal();
@ -67,26 +68,10 @@ fn xsk_derive_internal(xsk_external: &[u8; 169]) -> [u8; 169] {
xsk_internal_ret
}
/// Derive a child ExtendedFullViewingKey from a parent.
fn xfvk_derive(xfvk_parent: &[u8; 169], i: u32) -> Result<[u8; 169], String> {
let xfvk_parent = zip32::ExtendedFullViewingKey::read(&xfvk_parent[..])
.expect("valid ExtendedFullViewingKey");
let i = zip32::ChildIndex::from_index(i);
let xfvk = xfvk_parent
.derive_child(i)
.map_err(|()| "Cannot derive hardened xfvk".to_string())?;
let mut xfvk_i = [0; 169];
xfvk.write(&mut xfvk_i[..])
.expect("should be able to serialize an ExtendedFullViewingKey");
Ok(xfvk_i)
}
/// Derive the Sapling internal full viewing key from the corresponding external full viewing key
fn derive_internal_fvk(fvk: &[u8; 96], dk: [u8; 32]) -> ffi::FfiFullViewingKey {
let fvk = FullViewingKey::read(&fvk[..]).expect("valid Sapling FullViewingKey");
let dk = zip32::sapling::DiversifierKey::from_bytes(dk);
let dk = sapling::zip32::DiversifierKey::from_bytes(dk);
let (fvk_internal, dk_internal) = sapling_derive_internal_fvk(&fvk, &dk);
@ -99,8 +84,8 @@ fn derive_internal_fvk(fvk: &[u8; 96], dk: [u8; 32]) -> ffi::FfiFullViewingKey {
/// Derive a PaymentAddress from an ExtendedFullViewingKey.
fn address(fvk: &[u8; 96], dk: [u8; 32], j: [u8; 11]) -> Result<[u8; 43], String> {
let fvk = FullViewingKey::read(&fvk[..]).expect("valid Sapling FullViewingKey");
let dk = zip32::sapling::DiversifierKey::from_bytes(dk);
let j = zip32::DiversifierIndex(j);
let dk = sapling::zip32::DiversifierKey::from_bytes(dk);
let j = zip32::DiversifierIndex::from(j);
sapling_address(&fvk, &dk, j)
.ok_or_else(|| "Diversifier index does not produce a valid diversifier".to_string())
@ -114,21 +99,21 @@ fn find_address(
j: [u8; 11],
) -> Result<ffi::FfiPaymentAddress, String> {
let fvk = FullViewingKey::read(&fvk[..]).expect("valid Sapling FullViewingKey");
let dk = zip32::sapling::DiversifierKey::from_bytes(dk);
let j = zip32::DiversifierIndex(j);
let dk = sapling::zip32::DiversifierKey::from_bytes(dk);
let j = zip32::DiversifierIndex::from(j);
sapling_find_address(&fvk, &dk, j)
.ok_or_else(|| "No valid diversifiers at or above given index".to_string())
.map(|(j, addr)| ffi::FfiPaymentAddress {
j: j.0,
j: *j.as_bytes(),
addr: addr.to_bytes(),
})
}
fn diversifier_index(dk: [u8; 32], d: [u8; 11]) -> [u8; 11] {
let dk = zip32::sapling::DiversifierKey::from_bytes(dk);
let dk = sapling::zip32::DiversifierKey::from_bytes(dk);
let diversifier = Diversifier(d);
let j = dk.diversifier_index(&diversifier);
j.0
*j.as_bytes()
}

View File

@ -1,10 +1,10 @@
use std::convert::TryFrom;
use group::{ff::Field, Group, GroupEncoding};
use rand::{thread_rng, Rng};
use sapling::value::ValueCommitment;
use zcash_note_encryption::EphemeralKeyBytes;
use zcash_primitives::{
sapling::{self, redjubjub, value::ValueCommitment},
transaction::components::{sapling as sapling_tx, Amount},
};
use zcash_primitives::transaction::components::Amount;
pub(crate) fn test_only_invalid_sapling_bundle(
spends: usize,
@ -27,14 +27,17 @@ pub(crate) fn test_only_invalid_sapling_bundle(
.unwrap();
let anchor = jubjub::Base::random(&mut rng);
let nullifier = sapling::Nullifier(rng.gen());
let rk = redjubjub::PublicKey(jubjub::ExtendedPoint::random(&mut rng));
let rk = redjubjub::VerificationKey::try_from(
jubjub::ExtendedPoint::random(&mut rng).to_bytes(),
)
.unwrap();
let zkproof = gen_array(&mut rng);
let spend_auth_sig = {
let tmp = gen_array::<_, 64>(&mut rng);
redjubjub::Signature::read(&tmp[..]).unwrap()
redjubjub::Signature::from(tmp)
};
sapling_tx::SpendDescription::temporary_zcashd_from_parts(
sapling::bundle::SpendDescription::from_parts(
cv,
anchor,
nullifier,
@ -61,7 +64,7 @@ pub(crate) fn test_only_invalid_sapling_bundle(
let out_ciphertext = gen_array(&mut rng);
let zkproof = gen_array(&mut rng);
sapling_tx::OutputDescription::temporary_zcashd_from_parts(
sapling::bundle::OutputDescription::from_parts(
cv,
cmu,
ephemeral_key,
@ -74,16 +77,16 @@ pub(crate) fn test_only_invalid_sapling_bundle(
let binding_sig = {
let tmp = gen_array::<_, 64>(&mut rng);
redjubjub::Signature::read(&tmp[..]).unwrap()
redjubjub::Signature::from(tmp)
};
let bundle = sapling_tx::Bundle::temporary_zcashd_from_parts(
let bundle = sapling::Bundle::from_parts(
spends,
outputs,
Amount::from_i64(value_balance).unwrap(),
sapling_tx::Authorized { binding_sig },
sapling::bundle::Authorized { binding_sig },
);
Box::new(crate::sapling::Bundle(Some(bundle)))
Box::new(crate::sapling::Bundle(bundle))
}
pub(crate) fn test_only_replace_sapling_nullifier(
@ -92,18 +95,18 @@ pub(crate) fn test_only_replace_sapling_nullifier(
nullifier: [u8; 32],
) {
if let Some(bundle) = bundle.0.as_mut() {
*bundle = sapling_tx::Bundle::temporary_zcashd_from_parts(
*bundle = sapling::Bundle::from_parts(
bundle
.shielded_spends()
.iter()
.enumerate()
.map(|(i, spend)| {
if i == spend_index {
sapling_tx::SpendDescription::temporary_zcashd_from_parts(
sapling::bundle::SpendDescription::from_parts(
spend.cv().clone(),
*spend.anchor(),
sapling::Nullifier(nullifier),
spend.rk().clone(),
*spend.rk(),
*spend.zkproof(),
*spend.spend_auth_sig(),
)
@ -116,6 +119,7 @@ pub(crate) fn test_only_replace_sapling_nullifier(
*bundle.value_balance(),
*bundle.authorization(),
)
.expect("Prior bundle was valid");
}
}
@ -127,7 +131,7 @@ pub(crate) fn test_only_replace_sapling_output_parts(
out_ciphertext: [u8; 80],
) {
if let Some(bundle) = bundle.0.as_mut() {
*bundle = sapling_tx::Bundle::temporary_zcashd_from_parts(
*bundle = sapling::Bundle::from_parts(
bundle.shielded_spends().to_vec(),
bundle
.shielded_outputs()
@ -135,7 +139,7 @@ pub(crate) fn test_only_replace_sapling_output_parts(
.enumerate()
.map(|(i, output)| {
if i == output_index {
sapling_tx::OutputDescription::temporary_zcashd_from_parts(
sapling::bundle::OutputDescription::from_parts(
output.cv().clone(),
sapling::note::ExtractedNoteCommitment::from_bytes(&cmu).unwrap(),
output.ephemeral_key().clone(),
@ -151,5 +155,6 @@ pub(crate) fn test_only_replace_sapling_output_parts(
*bundle.value_balance(),
*bundle.authorization(),
)
.expect("Prior bundle was valid");
}
}

View File

@ -1,7 +1,7 @@
use group::GroupEncoding;
use zcash_primitives::{
constants::SPENDING_KEY_GENERATOR,
sapling::{Diversifier, Nullifier, ProofGenerationKey, Rseed},
use sapling::{
constants::SPENDING_KEY_GENERATOR, keys::SpendValidatingKey, value::NoteValue, Diversifier,
Nullifier, ProofGenerationKey, Rseed,
};
use crate::sapling::spec::{ask_to_ak, check_diversifier, crh_ivk, ivk_to_pkd, nsk_to_nk};
@ -661,7 +661,10 @@ fn key_components() {
assert_eq!(&ak, &tv.ak);
}
let pgk = ProofGenerationKey { ak, nsk };
let pgk = ProofGenerationKey {
ak: SpendValidatingKey::temporary_zcash_from_bytes(&ak.to_bytes()).unwrap(),
nsk,
};
let fvk = pgk.to_viewing_key();
assert_eq!(&fvk.nk.0.to_bytes(), &tv.nk);
{
@ -686,7 +689,7 @@ fn key_components() {
}
let note_r = jubjub::Scalar::from_bytes(&tv.note_r).unwrap();
let note = addr.create_note(tv.note_v, Rseed::BeforeZip212(note_r));
let note = addr.create_note(NoteValue::from_raw(tv.note_v), Rseed::BeforeZip212(note_r));
assert_eq!(&note.cmu().to_bytes(), &tv.note_cm);
assert_eq!(note.nf(&fvk.nk, tv.note_pos), Nullifier(tv.note_nf));

View File

@ -1,5 +1,5 @@
use group::GroupEncoding;
use zcash_primitives::constants::{
use sapling::constants::{
NOTE_COMMITMENT_RANDOMNESS_GENERATOR, NULLIFIER_POSITION_GENERATOR,
PROOF_GENERATION_KEY_GENERATOR, SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR,
VALUE_COMMITMENT_VALUE_GENERATOR,

View File

@ -1,7 +1,4 @@
use zcash_primitives::{
constants::SPENDING_KEY_GENERATOR,
sapling::redjubjub::{PrivateKey, PublicKey, Signature},
};
use std::convert::TryFrom;
#[test]
fn redjubjub_signatures() {
@ -16,7 +13,7 @@ fn redjubjub_signatures() {
rsig: [u8; 64],
}
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/sapling_signatures.py
// From https://github.com/zcash/zcash-test-vectors/blob/master/zcash_test_vectors/sapling/redjubjub.py
let test_vectors = vec![
TestVector {
sk: [
@ -50,18 +47,18 @@ fn redjubjub_signatures() {
0x00, 0x00, 0x00, 0x00,
],
sig: [
0xea, 0xa0, 0x57, 0x47, 0x6b, 0x4a, 0xb4, 0x82, 0x28, 0x8b, 0x93, 0xdf, 0x8f, 0xe0,
0xc5, 0xce, 0x9d, 0x78, 0x83, 0x67, 0xf2, 0xbe, 0x55, 0x1b, 0x7f, 0x7a, 0x82, 0xa6,
0xdb, 0x36, 0x04, 0x68, 0xde, 0xb9, 0xa7, 0xb7, 0xaf, 0xaa, 0xdf, 0xec, 0xa6, 0xf4,
0x81, 0x19, 0x3d, 0xc6, 0x57, 0x57, 0x47, 0xf6, 0x0a, 0x1a, 0x8a, 0x48, 0xff, 0x0a,
0xd7, 0x0c, 0xf8, 0xcb, 0x8d, 0x52, 0x8e, 0x08,
0xdc, 0xa3, 0xbb, 0x2c, 0xb8, 0xf0, 0x48, 0xcc, 0xab, 0x10, 0xae, 0xd7, 0x75, 0x46,
0xc1, 0xdb, 0xb1, 0x0c, 0xc4, 0xfb, 0x15, 0xab, 0x02, 0xac, 0xae, 0xf9, 0x44, 0xdd,
0xab, 0x8b, 0x67, 0x22, 0x54, 0x5f, 0xda, 0x4c, 0x62, 0x04, 0x6d, 0x69, 0xd9, 0x8f,
0x92, 0x2f, 0x4e, 0x8c, 0x21, 0x0b, 0xc4, 0x7b, 0x4f, 0xdd, 0xe0, 0xa1, 0x94, 0x71,
0x79, 0x80, 0x4c, 0x1a, 0xce, 0x56, 0x90, 0x05,
],
rsig: [
0xd5, 0x6f, 0x0d, 0x91, 0xaf, 0x42, 0x4e, 0x1f, 0x1c, 0x7f, 0xb8, 0x6b, 0xa4, 0xee,
0xd1, 0x43, 0xcc, 0x16, 0x66, 0x0c, 0x5f, 0xe8, 0xd7, 0xdc, 0x0d, 0x28, 0x4b, 0xcf,
0x65, 0xa0, 0x89, 0xe9, 0x8b, 0x56, 0x1f, 0x9f, 0x20, 0x1a, 0x63, 0x3d, 0x70, 0x0c,
0xd3, 0x98, 0x1e, 0x8c, 0xac, 0x07, 0xb5, 0xa8, 0x7e, 0xfa, 0x61, 0x86, 0x06, 0x2d,
0xd8, 0xe5, 0xd6, 0x32, 0x5e, 0x7b, 0x82, 0x02,
0x70, 0xc2, 0x84, 0x50, 0x4e, 0x90, 0xf0, 0x00, 0x8e, 0x8e, 0xd2, 0x20, 0x8f, 0x49,
0x69, 0x72, 0x7a, 0x41, 0x5e, 0xc3, 0x10, 0x2c, 0x29, 0x9e, 0x39, 0x8b, 0x6c, 0x16,
0x57, 0x2b, 0xd9, 0x64, 0x3e, 0xe1, 0x01, 0x17, 0x66, 0x68, 0x1e, 0x40, 0x6e, 0xe6,
0xbe, 0xe3, 0xd0, 0x3e, 0xe8, 0xf2, 0x71, 0x76, 0xe3, 0x2f, 0xba, 0xbd, 0xde, 0xd2,
0x0b, 0x0d, 0x17, 0x86, 0xa4, 0xee, 0x18, 0x01,
],
},
TestVector {
@ -96,18 +93,18 @@ fn redjubjub_signatures() {
0x01, 0x01, 0x01, 0x01,
],
sig: [
0x22, 0x35, 0x54, 0x94, 0xa8, 0x31, 0x6a, 0xb1, 0x34, 0x73, 0xf5, 0x5e, 0x62, 0x66,
0xb2, 0xfb, 0x41, 0x97, 0x31, 0x5e, 0xac, 0x62, 0xf8, 0x2c, 0xc7, 0x3d, 0xca, 0xca,
0x19, 0x90, 0x90, 0xf1, 0x5b, 0xe1, 0x98, 0xce, 0x7d, 0x3f, 0x9f, 0xc8, 0xff, 0xf5,
0x50, 0xe1, 0x08, 0x81, 0xec, 0x49, 0xff, 0x27, 0x36, 0x9e, 0x7d, 0x4f, 0xd9, 0x64,
0x01, 0x53, 0x49, 0x2a, 0x0a, 0x06, 0x25, 0x08,
0xb5, 0xa1, 0xf3, 0x2d, 0x3d, 0x50, 0xfc, 0x73, 0x8b, 0x5c, 0x3b, 0x4e, 0x99, 0x60,
0x72, 0x9c, 0xe4, 0x31, 0x6b, 0xa7, 0x72, 0x1a, 0x12, 0x68, 0x66, 0x04, 0xfe, 0xba,
0x6b, 0xd7, 0x48, 0x45, 0x00, 0x70, 0xcb, 0x92, 0x24, 0x06, 0xfd, 0xfc, 0x5d, 0x60,
0xde, 0xa9, 0xbe, 0x3a, 0x52, 0x6a, 0x16, 0xcf, 0xeb, 0x87, 0x77, 0x79, 0xfb, 0x78,
0x2d, 0x5d, 0x41, 0x39, 0x5b, 0x45, 0x5f, 0x04,
],
rsig: [
0xf4, 0xb8, 0x94, 0xba, 0x84, 0xce, 0x1e, 0xc3, 0x8a, 0x63, 0x15, 0x2f, 0xc4, 0x09,
0xf9, 0x47, 0xd6, 0x1a, 0xbb, 0x1f, 0x48, 0x91, 0x63, 0x6b, 0xc3, 0xee, 0x19, 0xef,
0x6d, 0x4b, 0x30, 0xc0, 0xfd, 0x22, 0x86, 0x6b, 0x84, 0xff, 0xbc, 0x7e, 0x2a, 0x78,
0xc4, 0x3f, 0x57, 0x83, 0xd2, 0xd2, 0xea, 0xd0, 0x78, 0x59, 0x55, 0x03, 0x74, 0x43,
0xc2, 0xf4, 0xd5, 0x2f, 0x78, 0x5e, 0xee, 0x07,
0x5a, 0x5a, 0x20, 0xd2, 0x00, 0xef, 0xdd, 0xd4, 0x98, 0xdf, 0xae, 0x2a, 0x9e, 0xf8,
0xcf, 0x01, 0x28, 0x1a, 0x89, 0x19, 0x01, 0x8a, 0x82, 0x4c, 0xc7, 0xa4, 0x98, 0x3b,
0x9a, 0x0d, 0x4a, 0x06, 0xff, 0x17, 0x20, 0x79, 0xe0, 0x13, 0xd4, 0x2a, 0x2a, 0x3a,
0x88, 0xa6, 0x52, 0x0c, 0x86, 0xfc, 0xe3, 0xb9, 0x8e, 0x1e, 0xfa, 0xa3, 0x25, 0x83,
0x2a, 0x6a, 0x56, 0x58, 0xd8, 0xdd, 0x7c, 0x0a,
],
},
TestVector {
@ -142,18 +139,18 @@ fn redjubjub_signatures() {
0x02, 0x02, 0x02, 0x02,
],
sig: [
0xdd, 0x65, 0x21, 0x01, 0x4d, 0xff, 0x70, 0x6e, 0x3a, 0x38, 0x52, 0x7a, 0x86, 0xb6,
0xc1, 0x6e, 0x94, 0x14, 0x80, 0xe7, 0x33, 0xef, 0xf7, 0x9e, 0xbe, 0x0c, 0x43, 0x03,
0x79, 0xd7, 0x57, 0x04, 0x9d, 0xb7, 0x90, 0xcd, 0x5e, 0x14, 0x44, 0x7c, 0x38, 0x6f,
0x5f, 0xcb, 0x41, 0x9f, 0x27, 0xc4, 0x41, 0x3f, 0x35, 0x88, 0xfa, 0x21, 0x42, 0xd2,
0xcf, 0xba, 0xed, 0x08, 0x2c, 0xc6, 0xdb, 0x07,
0x1f, 0x3e, 0x8a, 0x94, 0x31, 0x0c, 0x20, 0x71, 0xa7, 0x0f, 0x9d, 0xf5, 0xe7, 0x9a,
0xa9, 0xe8, 0x48, 0x5d, 0xec, 0xcb, 0x17, 0x8b, 0xdf, 0xf9, 0x80, 0x5f, 0xcb, 0xe6,
0xf7, 0xd5, 0x51, 0xee, 0xe3, 0xc3, 0x54, 0x2c, 0xa7, 0x5c, 0x9d, 0x8d, 0x4a, 0xdc,
0x54, 0xd7, 0x2c, 0x3d, 0xbe, 0x28, 0x62, 0x6d, 0x20, 0x78, 0x5b, 0xb7, 0xf5, 0x88,
0xc1, 0xa5, 0x82, 0xb8, 0x93, 0xdb, 0xb6, 0x01,
],
rsig: [
0xd8, 0x94, 0x45, 0xcb, 0x9b, 0xd1, 0x03, 0x35, 0x69, 0x23, 0x1d, 0xd6, 0x28, 0xaa,
0x62, 0x81, 0x09, 0xfe, 0x93, 0x50, 0x2b, 0xf2, 0x2f, 0x9a, 0x5f, 0x37, 0xb1, 0x4e,
0x51, 0x7f, 0x9a, 0x20, 0x54, 0xae, 0xe3, 0xc8, 0x1b, 0x60, 0xb3, 0xf0, 0x55, 0x1e,
0x32, 0xf7, 0x93, 0x5a, 0xbc, 0x2f, 0x37, 0xb9, 0x9a, 0xb3, 0xec, 0x99, 0x68, 0x02,
0xef, 0xd6, 0x50, 0x69, 0xe1, 0x28, 0x12, 0x08,
0xd1, 0x36, 0x21, 0x4c, 0x5d, 0x52, 0x8e, 0xa3, 0xd4, 0xcb, 0x7b, 0x63, 0x1a, 0x6b,
0xb0, 0x36, 0x06, 0x49, 0x73, 0xa1, 0x08, 0xb7, 0x33, 0xa5, 0xe3, 0xa4, 0x52, 0xab,
0x52, 0xa6, 0x59, 0xe5, 0x67, 0xcb, 0x55, 0xd2, 0x64, 0x4e, 0x74, 0xb6, 0xe8, 0x42,
0x6f, 0x2a, 0x7d, 0xd2, 0xa0, 0x4d, 0x2d, 0xda, 0x49, 0x35, 0xcc, 0x38, 0x20, 0xb7,
0x7a, 0x9c, 0x1a, 0xb6, 0x19, 0x86, 0x3c, 0x05,
],
},
TestVector {
@ -188,18 +185,18 @@ fn redjubjub_signatures() {
0x03, 0x03, 0x03, 0x03,
],
sig: [
0x72, 0x79, 0xa7, 0x5c, 0x01, 0x36, 0x75, 0xb3, 0x29, 0x84, 0xe5, 0xc7, 0x3a, 0x98,
0x91, 0xeb, 0xf0, 0xb2, 0x29, 0xb1, 0x6e, 0x62, 0x35, 0xba, 0x36, 0xdf, 0xa1, 0xb5,
0xa1, 0x0c, 0x5e, 0x44, 0x57, 0x81, 0x91, 0x89, 0x7c, 0x06, 0xb8, 0x52, 0x4a, 0x26,
0x74, 0xaa, 0x7a, 0x0c, 0x8c, 0x23, 0x5f, 0x52, 0xd3, 0x3a, 0xc9, 0x2c, 0x70, 0x56,
0xb2, 0xbe, 0x95, 0x3c, 0x3f, 0xaa, 0x3d, 0x07,
0x12, 0xc7, 0x8d, 0xdd, 0x20, 0xd3, 0x0a, 0x61, 0xf8, 0x93, 0x0c, 0x6f, 0xe0, 0x85,
0x0f, 0xd1, 0x12, 0xbb, 0x7b, 0xe8, 0x8b, 0x12, 0x38, 0xea, 0x33, 0xd6, 0xbe, 0xf8,
0x81, 0xc1, 0x02, 0xd1, 0x04, 0xaa, 0x36, 0x54, 0x4a, 0x78, 0x47, 0x1c, 0x9e, 0x28,
0x42, 0xe6, 0xfd, 0x42, 0x55, 0x83, 0x46, 0xcf, 0xf4, 0x31, 0x27, 0x03, 0x26, 0x66,
0xeb, 0x11, 0x6f, 0x44, 0x2a, 0x28, 0x48, 0x0c,
],
rsig: [
0xaa, 0xd4, 0x82, 0x8c, 0xb3, 0x42, 0xcf, 0x09, 0xb0, 0x0e, 0x30, 0x2c, 0xbb, 0xe7,
0xcc, 0x3e, 0x95, 0xfe, 0x1f, 0xf8, 0x28, 0x74, 0x8e, 0x5f, 0x5b, 0xc6, 0x9c, 0xbf,
0xde, 0x6e, 0x27, 0x22, 0xd7, 0x64, 0x35, 0x68, 0x7e, 0x85, 0x0c, 0xd3, 0x07, 0xa9,
0xc1, 0x82, 0xec, 0x10, 0xe6, 0x88, 0x1d, 0xd6, 0x5e, 0xed, 0xc1, 0x1f, 0xa7, 0xb4,
0x6d, 0xe3, 0xa7, 0x19, 0x59, 0xce, 0xc0, 0x02,
0x01, 0xba, 0xaa, 0x26, 0x27, 0x4c, 0x14, 0x9a, 0xcf, 0x12, 0xe1, 0xcc, 0xf5, 0x50,
0x7d, 0x56, 0x79, 0x04, 0x82, 0xf0, 0x67, 0xe5, 0xc9, 0x2b, 0x32, 0x19, 0xad, 0x6b,
0xf9, 0x11, 0x18, 0xcc, 0x3f, 0xce, 0x8d, 0x2a, 0x23, 0x19, 0x8a, 0x3b, 0x29, 0x0a,
0x7b, 0xf6, 0x8c, 0x2a, 0xc0, 0x7b, 0x5d, 0x90, 0x62, 0xb9, 0xf8, 0x68, 0x66, 0x2b,
0xb2, 0x52, 0x49, 0x12, 0xd4, 0x85, 0x6e, 0x0c,
],
},
TestVector {
@ -234,18 +231,18 @@ fn redjubjub_signatures() {
0x04, 0x04, 0x04, 0x04,
],
sig: [
0x51, 0x23, 0xb3, 0x1f, 0x84, 0xaf, 0x0c, 0x35, 0x5e, 0x13, 0xe7, 0x8a, 0x64, 0xd7,
0xa3, 0xcd, 0xfd, 0x6b, 0xdf, 0xfd, 0xc7, 0x33, 0x38, 0xd9, 0x31, 0x7f, 0x73, 0x43,
0x91, 0xa5, 0x5a, 0xe6, 0x25, 0x8f, 0x69, 0x80, 0xb9, 0xc7, 0xd1, 0x90, 0xcf, 0xa3,
0x65, 0x81, 0xa9, 0xa4, 0x7a, 0x86, 0x3f, 0xd3, 0xbf, 0x76, 0x59, 0x42, 0x22, 0x95,
0xb7, 0x5f, 0xd1, 0x22, 0xc3, 0xdd, 0x8a, 0x05,
0x77, 0x4a, 0xc4, 0x67, 0x3f, 0x09, 0xf3, 0xac, 0x57, 0x89, 0xb2, 0x86, 0xb5, 0xee,
0xcb, 0xed, 0xb2, 0x57, 0x23, 0x4e, 0x8c, 0xdf, 0xd9, 0x3f, 0x02, 0x89, 0x09, 0x78,
0xa6, 0xbb, 0xa6, 0x11, 0x69, 0xed, 0x48, 0xf9, 0xe1, 0xc9, 0xfd, 0x13, 0x19, 0xbd,
0x33, 0x0d, 0x2c, 0xf5, 0xb4, 0x91, 0x01, 0x0d, 0x69, 0xb0, 0x43, 0xf4, 0x64, 0x8b,
0xff, 0x55, 0x41, 0x62, 0xc6, 0xa6, 0xdc, 0x09,
],
rsig: [
0x5b, 0xae, 0x25, 0x4f, 0xbd, 0xed, 0x60, 0x7a, 0x5c, 0x48, 0xb5, 0x30, 0x29, 0xf5,
0x9b, 0xa7, 0x06, 0x32, 0x48, 0x79, 0xaa, 0x18, 0xd9, 0xc4, 0x73, 0x19, 0x00, 0x4b,
0xe0, 0x2c, 0xec, 0xe0, 0xb8, 0xbb, 0x02, 0x4a, 0x7a, 0xab, 0xaa, 0x0a, 0x64, 0x0f,
0x3a, 0x54, 0xdc, 0xda, 0xf2, 0x11, 0x31, 0x46, 0x9a, 0x50, 0x06, 0xbe, 0x27, 0x81,
0xa5, 0x67, 0xff, 0xa6, 0x50, 0x3a, 0x35, 0x03,
0x7c, 0x6c, 0x49, 0x8d, 0xe0, 0x01, 0x78, 0x61, 0x09, 0xb3, 0x03, 0xa4, 0xc5, 0xdc,
0xb7, 0xfd, 0x07, 0x57, 0x50, 0xa0, 0xb9, 0xdf, 0x5e, 0x1e, 0x2a, 0x8e, 0x75, 0x47,
0xb7, 0xed, 0x70, 0xcc, 0x0b, 0x56, 0xa5, 0xbf, 0xa9, 0x65, 0x78, 0x43, 0xef, 0xd8,
0x9c, 0x66, 0xa8, 0x4f, 0x41, 0xd2, 0xb1, 0xb5, 0x07, 0x51, 0x19, 0x6b, 0x1e, 0x8c,
0x0c, 0x44, 0x98, 0x60, 0x06, 0x96, 0xa4, 0x04,
],
},
TestVector {
@ -280,18 +277,18 @@ fn redjubjub_signatures() {
0x05, 0x05, 0x05, 0x05,
],
sig: [
0xdc, 0x18, 0xc8, 0x8d, 0x96, 0x44, 0x42, 0x40, 0x6d, 0x65, 0x0a, 0xa2, 0xff, 0xbd,
0x83, 0xd1, 0x13, 0xbf, 0x6a, 0x19, 0xda, 0x78, 0xf2, 0x66, 0x5b, 0x29, 0x4f, 0xa5,
0xfa, 0x45, 0x0b, 0x92, 0x81, 0xa0, 0x7e, 0x32, 0x0c, 0x1a, 0xa3, 0x1d, 0x32, 0x44,
0x9e, 0x00, 0xc5, 0xc3, 0x2d, 0xb2, 0xf4, 0x13, 0xdf, 0x0b, 0x63, 0xd0, 0x72, 0x8f,
0xa4, 0x09, 0x41, 0xa8, 0xda, 0x02, 0x4f, 0x01,
0x9a, 0x25, 0x42, 0x9f, 0x3e, 0xfd, 0x9b, 0x2f, 0x7d, 0xe2, 0x9e, 0x45, 0x12, 0x8d,
0xd7, 0xb7, 0x60, 0xf0, 0x50, 0x8c, 0xd9, 0x58, 0x21, 0x82, 0xab, 0xaf, 0x53, 0xdd,
0x76, 0xc0, 0x34, 0x2c, 0xe4, 0x1b, 0x4a, 0xcf, 0x8e, 0x0a, 0x48, 0x24, 0xe4, 0x11,
0x08, 0xc2, 0x02, 0x65, 0x73, 0x11, 0x4b, 0x60, 0xbe, 0xec, 0xb1, 0x74, 0x01, 0x2a,
0x2b, 0xdb, 0xee, 0xcb, 0xaa, 0x00, 0xb5, 0x06,
],
rsig: [
0x59, 0xe2, 0xe8, 0x18, 0x76, 0x6c, 0x50, 0xfc, 0x8f, 0x38, 0x40, 0xb2, 0x72, 0xaf,
0x9a, 0xd9, 0x47, 0x56, 0xc8, 0x41, 0x32, 0x95, 0xfc, 0x79, 0x5f, 0xaf, 0xbc, 0xc0,
0x71, 0x8e, 0x6c, 0x08, 0x16, 0x9a, 0x00, 0xd5, 0x83, 0x02, 0x77, 0x2a, 0x28, 0x28,
0x43, 0xe8, 0x88, 0xd9, 0x81, 0xfa, 0x04, 0x79, 0x5d, 0x01, 0x4c, 0xf9, 0xc8, 0xcd,
0xb9, 0x07, 0xff, 0x1b, 0x43, 0x0d, 0x92, 0x00,
0xcf, 0xf5, 0x83, 0x57, 0x13, 0xbe, 0x07, 0xfb, 0xe1, 0x25, 0xbb, 0xf2, 0x7a, 0x63,
0x6a, 0xdd, 0x13, 0x1c, 0x90, 0x81, 0x71, 0x6c, 0x52, 0xfd, 0xa8, 0x75, 0x42, 0x6d,
0x03, 0x98, 0x2c, 0xd2, 0x7e, 0xbd, 0x14, 0xb4, 0x22, 0x7b, 0x83, 0x96, 0x15, 0xfd,
0x03, 0x71, 0xbf, 0xdb, 0x8a, 0x30, 0xab, 0xdd, 0xff, 0x74, 0xd7, 0x95, 0xf3, 0xe2,
0x7d, 0x1d, 0x47, 0xc6, 0x29, 0x46, 0x9b, 0x08,
],
},
TestVector {
@ -326,18 +323,18 @@ fn redjubjub_signatures() {
0x06, 0x06, 0x06, 0x06,
],
sig: [
0x9a, 0xf6, 0xf2, 0x80, 0x0f, 0x4b, 0x80, 0xf7, 0x93, 0xbe, 0x64, 0x8a, 0x43, 0x9f,
0x86, 0xe5, 0x7d, 0xa1, 0xb9, 0x19, 0x99, 0x9e, 0x41, 0x91, 0x09, 0x99, 0xd4, 0x2e,
0xd0, 0xf3, 0x89, 0x6d, 0xb7, 0x6e, 0x06, 0x38, 0x8b, 0x27, 0x2c, 0x99, 0x85, 0x8b,
0x55, 0x04, 0xd0, 0x2e, 0xc6, 0xb4, 0xd5, 0x25, 0xb8, 0x71, 0x38, 0x10, 0x50, 0x5f,
0x4f, 0xc0, 0x31, 0x08, 0x3a, 0x14, 0xbf, 0x09,
0xbb, 0xe0, 0x23, 0x59, 0x87, 0xc6, 0xe0, 0xec, 0x68, 0x6d, 0xdb, 0x8a, 0x65, 0x72,
0x66, 0xad, 0x60, 0x5f, 0x7b, 0x75, 0x95, 0x5b, 0xb0, 0xe8, 0x02, 0xf8, 0x81, 0x64,
0xa0, 0xff, 0xe1, 0x0c, 0x3b, 0x73, 0x85, 0x04, 0xab, 0xb3, 0xd1, 0x05, 0x62, 0xb9,
0x27, 0xb3, 0xd2, 0x9f, 0xe9, 0xb0, 0xd3, 0x56, 0x28, 0x6a, 0xea, 0xe5, 0xa2, 0xac,
0x9e, 0x43, 0x5f, 0x20, 0x79, 0x1a, 0xf8, 0x00,
],
rsig: [
0x3f, 0x7d, 0x50, 0x71, 0xb8, 0x76, 0x17, 0x49, 0x05, 0x71, 0xa8, 0xbe, 0x91, 0x74,
0x9e, 0x69, 0xf6, 0xbc, 0xba, 0x5a, 0xb6, 0x26, 0xe4, 0x2f, 0xf9, 0x2d, 0x0d, 0x7d,
0xab, 0x73, 0xf3, 0x03, 0x61, 0xe5, 0xa2, 0x24, 0x99, 0x8e, 0x1f, 0x5e, 0xa1, 0xe5,
0xf8, 0x68, 0x9a, 0x06, 0xa2, 0x77, 0x48, 0xbf, 0x74, 0x19, 0x63, 0xef, 0x51, 0x33,
0x22, 0xf4, 0xa1, 0xba, 0x99, 0xaa, 0x36, 0x03,
0x6d, 0xe3, 0x2b, 0x54, 0x15, 0xd7, 0x7a, 0x90, 0x5f, 0x09, 0x03, 0x90, 0x2a, 0x11,
0x7e, 0xda, 0x79, 0x3c, 0x70, 0x8e, 0x23, 0xa5, 0x42, 0x45, 0xba, 0x8a, 0x8d, 0x1f,
0xe0, 0x26, 0x75, 0x23, 0x23, 0x15, 0x65, 0xe0, 0x57, 0x09, 0xae, 0xd9, 0x6c, 0x22,
0x1f, 0xb1, 0xf3, 0xd0, 0x42, 0x04, 0x35, 0x03, 0xff, 0x33, 0x85, 0x85, 0xa9, 0xbb,
0x98, 0x9c, 0x9d, 0xd4, 0x30, 0xd6, 0xd6, 0x0b,
],
},
TestVector {
@ -372,18 +369,18 @@ fn redjubjub_signatures() {
0x07, 0x07, 0x07, 0x07,
],
sig: [
0x64, 0x59, 0x67, 0x6a, 0x94, 0x16, 0x34, 0xec, 0xb6, 0x1e, 0x59, 0xb7, 0x9a, 0x98,
0xab, 0xe5, 0x87, 0x6f, 0x35, 0x6f, 0x72, 0x8a, 0xa0, 0x9e, 0x0c, 0xca, 0x9e, 0xfe,
0x05, 0x76, 0x1a, 0x33, 0x09, 0xaa, 0x88, 0xb2, 0xfa, 0x0e, 0xe2, 0xd0, 0x4c, 0x1c,
0x46, 0xe9, 0xf2, 0xa0, 0x48, 0xd5, 0x9d, 0x55, 0x65, 0xaf, 0xa6, 0xc3, 0xf1, 0x5b,
0xce, 0x70, 0x8d, 0xaa, 0xab, 0x7b, 0x34, 0x0e,
0x44, 0x6d, 0x67, 0x7c, 0x4c, 0xfe, 0xfd, 0x02, 0x4b, 0x0a, 0xeb, 0x37, 0xa5, 0x98,
0xcc, 0x2e, 0xb3, 0xd2, 0x9b, 0x02, 0x94, 0xfe, 0x5b, 0xb6, 0x97, 0x8e, 0x8b, 0x43,
0xd3, 0x2b, 0x2e, 0x4f, 0x09, 0x56, 0xac, 0xd1, 0x3e, 0x7e, 0x3a, 0x63, 0xa1, 0x8f,
0xca, 0x32, 0xd6, 0xab, 0x94, 0xb9, 0x4e, 0xd0, 0x33, 0xe9, 0xa1, 0x0f, 0xc5, 0x69,
0x28, 0xbc, 0x8a, 0x0f, 0x4f, 0x8e, 0x95, 0x00,
],
rsig: [
0xc9, 0x66, 0x84, 0xec, 0x7e, 0xa6, 0x0b, 0xde, 0x87, 0x88, 0x22, 0xdd, 0xca, 0xf6,
0xb8, 0xb0, 0xbd, 0x31, 0x98, 0x51, 0x54, 0xdf, 0x9a, 0xd4, 0xf6, 0x90, 0x7d, 0xf8,
0xfe, 0xd9, 0x5c, 0x1d, 0x84, 0xfe, 0x67, 0xe6, 0x78, 0x75, 0xa5, 0x39, 0x55, 0x0e,
0xb2, 0x51, 0x4f, 0x19, 0x3b, 0x8e, 0xd4, 0x57, 0x25, 0x6c, 0x8d, 0x30, 0x28, 0x1d,
0x6f, 0x8b, 0xb9, 0x54, 0x49, 0x24, 0xca, 0x0c,
0x8d, 0xe0, 0x41, 0xe7, 0x09, 0xdb, 0x62, 0x4a, 0xe2, 0xbe, 0x16, 0x48, 0xb6, 0x62,
0x23, 0x9c, 0xde, 0xdf, 0x85, 0xec, 0xd3, 0x82, 0x26, 0x8b, 0x0e, 0x35, 0x54, 0xbf,
0xa0, 0xf2, 0x08, 0x1c, 0xd6, 0x41, 0xbc, 0xa0, 0x40, 0x78, 0xaa, 0x89, 0xf7, 0xdd,
0x25, 0x40, 0x58, 0x7c, 0xed, 0x6b, 0x45, 0x89, 0x16, 0xb1, 0x3e, 0x4b, 0x6a, 0x36,
0x30, 0xda, 0x69, 0x76, 0x46, 0xdb, 0xbf, 0x09,
],
},
TestVector {
@ -418,18 +415,18 @@ fn redjubjub_signatures() {
0x08, 0x08, 0x08, 0x08,
],
sig: [
0x24, 0x93, 0x2c, 0x1f, 0xaa, 0x01, 0x63, 0xca, 0x9a, 0x7f, 0xcd, 0xe4, 0x76, 0x11,
0x29, 0xd2, 0xe5, 0xe9, 0x9c, 0xf5, 0xef, 0xa2, 0x5d, 0x27, 0x04, 0x58, 0x8e, 0x1c,
0x75, 0x67, 0x7b, 0x5e, 0xeb, 0xe4, 0x55, 0x04, 0x8d, 0x7c, 0xe1, 0xb0, 0xd2, 0x01,
0x27, 0x53, 0xf7, 0x1b, 0x27, 0x25, 0x01, 0x2e, 0xe1, 0x85, 0x49, 0x28, 0x73, 0x18,
0xf9, 0xcd, 0x73, 0xf0, 0x7f, 0x0f, 0xb5, 0x02,
0x99, 0x35, 0x80, 0xef, 0x93, 0x34, 0x9a, 0x1c, 0x9e, 0xe9, 0x60, 0xca, 0x3e, 0x7c,
0xd0, 0x4c, 0x13, 0xb4, 0xa0, 0xec, 0x4f, 0xd1, 0x80, 0x53, 0xa1, 0x9c, 0xff, 0x77,
0x63, 0x62, 0x09, 0x65, 0xfb, 0xee, 0x96, 0xc1, 0x64, 0x72, 0x30, 0xe3, 0x73, 0xcb,
0x82, 0xb8, 0x1d, 0x00, 0x03, 0x92, 0x23, 0xd3, 0x0b, 0x39, 0x3e, 0xd1, 0x72, 0xc9,
0xb3, 0xc5, 0x63, 0xc6, 0x11, 0x79, 0x22, 0x05,
],
rsig: [
0xf7, 0xfa, 0x26, 0xca, 0x22, 0xf3, 0x86, 0xc4, 0x3c, 0x19, 0x1a, 0x0b, 0x3e, 0xa6,
0x57, 0x7e, 0x8e, 0xea, 0xa3, 0xf3, 0x6b, 0x9b, 0xd1, 0xa3, 0xac, 0x3d, 0xf6, 0xf8,
0x83, 0xa3, 0xff, 0xdb, 0x31, 0x32, 0x0b, 0xde, 0x62, 0x7f, 0xf4, 0x6f, 0xc2, 0x26,
0x4a, 0x32, 0x63, 0xb9, 0xab, 0x67, 0x12, 0x3b, 0xa5, 0xe1, 0x08, 0x43, 0x20, 0xd9,
0x10, 0xb3, 0x94, 0xef, 0x8c, 0x65, 0xba, 0x09,
0xcc, 0x7a, 0xae, 0x1c, 0xed, 0xad, 0x2d, 0x7f, 0x6c, 0xe0, 0x4c, 0x19, 0xc5, 0xa5,
0xb6, 0xb7, 0xa6, 0xa0, 0x82, 0x78, 0x5c, 0x54, 0x0c, 0x14, 0xf6, 0x30, 0x9b, 0x06,
0x4d, 0x1f, 0xfa, 0x68, 0x17, 0x29, 0x53, 0xfb, 0xa0, 0xc2, 0xfc, 0xfb, 0x87, 0x5c,
0xa7, 0xf7, 0xea, 0x98, 0xef, 0x55, 0xa0, 0x40, 0x2f, 0xd5, 0x29, 0xcf, 0xcd, 0xdf,
0x99, 0x6c, 0xa2, 0xb8, 0xca, 0x89, 0x90, 0x0a,
],
},
TestVector {
@ -464,47 +461,37 @@ fn redjubjub_signatures() {
0x09, 0x09, 0x09, 0x09,
],
sig: [
0x64, 0xab, 0xd1, 0x25, 0xbf, 0xc4, 0xc6, 0x54, 0xfa, 0xf2, 0xb6, 0xdd, 0x75, 0x3e,
0xc6, 0x90, 0x22, 0x4d, 0xbc, 0xab, 0x8c, 0xd6, 0x32, 0xdd, 0x59, 0x3c, 0x91, 0xce,
0x3a, 0xb0, 0xbc, 0xad, 0xca, 0x92, 0x76, 0x34, 0x02, 0x1c, 0x31, 0x47, 0x6c, 0x78,
0xc5, 0xac, 0x7c, 0xcc, 0xab, 0xbd, 0x6f, 0x92, 0x7d, 0xf2, 0x05, 0xea, 0xa7, 0x07,
0xcc, 0x00, 0xd4, 0x7d, 0x39, 0xf3, 0xe4, 0x0c,
0xce, 0x90, 0xdd, 0xf4, 0xaf, 0x21, 0xaa, 0xc4, 0xd9, 0x41, 0x93, 0xea, 0x16, 0xff,
0x35, 0xcd, 0x93, 0x79, 0x20, 0x4e, 0x7d, 0x8f, 0xf4, 0xc0, 0xf5, 0x41, 0x17, 0xab,
0xb1, 0x6b, 0x7c, 0x85, 0xa0, 0xb1, 0x97, 0xcf, 0x13, 0xab, 0x14, 0xd7, 0xc3, 0xba,
0x68, 0x01, 0x0a, 0xb8, 0x05, 0x12, 0x25, 0x91, 0x3b, 0xdb, 0xc3, 0x9a, 0x51, 0xf6,
0x03, 0x7a, 0xfc, 0x6c, 0xee, 0xcb, 0x0b, 0x06,
],
rsig: [
0xeb, 0x7a, 0x06, 0x5d, 0x75, 0xf8, 0x45, 0xdc, 0x09, 0x41, 0xb7, 0x09, 0xc0, 0xb1,
0x49, 0xea, 0xfd, 0x80, 0x5e, 0xa5, 0x8f, 0x38, 0x0b, 0x92, 0xb9, 0xd3, 0x10, 0x8a,
0x56, 0x1b, 0xda, 0x17, 0x85, 0xdf, 0x8f, 0x10, 0x1e, 0x0e, 0x14, 0x0f, 0xca, 0xee,
0x99, 0xb7, 0xdb, 0xb7, 0xdf, 0xbf, 0x7e, 0x61, 0xf3, 0xa1, 0x2f, 0x46, 0x09, 0x50,
0x69, 0xe0, 0x6e, 0x88, 0x96, 0xa9, 0xe4, 0x04,
0xa8, 0x47, 0x74, 0x2e, 0x94, 0x01, 0xcf, 0x22, 0x39, 0x21, 0x3d, 0xc8, 0x81, 0x3e,
0x97, 0x72, 0xe9, 0x7a, 0xf8, 0xd6, 0x7a, 0xdf, 0xfe, 0xab, 0xc8, 0xe6, 0x7f, 0x5d,
0x2d, 0x90, 0xd0, 0xb4, 0x1b, 0xc2, 0x5b, 0x05, 0xf9, 0x4a, 0xce, 0x16, 0x8a, 0xec,
0xc6, 0x58, 0x3e, 0x18, 0xf7, 0x63, 0x74, 0x92, 0xf3, 0x7a, 0x9c, 0xa3, 0x00, 0x20,
0x2b, 0xc0, 0x65, 0xab, 0xd3, 0x80, 0xec, 0x00,
],
},
];
for tv in test_vectors {
let sk = PrivateKey::read(&tv.sk[..]).unwrap();
let vk = PublicKey::read(&tv.vk[..]).unwrap();
let rvk = PublicKey::read(&tv.rvk[..]).unwrap();
let sig = Signature::read(&tv.sig[..]).unwrap();
let rsig = Signature::read(&tv.rsig[..]).unwrap();
let sk = redjubjub::SigningKey::try_from(tv.sk).unwrap();
let vk = redjubjub::VerificationKey::try_from(tv.vk).unwrap();
let rvk = redjubjub::VerificationKey::try_from(tv.rvk).unwrap();
let sig = redjubjub::Signature::from(tv.sig);
let rsig = redjubjub::Signature::from(tv.rsig);
let alpha = jubjub::Scalar::from_bytes(&tv.alpha).unwrap();
{
let mut vec = Vec::new();
sk.randomize(alpha).write(&mut vec).unwrap();
assert_eq!(&vec, &tv.rsk);
}
{
let mut vec = Vec::new();
vk.randomize(alpha, SPENDING_KEY_GENERATOR)
.write(&mut vec)
.unwrap();
assert_eq!(&vec, &tv.rvk);
}
assert_eq!(<[u8; 32]>::from(sk.randomize(&alpha)), tv.rsk);
assert_eq!(<[u8; 32]>::from(vk.randomize(&alpha)), tv.rvk);
assert!(vk.verify(&tv.m, &sig, SPENDING_KEY_GENERATOR));
assert!(rvk.verify(&tv.m, &rsig, SPENDING_KEY_GENERATOR));
assert!(!vk.verify(&tv.m, &rsig, SPENDING_KEY_GENERATOR));
assert!(!rvk.verify(&tv.m, &sig, SPENDING_KEY_GENERATOR));
assert_eq!(vk.verify(&tv.m, &sig), Ok(()));
assert_eq!(rvk.verify(&tv.m, &rsig), Ok(()));
assert!(matches!(vk.verify(&tv.m, &rsig), Err(_)));
assert!(matches!(rvk.verify(&tv.m, &sig), Err(_)));
}
}

View File

@ -6,11 +6,12 @@ use blake2b_simd::Hash;
use libc::{c_uchar, size_t};
use tracing::error;
use zcash_encoding::Vector;
use zcash_primitives::transaction::components::amount::NonNegativeAmount;
use zcash_primitives::{
consensus::BranchId,
legacy::Script,
transaction::{
components::{sapling, transparent, Amount},
components::transparent,
sighash::{SignableInput, TransparentAuthorizingContext},
sighash_v5::v5_signature_hash,
txid::TxIdDigester,
@ -69,7 +70,7 @@ impl transparent::Authorization for TransparentAuth {
}
impl TransparentAuthorizingContext for TransparentAuth {
fn input_amounts(&self) -> Vec<Amount> {
fn input_amounts(&self) -> Vec<NonNegativeAmount> {
self.all_prev_outputs
.iter()
.map(|prevout| prevout.value)
@ -148,7 +149,7 @@ pub(crate) struct PrecomputedAuth;
impl Authorization for PrecomputedAuth {
type TransparentAuth = TransparentAuth;
type SaplingAuth = sapling::Authorized;
type SaplingAuth = sapling::bundle::Authorized;
type OrchardAuth = orchard::bundle::Authorized;
}

View File

@ -50,9 +50,7 @@ pub extern "C" fn unified_full_viewing_key_parse(
Fvk::Sapling(data) => {
// The last 32 bytes is the diversifier key, which is opaque.
// The remaining 96 bytes should be a valid Sapling FVK.
if zcash_primitives::sapling::keys::FullViewingKey::read(&data[..96])
.is_err()
{
if sapling::keys::FullViewingKey::read(&data[..96]).is_err() {
error!("Unified FVK contains invalid Sapling FVK");
return std::ptr::null_mut();
}

View File

@ -13,7 +13,6 @@ use zcash_encoding::{Optional, Vector};
use zcash_primitives::{
consensus::BlockHeight,
merkle_tree::{read_position, write_position},
sapling::NOTE_COMMITMENT_TREE_DEPTH,
transaction::{components::Amount, TxId},
};
@ -150,7 +149,8 @@ pub struct Wallet {
nullifiers: BTreeMap<Nullifier, OutPoint>,
/// The incremental Merkle tree used to track note commitments and witnesses for notes
/// belonging to the wallet.
commitment_tree: BridgeTree<MerkleHashOrchard, u32, NOTE_COMMITMENT_TREE_DEPTH>,
// TODO: Replace this with an `orchard` crate constant (they happen to be the same).
commitment_tree: BridgeTree<MerkleHashOrchard, u32, { sapling::NOTE_COMMITMENT_TREE_DEPTH }>,
/// The block height at which the last checkpoint was created, if any.
last_checkpoint: Option<BlockHeight>,
/// The block height and transaction index of the note most recently added to
@ -1370,7 +1370,10 @@ pub extern "C" fn orchard_wallet_load_note_commitment_tree(
#[no_mangle]
pub extern "C" fn orchard_wallet_init_from_frontier(
wallet: *mut Wallet,
frontier: *const bridgetree::Frontier<MerkleHashOrchard, NOTE_COMMITMENT_TREE_DEPTH>,
frontier: *const bridgetree::Frontier<
MerkleHashOrchard,
{ sapling::NOTE_COMMITMENT_TREE_DEPTH },
>,
) -> bool {
let wallet = unsafe { wallet.as_mut() }.expect("Wallet pointer may not be null.");
let frontier = unsafe { frontier.as_ref() }.expect("Wallet pointer may not be null.");

View File

@ -10,15 +10,12 @@ use std::sync::{
use crossbeam_channel as channel;
use memuse::DynamicUsage;
use sapling::{bundle::GrothProofBytes, note_encryption::SaplingDomain};
use zcash_note_encryption::{batch, BatchDomain, Domain, ShieldedOutput, ENC_CIPHERTEXT_SIZE};
use zcash_primitives::{
block::BlockHash,
consensus,
sapling::note_encryption::SaplingDomain,
transaction::{
components::{sapling::GrothProofBytes, OutputDescription},
Transaction, TxId,
},
transaction::{components::OutputDescription, Transaction, TxId},
};
use crate::{bridge::ffi, note_encryption::parse_and_prepare_sapling_ivk, params::Network};
@ -38,7 +35,7 @@ trait OutputDomain: BatchDomain {
const KIND: &'static str;
}
impl<P: consensus::Parameters> OutputDomain for SaplingDomain<P> {
impl OutputDomain for SaplingDomain {
const KIND: &'static str = "sapling";
}
@ -550,7 +547,7 @@ where
}
type SaplingRunner =
BatchRunner<[u8; 32], SaplingDomain<Network>, OutputDescription<GrothProofBytes>, WithUsage>;
BatchRunner<[u8; 32], SaplingDomain, OutputDescription<GrothProofBytes>, WithUsage>;
/// A batch scanner for the `zcashd` wallet.
pub(crate) struct BatchScanner {
@ -622,7 +619,7 @@ impl BatchScanner {
runner.add_outputs(
block_tag,
txid,
|| SaplingDomain::for_height(params, height),
|| SaplingDomain::new(consensus::sapling_zip212_enforcement(&params, height)),
bundle.shielded_outputs(),
);
}
@ -671,7 +668,7 @@ impl BatchScanner {
}
pub(crate) struct BatchResult {
sapling: HashMap<(TxId, usize), DecryptedNote<[u8; 32], SaplingDomain<Network>>>,
sapling: HashMap<(TxId, usize), DecryptedNote<[u8; 32], SaplingDomain>>,
}
impl BatchResult {

View File

@ -306,9 +306,10 @@ public:
// The Orchard bundle builder always pads to two Actions, so we can just
// use an empty builder to create a dummy Orchard bundle.
// TODO: With the new BundleType::DEFAULT this is no longer true. Fix this.
uint256 orchardAnchor;
uint256 dataToBeSigned;
auto builder = orchard::Builder(true, true, orchardAnchor);
auto builder = orchard::Builder(false, orchardAnchor);
mutableTx.orchardBundle = builder.Build().value().ProveAndSign({}, dataToBeSigned).value();
orchardNullifier = mutableTx.orchardBundle.GetNullifiers()[0];
@ -340,7 +341,7 @@ template<> void AppendRandomLeaf(OrchardMerkleFrontier &tree) {
// append a random leaf to OrchardMerkleFrontier.
uint256 orchardAnchor;
uint256 dataToBeSigned;
auto builder = orchard::Builder(true, true, orchardAnchor);
auto builder = orchard::Builder(false, orchardAnchor);
auto bundle = builder.Build().value().ProveAndSign({}, dataToBeSigned).value();
tree.AppendBundle(bundle);
}

View File

@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(zs_address_test)
KeyIO keyIO(Params());
for (uint32_t i = 0; i < 1000; i++) {
auto sk = m.Derive(i);
auto sk = m.Derive(i | HARDENED_KEY_LIMIT);
{
std::string sk_string = keyIO.EncodeSpendingKey(sk);
BOOST_CHECK(sk_string.compare(0, 27, Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY)) == 0);

View File

@ -48,11 +48,10 @@ uint256 ProduceShieldedSignatureHash(
namespace orchard {
Builder::Builder(
bool spendsEnabled,
bool outputsEnabled,
bool coinbase,
uint256 anchor) : inner(nullptr, orchard_builder_free)
{
inner.reset(orchard_builder_new(spendsEnabled, outputsEnabled, anchor.IsNull() ? nullptr : anchor.begin()));
inner.reset(orchard_builder_new(coinbase, anchor.IsNull() ? nullptr : anchor.begin()));
}
bool Builder::AddSpend(orchard::SpendInfo spendInfo)
@ -209,6 +208,7 @@ TransactionBuilder::TransactionBuilder(
const CChainParams& params,
int nHeight,
std::optional<uint256> orchardAnchor,
uint256 saplingAnchor,
const CKeyStore* keystore,
const CCoinsViewCache* coinsView,
CCriticalSection* cs_coinsView) :
@ -218,7 +218,8 @@ TransactionBuilder::TransactionBuilder(
coinsView(coinsView),
cs_coinsView(cs_coinsView),
orchardAnchor(orchardAnchor),
saplingBuilder(sapling::new_builder(*params.RustNetwork(), nHeight))
saplingAnchor(saplingAnchor),
saplingBuilder(sapling::new_builder(*params.RustNetwork(), nHeight, saplingAnchor.ToRawBytes(), false))
{
mtx = CreateNewContextualCMutableTransaction(
consensusParams, nHeight,
@ -226,7 +227,7 @@ TransactionBuilder::TransactionBuilder(
// Ignore the Orchard anchor if we can't use it yet.
if (orchardAnchor.has_value() && mtx.nVersion >= ZIP225_MIN_TX_VERSION) {
orchardBuilder = orchard::Builder(true, true, orchardAnchor.value());
orchardBuilder = orchard::Builder(false, orchardAnchor.value());
}
}
@ -329,7 +330,6 @@ void TransactionBuilder::AddSaplingSpend(
saplingBuilder->add_spend(
{reinterpret_cast<uint8_t*>(ssExtSk.data()), ssExtSk.size()},
note.d,
recipient.GetRawBytes(),
note.value(),
note.rcm().GetRawBytes(),
@ -525,7 +525,7 @@ TransactionBuilderResult TransactionBuilder::Build()
std::optional<rust::Box<sapling::UnauthorizedBundle>> maybeSaplingBundle;
try {
maybeSaplingBundle = sapling::build_bundle(std::move(saplingBuilder), nHeight);
maybeSaplingBundle = sapling::build_bundle(std::move(saplingBuilder));
} catch (rust::Error e) {
return TransactionBuilderResult("Failed to build Sapling bundle: " + std::string(e.what()));
}

View File

@ -91,7 +91,7 @@ private:
Builder() : inner(nullptr, orchard_builder_free), hasActions(false) { }
public:
Builder(bool spendsEnabled, bool outputsEnabled, uint256 anchor);
Builder(bool coinbase, uint256 anchor);
// Builder should never be copied
Builder(const Builder&) = delete;
@ -242,6 +242,7 @@ private:
std::optional<uint256> orchardAnchor;
std::optional<orchard::Builder> orchardBuilder;
CAmount valueBalanceOrchard = 0;
uint256 saplingAnchor;
rust::Box<sapling::Builder> saplingBuilder;
CAmount valueBalanceSapling = 0;
@ -268,6 +269,7 @@ public:
const CChainParams& params,
int nHeight,
std::optional<uint256> orchardAnchor,
uint256 saplingAnchor,
const CKeyStore* keyStore = nullptr,
const CCoinsViewCache* coinsView = nullptr,
CCriticalSection* cs_coinsView = nullptr);
@ -286,6 +288,7 @@ public:
orchardAnchor(std::move(builder.orchardAnchor)),
orchardBuilder(std::move(builder.orchardBuilder)),
valueBalanceOrchard(std::move(builder.valueBalanceOrchard)),
saplingAnchor(std::move(builder.saplingAnchor)),
saplingBuilder(std::move(builder.saplingBuilder)),
valueBalanceSapling(std::move(builder.valueBalanceSapling)),
orchardSpendingKeys(std::move(orchardSpendingKeys)),
@ -308,8 +311,10 @@ public:
cs_coinsView = std::move(builder.cs_coinsView);
mtx = std::move(builder.mtx);
fee = std::move(builder.fee);
orchardAnchor = std::move(builder.orchardAnchor);
orchardBuilder = std::move(builder.orchardBuilder);
valueBalanceOrchard = std::move(builder.valueBalanceOrchard);
saplingAnchor = std::move(builder.saplingAnchor);
saplingBuilder = std::move(builder.saplingBuilder);
valueBalanceSapling = std::move(builder.valueBalanceSapling);
orchardSpendingKeys = std::move(builder.orchardSpendingKeys),

View File

@ -352,8 +352,9 @@ CWalletTx GetValidSaplingReceive(const CChainParams& params,
// To zaddr
auto fvk = sk.expsk.full_viewing_key();
auto pa = sk.ToXFVK().DefaultAddress();
auto saplingAnchor = SaplingMerkleTree::empty_root();
auto builder = TransactionBuilder(params, 1, std::nullopt, &keyStore);
auto builder = TransactionBuilder(params, 1, std::nullopt, saplingAnchor, &keyStore);
builder.SetFee(0);
builder.AddTransparentInput(COutPoint(), scriptPubKey, value);
builder.AddSaplingOutput(fvk.ovk, pa, value, {});

View File

@ -16,7 +16,8 @@
const int MIGRATION_EXPIRY_DELTA = 450;
AsyncRPCOperation_saplingmigration::AsyncRPCOperation_saplingmigration(int targetHeight) : targetHeight_(targetHeight) {}
AsyncRPCOperation_saplingmigration::AsyncRPCOperation_saplingmigration(int targetHeight, uint256 saplingAnchor) :
targetHeight_(targetHeight), saplingAnchor_(saplingAnchor) {}
AsyncRPCOperation_saplingmigration::~AsyncRPCOperation_saplingmigration() {}
@ -112,7 +113,14 @@ bool AsyncRPCOperation_saplingmigration::main_impl() {
CCoinsViewCache coinsView(pcoinsTip);
do {
CAmount amountToSend = chooseAmount(availableFunds);
auto builder = TransactionBuilder(Params(), targetHeight_, std::nullopt, pwalletMain, &coinsView, &cs_main);
auto builder = TransactionBuilder(
Params(),
targetHeight_,
std::nullopt,
saplingAnchor_,
pwalletMain,
&coinsView,
&cs_main);
builder.SetExpiryHeight(targetHeight_ + MIGRATION_EXPIRY_DELTA);
LogPrint("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", getId(), FormatMoney(amountToSend - LEGACY_DEFAULT_FEE));
std::vector<SproutNoteEntry> fromNotes;

View File

@ -9,7 +9,7 @@
class AsyncRPCOperation_saplingmigration : public AsyncRPCOperation
{
public:
AsyncRPCOperation_saplingmigration(int targetHeight);
AsyncRPCOperation_saplingmigration(int targetHeight, uint256 saplingAnchor);
virtual ~AsyncRPCOperation_saplingmigration();
// We don't want to be copied or moved around
@ -28,6 +28,7 @@ public:
private:
int targetHeight_;
uint256 saplingAnchor_;
bool main_impl();

View File

@ -32,7 +32,7 @@ CTransaction FakeOrchardTx(const OrchardSpendingKey& sk, libzcash::diversifier_i
// Create a shielding transaction from transparent to Orchard
// 0.0005 t-ZEC in, 0.0004 z-ZEC out, 0.0001 fee
auto builder = TransactionBuilder(Params(), 1, orchardAnchor, &keystore);
auto builder = TransactionBuilder(Params(), 1, orchardAnchor, SaplingMerkleTree::empty_root(), &keystore);
builder.SetFee(10000);
builder.AddTransparentInput(COutPoint(uint256S("1234"), 0), scriptPubKey, 50000);
builder.AddOrchardOutput(std::nullopt, recipient, 40000, std::nullopt);
@ -129,7 +129,7 @@ TEST(TransactionBuilder, OrchardToOrchard) {
// Create an Orchard-only transaction
// 0.0004 z-ZEC in, 0.00025 z-ZEC out, default fee, 0.00014 z-ZEC change
auto builder = TransactionBuilder(Params(), 2, orchardAnchor);
auto builder = TransactionBuilder(Params(), 2, orchardAnchor, SaplingMerkleTree::empty_root());
EXPECT_TRUE(builder.AddOrchardSpend(sk, std::move(spendInfo[0].second)));
builder.AddOrchardOutput(std::nullopt, recipient, 25000, std::nullopt);
auto maybeTx = builder.Build();

View File

@ -330,65 +330,77 @@ TEST(WalletRPCTests, RPCZsendmanyTaddrToSapling)
ss >> tx;
ASSERT_NE(tx.GetSaplingOutputsCount(), 0);
auto outputs = tx.GetSaplingOutputs();
auto enc_ciphertext = outputs[0].enc_ciphertext();
auto out_ciphertext = outputs[0].out_ciphertext();
auto cv = outputs[0].cv();
auto cmu = outputs[0].cmu();
auto ephemeral_key = outputs[0].ephemeral_key();
// We shouldn't be able to decrypt with the empty ovk
EXPECT_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
uint256().GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}), rust::Error);
// We shouldn't be able to decrypt with a random ovk
EXPECT_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
random_uint256().GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}), rust::Error);
auto accountKey = pwalletMain->GetLegacyAccountKey().ToAccountPubKey();
auto ovks = accountKey.GetOVKsForShielding();
// We should not be able to decrypt with the internal change OVK for shielding
EXPECT_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
ovks.first.GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}), rust::Error);
// We should be able to decrypt with the external OVK for shielding
EXPECT_NO_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
ovks.second.GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}));
auto extDecryptSucceeded = 0;
auto extDecryptFailed = 0;
for (auto& output: tx.GetSaplingOutputs()) {
auto enc_ciphertext = output.enc_ciphertext();
auto out_ciphertext = output.out_ciphertext();
auto cv = output.cv();
auto cmu = output.cmu();
auto ephemeral_key = output.ephemeral_key();
// We shouldn't be able to decrypt with the empty ovk
EXPECT_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
uint256().GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}), rust::Error);
// We shouldn't be able to decrypt with a random ovk
EXPECT_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
random_uint256().GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}), rust::Error);
// We should not be able to decrypt with the internal change OVK for shielding
EXPECT_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
ovks.first.GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}), rust::Error);
// We should be able to decrypt one of the outputs with the external OVK for shielding.
try {
wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
ovks.second.GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
});
extDecryptSucceeded += 1;
} catch (...) {
extDecryptFailed += 1;
}
}
EXPECT_EQ(extDecryptSucceeded, 1);
EXPECT_EQ(extDecryptFailed, 1);
// Tear down
chainActive.SetTip(NULL);

View File

@ -421,13 +421,14 @@ TEST(WalletTests, SetSaplingNoteAddrsInCWalletTx) {
auto cm = note.cmu().value();
SaplingMerkleTree tree;
tree.append(cm);
auto anchor = tree.root();
auto witness = tree.witness();
auto nf = note.nullifier(fvk, witness.position());
ASSERT_TRUE(nf);
uint256 nullifier = nf.value();
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, anchor);
builder.AddSaplingSpend(sk, note, witness);
builder.AddSaplingOutput(fvk.ovk, pk, 50000, {});
builder.SetFee(0);
@ -564,7 +565,7 @@ TEST(WalletTests, FindMySaplingNotes) {
auto testNote = GetTestSaplingNote(pa, 50000);
// Generate transaction
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(extfvk.fvk.ovk, pa, 25000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -708,10 +709,11 @@ TEST(WalletTests, GetConflictedSaplingNotes) {
MerkleFrontiers frontiers;
frontiers.sapling.append(cm);
auto anchor = frontiers.sapling.root();
auto witness = frontiers.sapling.witness();
// Generate tx to create output note B
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, anchor);
builder.AddSaplingSpend(sk, note, witness);
builder.AddSaplingOutput(extfvk.fvk.ovk, pk, 35000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -758,13 +760,13 @@ TEST(WalletTests, GetConflictedSaplingNotes) {
auto nullifier2 = maybe_nf.value();
// Create transaction to spend note B
auto builder2 = TransactionBuilder(Params(), 2, std::nullopt);
auto builder2 = TransactionBuilder(Params(), 2, std::nullopt, spend_note_witness.root());
builder2.AddSaplingSpend(sk, note2, spend_note_witness);
builder2.AddSaplingOutput(extfvk.fvk.ovk, pk, 2000, {});
auto tx2 = builder2.Build().GetTxOrThrow();
// Create conflicting transaction which also spends note B
auto builder3 = TransactionBuilder(Params(), 2, std::nullopt);
auto builder3 = TransactionBuilder(Params(), 2, std::nullopt, spend_note_witness.root());
builder3.AddSaplingSpend(sk, note2, spend_note_witness);
builder3.AddSaplingOutput(extfvk.fvk.ovk, pk, 1999, {});
auto tx3 = builder3.Build().GetTxOrThrow();
@ -822,7 +824,7 @@ TEST(WalletTests, GetConflictedOrchardNotes) {
auto scriptPubKey = GetScriptForDestination(tkeyid);
// Generate a bundle containing output note A.
auto builder = TransactionBuilder(Params(), 1, orchardAnchor, &keystore);
auto builder = TransactionBuilder(Params(), 1, orchardAnchor, SaplingMerkleTree::empty_root(), &keystore);
builder.AddTransparentInput(COutPoint(uint256(), 0), scriptPubKey, 5000);
builder.AddOrchardOutput(std::nullopt, recipient, 4000, {});
auto maybeTx = builder.Build();
@ -876,7 +878,7 @@ TEST(WalletTests, GetConflictedOrchardNotes) {
auto recipient2 = ivk.Address(j2);
// Generate tx to spend note A
auto builder2 = TransactionBuilder(Params(), 2, orchardTree.root());
auto builder2 = TransactionBuilder(Params(), 2, orchardTree.root(), SaplingMerkleTree::empty_root());
auto noteToSpend = std::move(wallet.GetOrchardSpendInfo(orchardEntries, 1, orchardTree.root())[0]);
builder2.AddOrchardSpend(std::move(noteToSpend.first), std::move(noteToSpend.second));
auto maybeTx2 = builder2.Build();
@ -890,7 +892,7 @@ TEST(WalletTests, GetConflictedOrchardNotes) {
// Generate conflicting tx to spend note A
auto noteToSpend2 = std::move(wallet.GetOrchardSpendInfo(orchardEntries, 1, orchardTree.root())[0]);
auto builder3 = TransactionBuilder(Params(), 2, orchardTree.root());
auto builder3 = TransactionBuilder(Params(), 2, orchardTree.root(), SaplingMerkleTree::empty_root());
builder3.AddOrchardSpend(std::move(noteToSpend2.first), std::move(noteToSpend2.second));
auto maybeTx3 = builder3.Build();
EXPECT_TRUE(maybeTx3.IsTx());
@ -992,7 +994,7 @@ TEST(WalletTests, SaplingNullifierIsSpent) {
auto testNote = GetTestSaplingNote(pa, 50000);
// Generate transaction
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(extfvk.fvk.ovk, pa, 25000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -1079,7 +1081,7 @@ TEST(WalletTests, NavigateFromSaplingNullifierToNote) {
auto testNote = GetTestSaplingNote(pa, 50000);
// Generate transaction
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(extfvk.fvk.ovk, pa, 25000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -1214,10 +1216,11 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) {
auto cm = note.cmu().value();
MerkleFrontiers frontiers;
frontiers.sapling.append(cm);
auto anchor = frontiers.sapling.root();
auto witness = frontiers.sapling.witness();
// Generate transaction, which sends funds to note B
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, anchor);
builder.AddSaplingSpend(sk, note, witness);
builder.AddSaplingOutput(extfvk.fvk.ovk, pk, 25000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -1278,7 +1281,7 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) {
auto nullifier2 = maybe_nf.value();
// Create transaction to spend note B
auto builder2 = TransactionBuilder(Params(), 2, std::nullopt);
auto builder2 = TransactionBuilder(Params(), 2, std::nullopt, spend_note_witness.root());
builder2.AddSaplingSpend(sk, note2, spend_note_witness);
builder2.AddSaplingOutput(extfvk.fvk.ovk, pk, 12500, {});
auto tx2 = builder2.Build().GetTxOrThrow();
@ -2046,13 +2049,13 @@ TEST(WalletTests, UpdatedSaplingNoteData) {
auto m = GetTestMasterSaplingSpendingKey();
// Generate dummy Sapling address
auto sk = m.Derive(0);
auto sk = m.Derive(0 | HARDENED_KEY_LIMIT);
auto expsk = sk.expsk;
auto extfvk = sk.ToXFVK();
auto pa = extfvk.DefaultAddress();
// Generate dummy recipient Sapling address
auto sk2 = m.Derive(1);
auto sk2 = m.Derive(1 | HARDENED_KEY_LIMIT);
auto expsk2 = sk2.expsk;
auto extfvk2 = sk2.ToXFVK();
auto pa2 = extfvk2.DefaultAddress();
@ -2060,7 +2063,7 @@ TEST(WalletTests, UpdatedSaplingNoteData) {
auto testNote = GetTestSaplingNote(pa, 50000);
// Generate transaction
auto builder = TransactionBuilder(Params(), 1, std::nullopt);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, testNote.tree.root());
builder.AddSaplingSpend(sk, testNote.note, testNote.tree.witness());
builder.AddSaplingOutput(extfvk.fvk.ovk, pa2, 25000, {});
auto tx = builder.Build().GetTxOrThrow();
@ -2223,7 +2226,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) {
// Generate shielding tx from transparent to Sapling
// 0.0005 t-ZEC in, 0.0004 z-ZEC out, default fee
auto builder = TransactionBuilder(Params(), 1, std::nullopt, &keystore);
auto builder = TransactionBuilder(Params(), 1, std::nullopt, SaplingMerkleTree::empty_root(), &keystore);
builder.AddTransparentInput(
COutPoint(uint256S("7777777777777777777777777777777777777777777777777777777777777777"), 0),
scriptPubKey, 5000);
@ -2234,7 +2237,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) {
EXPECT_EQ(tx1.vout.size(), 0);
EXPECT_EQ(tx1.vJoinSplit.size(), 0);
EXPECT_EQ(tx1.GetSaplingSpendsCount(), 0);
EXPECT_EQ(tx1.GetSaplingOutputsCount(), 1);
EXPECT_EQ(tx1.GetSaplingOutputsCount(), 2);
EXPECT_EQ(tx1.GetValueBalanceSapling(), -4000);
CWalletTx wtx {&wallet, tx1};
@ -2269,17 +2272,23 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) {
wtx = wallet.mapWallet[hash];
// Prepare to spend the note that was just created
auto maybe_pt = wtx.DecryptSaplingNote(Params(), SaplingOutPoint(hash, 0));
auto outpt = SaplingOutPoint(hash, 0);
auto maybe_pt = wtx.DecryptSaplingNote(Params(), outpt);
if (!static_cast<bool>(maybe_pt)) {
outpt = SaplingOutPoint(hash, 1);
maybe_pt = wtx.DecryptSaplingNote(Params(), outpt);
}
ASSERT_EQ(static_cast<bool>(maybe_pt), true);
auto maybe_note = maybe_pt.value().first.note(ivk);
ASSERT_EQ(static_cast<bool>(maybe_note), true);
auto note = maybe_note.value();
auto anchor = frontiers.sapling.root();
auto witness = frontiers.sapling.witness();
auto witness = wtx.mapSaplingNoteData[outpt].witnesses.back();
ASSERT_EQ(anchor, witness.root());
// Create a Sapling-only transaction
// 0.0004 z-ZEC in, 0.00025 z-ZEC out, default fee, 0.00005 z-ZEC change
auto builder2 = TransactionBuilder(Params(), 2, std::nullopt);
auto builder2 = TransactionBuilder(Params(), 2, std::nullopt, anchor);
builder2.AddSaplingSpend(sk, note, witness);
builder2.AddSaplingOutput(extfvk.fvk.ovk, pk, 2500, {});
auto tx2 = builder2.Build().GetTxOrThrow();

View File

@ -48,7 +48,7 @@ TEST(WalletZkeysTest, StoreAndLoadSaplingZkeys) {
// manually add new spending key to wallet
auto m = libzcash::SaplingExtendedSpendingKey::Master(seed);
auto sk = m.Derive(0);
auto sk = m.Derive(0 | HARDENED_KEY_LIMIT);
ASSERT_TRUE(wallet.AddSaplingZKey(sk));
// verify wallet did add it
@ -88,7 +88,7 @@ TEST(WalletZkeysTest, StoreAndLoadSaplingZkeys) {
EXPECT_TRUE(wallet.HaveSaplingIncomingViewingKey(dpa));
// Load a third key into the wallet
auto sk2 = m.Derive(1);
auto sk2 = m.Derive(1 | HARDENED_KEY_LIMIT);
ASSERT_TRUE(wallet.LoadSaplingZKey(sk2));
// attach metadata to this third key

View File

@ -691,7 +691,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
BOOST_CHECK_EQUAL(retValue.get_str(), testKey);
// create a random Sapling key locally; split between IVKs and spending keys.
auto testSaplingSpendingKey = m.Derive(i);
auto testSaplingSpendingKey = m.Derive(i | HARDENED_KEY_LIMIT);
auto testSaplingPaymentAddress = testSaplingSpendingKey.ToXFVK().DefaultAddress();
if (i % 2 == 0) {
std::string testSaplingAddr = keyIO.EncodePaymentAddress(testSaplingPaymentAddress);
@ -1204,7 +1204,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
// Mutable tx containing contextual information we need to build tx
UniValue retValue = CallRPC("getblockcount");
int nHeight = retValue.get_int();
TransactionBuilder builder(Params(), nHeight + 1, std::nullopt, pwalletMain);
TransactionBuilder builder(Params(), nHeight + 1, std::nullopt, SaplingMerkleTree::empty_root(), pwalletMain);
}
BOOST_AUTO_TEST_CASE(asyncrpcoperation_sign_send_raw_transaction) {

View File

@ -1481,7 +1481,11 @@ void CWallet::RunSaplingMigration(int blockHeight) {
lastOperation->cancel();
}
pendingSaplingMigrationTxs.clear();
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_saplingmigration(blockHeight + 5));
auto targetHeight = blockHeight + 5;
auto anchorBlockIndex = chainActive[blockHeight - 5];
assert(anchorBlockIndex != nullptr);
auto saplingAnchor = anchorBlockIndex->hashFinalSaplingRoot;
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_saplingmigration(targetHeight, saplingAnchor));
saplingMigrationOperationId = operation->getId();
q->addOperation(operation);
} else if (blockHeight % 500 == 499) {

View File

@ -937,9 +937,6 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
orchardAnchor = anchorBlockIndex->hashFinalOrchardRoot;
}
auto builder = TransactionBuilder(params, nextBlockHeight, orchardAnchor, &wallet);
builder.SetFee(fee);
// Track the total of notes that we've added to the builder. This
// shouldn't strictly be necessary, given `spendable.LimitToAmount`
CAmount totalSpend = 0;
@ -984,6 +981,9 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
}
}
auto builder = TransactionBuilder(params, nextBlockHeight, orchardAnchor, saplingAnchor, &wallet);
builder.SetFee(fee);
// Add Orchard spends
for (size_t i = 0; i < orchardSpendInfo.size(); i++) {
auto spendInfo = std::move(orchardSpendInfo[i]);

View File

@ -55,28 +55,6 @@ std::optional<uint32_t> diversifier_index_t::ToTransparentChildIndex() const {
}
}
//
// SaplingExtendedFullViewingKey
//
std::optional<SaplingExtendedFullViewingKey> SaplingExtendedFullViewingKey::Derive(uint32_t i) const
{
CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
ss_p << *this;
std::array<unsigned char, ZIP32_XFVK_SIZE> p_bytes;
std::copy(ss_p.begin(), ss_p.end(), p_bytes.begin());
try {
auto i_bytes = sapling::zip32::xfvk_derive(p_bytes, i);
CDataStream ss_i(i_bytes, SER_NETWORK, PROTOCOL_VERSION);
SaplingExtendedFullViewingKey xfvk_i;
ss_i >> xfvk_i;
return xfvk_i;
} catch (rust::Error) {
return std::nullopt;
}
}
//
// SaplingDiversifiableFullViewingKey
//
@ -173,6 +151,10 @@ SaplingExtendedSpendingKey SaplingExtendedSpendingKey::Master(const HDSeed& seed
SaplingExtendedSpendingKey SaplingExtendedSpendingKey::Derive(uint32_t i) const
{
if (i < HARDENED_KEY_LIMIT) {
throw std::runtime_error("non-hardened derivation is unsupported");
}
CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
ss_p << *this;
std::array<unsigned char, ZIP32_XSK_SIZE> p_bytes;

View File

@ -257,8 +257,6 @@ public:
READWRITE(dk);
}
std::optional<SaplingExtendedFullViewingKey> Derive(uint32_t i) const;
friend inline bool operator==(const SaplingExtendedFullViewingKey& a, const SaplingExtendedFullViewingKey& b) {
return (
a.depth == b.depth &&

View File

@ -759,6 +759,7 @@ double benchmark_create_sapling_spend()
auto maybe_cmu = note.cmu();
tree.append(maybe_cmu.value());
auto witness = tree.witness();
auto anchor = tree.root().GetRawBytes();
CDataStream ssExtSk(SER_NETWORK, PROTOCOL_VERSION);
ssExtSk << sk;
@ -769,10 +770,9 @@ double benchmark_create_sapling_spend()
std::move(ss.begin(), ss.end(), witnessChars.begin());
auto nHeight = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight;
auto builder = sapling::new_builder(*Params().RustNetwork(), nHeight);
auto builder = sapling::new_builder(*Params().RustNetwork(), nHeight, anchor, false);
builder->add_spend(
{reinterpret_cast<uint8_t*>(ssExtSk.data()), ssExtSk.size()},
note.d,
address.GetRawBytes(),
note.value(),
note.rcm().GetRawBytes(),
@ -781,7 +781,7 @@ double benchmark_create_sapling_spend()
struct timeval tv_start;
timer_start(tv_start);
auto result = sapling::build_bundle(std::move(builder), nHeight);
auto result = sapling::build_bundle(std::move(builder));
double t = timer_stop(tv_start);
return t;
@ -791,9 +791,10 @@ double benchmark_create_sapling_output()
{
auto sk = libzcash::SaplingSpendingKey::random();
auto address = sk.default_address();
auto anchor = SaplingMerkleTree::empty_root().GetRawBytes();
auto nHeight = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight;
auto builder = sapling::new_builder(*Params().RustNetwork(), nHeight);
auto builder = sapling::new_builder(*Params().RustNetwork(), nHeight, anchor, false);
builder->add_recipient(
uint256().GetRawBytes(),
address.GetRawBytes(),
@ -803,7 +804,7 @@ double benchmark_create_sapling_output()
struct timeval tv_start;
timer_start(tv_start);
auto result = sapling::build_bundle(std::move(builder), nHeight);
auto result = sapling::build_bundle(std::move(builder));
double t = timer_stop(tv_start);
return t;

View File

@ -1,7 +1,7 @@
//! Rust bindings for Zcash transparent scripts.
#![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")]
#![doc(html_root_url = "https://docs.rs/zcash_script/0.1.15")]
#![doc(html_root_url = "https://docs.rs/zcash_script/0.1.16")]
#![allow(missing_docs)]
#![allow(clippy::needless_lifetimes)]
#![allow(non_upper_case_globals)]
@ -17,14 +17,18 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
// Include the items from depend/zcash/src/rust/src/rustzcash.rs (librustzcash/lib.rs)
// that we need
use ::sapling::circuit::{
OutputParameters, OutputVerifyingKey, SpendParameters, SpendVerifyingKey,
};
/// The code that uses this constant is not called by zcash_script.
static mut SAPLING_SPEND_VK: Option<bellman::groth16::VerifyingKey<bls12_381::Bls12>> = None;
static mut SAPLING_SPEND_VK: Option<SpendVerifyingKey> = None;
/// The code that uses this constant is not called by zcash_script.
static mut SAPLING_OUTPUT_VK: Option<bellman::groth16::VerifyingKey<bls12_381::Bls12>> = None;
static mut SAPLING_OUTPUT_VK: Option<OutputVerifyingKey> = None;
/// The code that uses this constant is not called by zcash_script.
static mut SAPLING_SPEND_PARAMS: Option<bellman::groth16::Parameters<bls12_381::Bls12>> = None;
static mut SAPLING_SPEND_PARAMS: Option<SpendParameters> = None;
/// The code that uses this constant is not called by zcash_script.
static mut SAPLING_OUTPUT_PARAMS: Option<bellman::groth16::Parameters<bls12_381::Bls12>> = None;
static mut SAPLING_OUTPUT_PARAMS: Option<OutputParameters> = None;
/// The code that uses this constant is not called by zcash_script.
static mut ORCHARD_PK: Option<orchard::circuit::ProvingKey> = None;

View File

@ -22,16 +22,3 @@ index c5cd6b173c..1da334b377 100644
return cache;
}
} // namespace libzcash
diff --git a/depend/zcash/src/zcash/cache.h b/depend/zcash/src/zcash/cache.h
index 9bef1e43b5..283123bec9 100644
--- a/depend/zcash/src/zcash/cache.h
+++ b/depend/zcash/src/zcash/cache.h
@@ -31,7 +31,7 @@ public:
{
static_assert(hash_select < 8, "BundleCacheHasher only has 8 hashes available.");
uint32_t u;
- std::memcpy(&u, key.begin() + 4 * hash_select, 4);
+ std::memcpy(&u, key.data() + 4 * hash_select, 4);
return u;
}
};