v0.1.14 release (#102)

* rm zcash

* Squashed 'depend/zcash/' content from commit e08571476

git-subtree-dir: depend/zcash
git-subtree-split: e08571476d8a59d0a624da7b118ab8d8ad2a6246

* delete zcash/Cargo.toml

* update versions

* update build

* make sapling.rs work by renaming it and copying it to OUT_DIR

* cargo fmt

---------

Co-authored-by: Conrado Gouvea <conradoplg@gmail.com>
This commit is contained in:
Alfredo Garcia 2023-10-17 16:03:37 -03:00 committed by GitHub
parent 36de9309bf
commit 3fdf588c23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 4302 additions and 4507 deletions

34
Cargo.lock generated
View File

@ -216,9 +216,9 @@ dependencies = [
[[package]]
name = "bridgetree"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a813dadc684e4c78a4547757debd99666282545d90e4ccc3210913ed4337ad2"
checksum = "fbfcb6c5a091e80cb3d3b0c1a7f126af4631cd5065b1f9929b139f1be8f3fb62"
dependencies = [
"incrementalmerkletree",
]
@ -411,9 +411,9 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.95"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "109308c20e8445959c2792e81871054c6a17e6976489a93d2769641a2ba5839c"
checksum = "bbe98ba1789d56fb3db3bee5e032774d4f421b685de7ba703643584ba24effbe"
dependencies = [
"cc",
"cxxbridge-flags",
@ -435,15 +435,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.95"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "882074421238e84fe3b4c65d0081de34e5b323bf64555d3e61991f76eb64a7bb"
checksum = "20888d9e1d2298e2ff473cee30efe7d5036e437857ab68bbfea84c74dba91da2"
[[package]]
name = "cxxbridge-macro"
version = "1.0.95"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a076022ece33e7686fb76513518e219cca4fce5750a8ae6d1ce6c0f48fd1af9"
checksum = "2fa16a70dd58129e4dfffdff535fb1bce66673f7bbeec4a5a1765a504e1ccd84"
dependencies = [
"proc-macro2",
"quote",
@ -674,9 +674,9 @@ dependencies = [
[[package]]
name = "incrementalmerkletree"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb91780c91bfc79769006a55c49127b83e1c1a6cf2b3b149ce3f247cbe342f0"
checksum = "361c467824d4d9d4f284be4b2608800839419dccc4d4608f28345237fe354623"
dependencies = [
"either",
"proptest",
@ -923,9 +923,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "orchard"
version = "0.5.0"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4e7a52f510cb8c39e639e662a353adbaf86025478af89ae54a0551f8ca35e2"
checksum = "5d31e68534df32024dcc89a8390ec6d7bef65edd87d91b45cfb481a2eb2d77c5"
dependencies = [
"aes",
"bitvec",
@ -1784,9 +1784,9 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.12.0"
version = "0.13.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de1a231e6a58d3dcdd6e21d229db33d7c10f9b54d8c170e122b267f6826bb48f"
checksum = "0cc4391d9325e0a51a7cbff02b5c4b5472d66087bd9c903ddb12dea7ec22f3e0"
dependencies = [
"aes",
"bip0039",
@ -1821,16 +1821,15 @@ dependencies = [
[[package]]
name = "zcash_proofs"
version = "0.12.1"
version = "0.13.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59d2e066a717f28451a081f2ebd483ddda896cf00d572972c10979d645ffa6c4"
checksum = "48f22eff3bdc382327ef28f809024ddc89ec6d903ba71be629b2cbea34afdda2"
dependencies = [
"bellman",
"blake2b_simd",
"bls12_381",
"group",
"home",
"incrementalmerkletree",
"jubjub",
"known-folders",
"lazy_static",
@ -1848,6 +1847,7 @@ dependencies = [
"bellman",
"bindgen",
"blake2b_simd",
"blake2s_simd",
"bls12_381",
"bridgetree",
"byteorder",

View File

@ -53,17 +53,18 @@ external-secp = []
# https://github.com/zcash/zcash/blob/<git subtree version>/Cargo.toml
bellman = "0.14"
blake2b_simd = "1"
blake2s_simd = "1"
bls12_381 = "0.8"
byteorder = "1"
crossbeam-channel = "0.5"
cxx = { version = "=1.0.95", features = ["c++17"] }
cxx = { version = "=1.0.107", features = ["c++17"] }
group = "0.13"
incrementalmerkletree = "0.4"
incrementalmerkletree = "0.5"
jubjub = "0.10"
libc = "0.2"
memuse = "0.2"
metrics = "0.21"
orchard = "0.5"
orchard = "0.6"
rand_core = "0.6"
rayon = "1.5"
subtle = "2.2"
@ -71,9 +72,9 @@ tracing = "0.1"
zcash_address = "0.3"
zcash_encoding = "0.2"
zcash_note_encryption = "0.4"
zcash_primitives = { version = "0.12", features = ["temporary-zcashd", "transparent-inputs"] }
zcash_proofs = "0.12"
bridgetree = "0.3"
zcash_primitives = { version = "=0.13.0-rc.1", features = ["temporary-zcashd", "transparent-inputs"] }
zcash_proofs = { version = "=0.13.0-rc.1", features = ["directories"] }
bridgetree = "0.4"
rand = "0.8"
[build-dependencies]
@ -86,9 +87,9 @@ 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.79", features = ["parallel"] }
cc = { version = "1.0.83", features = ["parallel"] }
# Treat minor versions with a zero major version as compatible (cargo doesn't by default).
cxx-gen = ">= 0.7.93"
cxx-gen = ">= 0.7.107"
syn = { version = "1.0.109", features = ["full", "printing"] }
[dev-dependencies]
@ -98,8 +99,8 @@ syn = { version = "1.0.109", features = ["full", "printing"] }
# Treat minor versions with a zero major version as compatible (cargo doesn't by default).
hex = ">= 0.4.3"
lazy_static = "1.4.0"
incrementalmerkletree = { version = "0.4", features = ["test-dependencies"] }
zcash_primitives = { version = "0.12", features = ["temporary-zcashd", "transparent-inputs", "test-dependencies"] }
incrementalmerkletree = { version = "0.5", features = ["test-dependencies"] }
zcash_primitives = { version = "=0.13.0-rc.1", features = ["temporary-zcashd", "transparent-inputs", "test-dependencies"] }
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"

View File

@ -69,7 +69,14 @@ fn gen_cxxbridge() -> Result<()> {
let header_out_path = PathBuf::from(&out_path).join("include").join("rust");
// These must match `CXXBRIDGE_RS` in depend/zcash/src/Makefile.am
let filenames = ["blake2b", "ed25519", "equihash", "streams", "bridge"];
let filenames = [
"blake2b",
"ed25519",
"equihash",
"streams",
"bridge",
"sapling/zip32",
];
// The output folder must exist
fs::create_dir_all(&src_out_path).unwrap();
@ -103,16 +110,15 @@ fn gen_cxxbridge() -> Result<()> {
)
});
fs::write(
header_out_path.join(format!("{}.h", filename)),
output.header,
)
.unwrap();
fs::write(
src_out_path.join(format!("{}.c", filename)),
output.implementation,
)
.unwrap();
let header_path = header_out_path.join(format!("{}.h", filename));
// Create output dir if does not exist (since `filename` can have a subdir)
fs::create_dir_all(header_path.parent().unwrap()).unwrap();
fs::write(header_path, output.header).unwrap();
let src_path = src_out_path.join(format!("{}.c", filename));
// Create output dir if does not exist (since `filename` can have a subdir)
fs::create_dir_all(src_path.parent().unwrap()).unwrap();
fs::write(src_path, output.implementation).unwrap();
}
Ok(())
}
@ -121,6 +127,43 @@ fn main() -> Result<()> {
bindgen_headers()?;
gen_cxxbridge()?;
let rust_path = env::var("OUT_DIR").map_err(Error::Env)?;
let rust_path = PathBuf::from(rust_path).join("rust");
// We want to compile `depend/zcash/src/rust/src/sapling.rs`, which we used
// to do in `src/sapling.rs` by just including it. However, now that it has
// submodules, that approach doesn't work because for some reason Rust
// searches for the submodules in `depend/zcash/src/rust/src/` instead of
// `depend/zcash/src/rust/src/sapling/` where they are located. This can
// be solved if `depend/zcash/src/rust/src/sapling.rs` is renamed to
// `depend/zcash/src/rust/src/sapling/mod.rs`. But we can't do that directly
// because we can't change the source tree inside `build.rs`. Therefore we
// copy the required files to OUT_DIR, with a renamed sapling.rs, and include
// the copied file instead (see src/sapling.rs).
// See also https://stackoverflow.com/questions/77310390/how-to-include-a-source-file-that-has-modules
fs::create_dir_all(rust_path.join("sapling")).unwrap();
for filename in &["sapling.rs", "sapling/spec.rs", "sapling/zip32.rs"] {
println!(
"cargo:rerun-if-changed=depend/zcash/src/rust/src/{}.rs",
filename
);
}
fs::copy(
"depend/zcash/src/rust/src/sapling.rs",
rust_path.join("sapling/mod.rs"),
)
.unwrap();
fs::copy(
"depend/zcash/src/rust/src/sapling/spec.rs",
rust_path.join("sapling/spec.rs"),
)
.unwrap();
fs::copy(
"depend/zcash/src/rust/src/sapling/zip32.rs",
rust_path.join("sapling/zip32.rs"),
)
.unwrap();
let gen_path = env::var("OUT_DIR").map_err(Error::Env)?;
let gen_path = PathBuf::from(gen_path).join("gen");

View File

@ -14,5 +14,14 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
id: toolchain
- run: rustup override set ${{steps.toolchain.outputs.name}}
- run: cargo install cargo-vet --version ~0.6
- run: cargo install cargo-vet --version ~0.8
- run: cargo vet --locked
cargo-deny:
name: Check licenses
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: EmbarkStudios/cargo-deny-action@v1
with:
command: check licenses

View File

@ -56,7 +56,7 @@ jobs:
- name: Install cross-compilation build dependencies
if: matrix.cross_deps != ''
run: sudo apt install ${{ matrix.cross_deps }}
run: sudo apt update && sudo apt install ${{ matrix.cross_deps }}
- name: Configure MinGW to use POSIX variant
if: matrix.name == 'mingw32'
@ -85,12 +85,17 @@ jobs:
restore-keys: |
${{ matrix.name }}-ccache-
- name: Get the number of available processing cores
id: nproc
shell: bash
run: echo "count=$(nproc 2> /dev/null || sysctl -n hw.logicalcpu)" >> "$GITHUB_OUTPUT"
- name: Build zcashd
id: build
run: >
${{ matrix.host }}
./zcutil/build.sh
-j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
-j"${{ steps.nproc.outputs.count }}"
- name: Build zcashd with libraries enabled
if: ${{ always() && steps.build.outcome == 'success' }}
@ -98,7 +103,7 @@ jobs:
CONFIGURE_FLAGS="--with-libs"
${{ matrix.host }}
./zcutil/build.sh
-j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
-j"${{ steps.nproc.outputs.count }}"
- name: Build zcashd with wallet disabled
if: ${{ always() && steps.build.outcome == 'success' }}
@ -106,7 +111,7 @@ jobs:
CONFIGURE_FLAGS="--disable-wallet"
${{ matrix.host }}
./zcutil/build.sh
-j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
-j"${{ steps.nproc.outputs.count }}"
- name: Build zcashd with mining disabled
if: ${{ always() && steps.build.outcome == 'success' }}
@ -114,4 +119,4 @@ jobs:
CONFIGURE_FLAGS="--disable-mining"
${{ matrix.host }}
./zcutil/build.sh
-j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
-j"${{ steps.nproc.outputs.count }}"

View File

@ -40,6 +40,10 @@ jobs:
if: always()
continue-on-error: true # Temporary until we get this passing
- name: make dist
run: ./test/lint/lint-make-dist.sh
if: always()
- name: Shebang
run: ./test/lint/lint-shebang.sh
if: always()

883
depend/zcash/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
Zcash 5.6.1
Zcash 5.7.0
<img align="right" width="120" height="80" src="doc/imgs/logo.png">
===========

View File

@ -1,8 +1,8 @@
dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 5)
define(_CLIENT_VERSION_MINOR, 6)
define(_CLIENT_VERSION_REVISION, 1)
define(_CLIENT_VERSION_MINOR, 7)
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)))
define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1)))

View File

@ -1,35 +0,0 @@
FROM electriccoinco/zcashd-build-centos8
# Buildbot user
ARG BUILDBOT_USER=zcbbworker
ARG BUILDBOT_UID=2001
RUN useradd --home-dir /home/$BUILDBOT_USER \
--shell /bin/bash \
--create-home \
--uid $BUILDBOT_UID\
$BUILDBOT_USER
USER $BUILDBOT_USER
WORKDIR /home/$BUILDBOT_USER
ADD bbworker-requirements.txt requirements.txt
RUN python3 -m venv venv \
&& . venv/bin/activate \
&& python -m pip install wheel \
&& python -m pip install -r requirements.txt
# Buildbot worker
ARG BUILDBOT_WORKER_NAME=centos8-docker
ARG BUILDBOT_WORKER_PASS=thisgetssetwhenpodisstarted
ARG BUILDBOT_MASTER_HOST=dev-ci.z.cash
ARG BUILDBOT_MASTER_PORT=9899
WORKDIR /home/$BUILDBOT_USER
RUN venv/bin/buildbot-worker create-worker $BUILDBOT_WORKER_NAME \
$BUILDBOT_MASTER_HOST:$BUILDBOT_MASTER_PORT \
$BUILDBOT_WORKER_NAME $BUILDBOT_WORKER_PASS \
&& echo "OS: Centos 8" > $BUILDBOT_WORKER_NAME/info/host
ADD bbworker-buildbot.tac $BUILDBOT_WORKER_NAME/buildbot.tac
WORKDIR /home/$BUILDBOT_USER/$BUILDBOT_WORKER_NAME
CMD ["/usr/bin/dumb-init", "../venv/bin/twistd", "--pidfile=", "-ny", "buildbot.tac"]

View File

@ -1,14 +0,0 @@
FROM centos:8
RUN yum update -y \
&& dnf group install -y "Development Tools" \
&& yum install -y \
ncurses-compat-libs \
python3 \
python3-devel \
wget
RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64
RUN chmod +x /usr/bin/dumb-init
RUN alternatives --set python /usr/bin/python3 \
&& python3 -m pip install virtualenv

View File

@ -38,5 +38,4 @@ Currently available images are hosted at https://hub.docker.com/r/electriccoinco
Additional buildbot workers for Centos8 and Arch.
- Dockerfile-bbworker.arch
- Dockerfile-bbworker.centos8

View File

@ -49,12 +49,6 @@ docker push electriccoinco/zcashd-gitian-ubuntu2004
docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=2004 -t electriccoinco/zcashd-bbworker-ubuntu2004
docker push electriccoinco/zcashd-bbworker-ubuntu2004
# Centos8
docker build . -f Dockerfile-build.centos8 -t electriccoinco/zcashd-build-centos8
docker build . -f Dockerfile-bbworker.centos8 -t electriccoinco/zcashd-bbworker-centos8
docker push electriccoinco/zcashd-build-centos8
docker push electriccoinco/zcashd-bbworker-centos8
# Arch 20200908
docker build . -f Dockerfile-build.arch --build-arg ARCHLINUX_TAG=20200908 -t electriccoinco/zcashd-build-arch
docker build . -f Dockerfile-bbworker.arch -t electriccoinco/zcashd-bbworker-arch

View File

@ -1,14 +0,0 @@
FROM centos:8
RUN yum update -y \
&& dnf group install -y "Development Tools" \
&& yum install -y \
ncurses-compat-libs \
python3 \
python3-devel \
wget
RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64
RUN chmod +x /usr/bin/dumb-init
RUN alternatives --set python /usr/bin/python3 \
&& python3 -m pip install virtualenv

View File

@ -31,5 +31,4 @@ Currently available images are hosted at https://hub.docker.com/r/electriccoinco
Additional Tekton base builders for Centos8 and Arch. Can be used with `Dockerfile-tekton-worker` to create Tekton workers.
- Dockerfile-build.arch
- Dockerfile-build.centos8

View File

@ -45,13 +45,6 @@ docker push electriccoinco/zcashd-build-ubuntu2004
docker build . -f Dockerfile-tekton-worker --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=2004 -t electriccoinco/zcashd-worker-ubuntu2004
docker push electriccoinco/zcashd-worker-ubuntu2004
# Centos8
docker build . -f Dockerfile-build.centos8 -t electriccoinco/zcashd-build-centos8
docker push electriccoinco/zcashd-build-centos8
docker build . -f Dockerfile-tekton-worker --build-arg FROMBASEOS=centos --build-arg FROMBASEOS_BUILD_TAG=8 -t electriccoinco/zcashd-worker-centos8
docker push electriccoinco/zcashd-worker-centos8
# Arch 20210418.0.20194
docker build . -f Dockerfile-build.arch --build-arg FROMBASEOS=archlinux --build-arg FROMBASEOS_BUILD_TAG=base-20210418.0.20194 -t electriccoinco/zcashd-build-archlinux
docker push electriccoinco/zcashd-build-archlinux

View File

@ -1,3 +1,15 @@
zcash (5.7.0) stable; urgency=medium
* 5.7.0 release.
-- Electric Coin Company <team@electriccoin.co> Thu, 28 Sep 2023 18:22:50 +0000
zcash (5.7.0~rc1) stable; urgency=medium
* 5.7.0-rc1 release.
-- Electric Coin Company <team@electriccoin.co> Fri, 22 Sep 2023 20:31:30 +0000
zcash (5.6.1) stable; urgency=medium
* 5.6.1 release.

View File

@ -240,7 +240,7 @@ License: WTFPL
Files: depends/*/vendored-sources/unicode-ident/src/tables.rs
Copyright: 1991-2022 Unicode, Inc
License: Unicode
License: Unicode-DFS-2016
Comment: This entry is for code in the unicode-ident crate generated from Unicode data tables.
The license of the unicode-ident crate itself is MIT/Expat or Apache-2.0.
@ -1922,7 +1922,7 @@ License: BOSL-1
a notice of your own that is not confusingly similar to the notice in this
License.
License: Unicode
License: Unicode-DFS-2016
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
.
See Terms of Use <https://www.unicode.org/copyright.html>

View File

@ -3,7 +3,7 @@ FROM debian:11
RUN apt-get update \
&& apt-get install -y gnupg2 apt-transport-https curl
ARG ZCASH_SIGNING_KEY_ID=6DEF3BAF272766C0
ARG ZCASH_SIGNING_KEY_ID=1D05FDC66B372CFE
ARG ZCASH_VERSION=
# The empty string for ZCASH_VERSION will install the apt default version,

View File

@ -1,5 +1,5 @@
---
name: "zcash-5.6.1"
name: "zcash-5.7.0"
enable_cache: true
distro: "debian"
suites:

View File

@ -1,5 +1,5 @@
---
name: "zcash-5.6.1"
name: "zcash-5.7.0"
enable_cache: true
distro: "debian"
suites:

View File

@ -338,7 +338,7 @@
"uid": "T9XAoUn4k"
},
"editorMode": "builder",
"expr": "avg_over_time(zcashd_wallet_batchscanner_usage_byes[$__interval])",
"expr": "avg_over_time(zcashd_wallet_batchscanner_usage_bytes[$__interval])",
"hide": false,
"legendFormat": "Heap usage",
"range": true,
@ -618,7 +618,7 @@
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"fillOpacity": 50,
"gradientMode": "none",
"hideFrom": {
"legend": false,
@ -631,11 +631,11 @@
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
@ -648,14 +648,10 @@
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "ZEC"
"unit": "bytes"
},
"overrides": []
},
@ -665,7 +661,7 @@
"x": 12,
"y": 16
},
"id": 8,
"id": 18,
"options": {
"legend": {
"calcs": [],
@ -678,20 +674,21 @@
"sort": "none"
}
},
"pluginVersion": "9.1.6",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "T9XAoUn4k"
},
"expr": "zcash_pool_value_zatoshis/100000000",
"interval": "",
"legendFormat": "{{name}}",
"refId": "A"
"editorMode": "code",
"expr": "zcash_mempool_size_weighted",
"hide": false,
"legendFormat": "{{bk}}",
"range": true,
"refId": "Size"
}
],
"title": "Shielded pools",
"title": "Mempool composition by weight",
"type": "timeseries"
},
{
@ -797,6 +794,200 @@
"title": "Outbound messages",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "T9XAoUn4k"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 50,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 24
},
"id": 19,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "T9XAoUn4k"
},
"editorMode": "code",
"expr": "zcash_mempool_actions_unpaid",
"legendFormat": "{{bk}}",
"range": true,
"refId": "Unpaid"
},
{
"datasource": {
"type": "prometheus",
"uid": "T9XAoUn4k"
},
"editorMode": "code",
"expr": "zcash_mempool_actions_paid",
"hide": false,
"legendFormat": "Paid",
"range": true,
"refId": "Paid"
}
],
"title": "Mempool unpaid actions by weight",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "T9XAoUn4k"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "ZEC"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 32
},
"id": 8,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "9.1.6",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "T9XAoUn4k"
},
"expr": "zcash_pool_value_zatoshis/100000000",
"interval": "",
"legendFormat": "{{name}}",
"refId": "A"
}
],
"title": "Shielded pools",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
@ -859,7 +1050,7 @@
"h": 8,
"w": 12,
"x": 12,
"y": 24
"y": 32
},
"id": 14,
"options": {
@ -906,6 +1097,6 @@
"timezone": "",
"title": "zcashd metrics",
"uid": "U4U58t-Gk",
"version": 1,
"version": 8,
"weekStart": ""
}

50
depend/zcash/deny.toml Normal file
View File

@ -0,0 +1,50 @@
# Configuration file for cargo-deny
targets = [
{ triple = "aarch64-unknown-linux-gnu" },
{ triple = "x86_64-apple-darwin" },
{ triple = "x86_64-pc-windows-gnu" },
{ triple = "x86_64-unknown-freebsd" },
{ triple = "x86_64-unknown-linux-gnu" },
]
[licenses]
unlicensed = "deny"
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
# checks licenses for dependencies that are compiled into the end binary for the
# above listed targets, whereas `contrib/debian/copyright` covers anything that
# may end up in a source archive (including dev-dependencies and unsupported
# targets).
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"] },
{ name = "subtle", allow = ["BSD-3-Clause"] },
{ name = "terminfo", allow = ["WTFPL"] },
{ name = "unicode-ident", allow = ["Unicode-DFS-2016"] },
{ 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"
license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 },
]

View File

@ -1,9 +1,10 @@
package=boost
$(package)_version=1_82_0
$(package)_version=1_83_0
$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/
$(package)_file_name=boost_$($(package)_version).tar.bz2
$(package)_sha256_hash=a6e1ab9b0860e6a2881dd7b21fe9f737a095e5f33a3a874afc6a345228597ee6
$(package)_sha256_hash=6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e
$(package)_dependencies=native_b2
$(package)_patches=6753-signals2-function-fix.patch
ifneq ($(host_os),darwin)
$(package)_dependencies+=libcxx
@ -41,6 +42,7 @@ endif
endef
define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/6753-signals2-function-fix.patch && \
echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : <cflags>\"$($(package)_cflags)\" <cxxflags>\"$($(package)_cxxflags)\" <compileflags>\"$($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$($(package)_ar)\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
endef

View File

@ -1,8 +1,8 @@
package=libsodium
$(package)_version=1.0.18
$(package)_version=1.0.19
$(package)_download_path=https://download.libsodium.org/libsodium/releases/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1
$(package)_sha256_hash=018d79fe0a045cca07331d37bd0cb57b2e838c51bc48fd837a1472e50068bbea
$(package)_dependencies=
$(package)_patches=1.0.15-pubkey-validation.diff 1.0.15-signature-validation.diff
$(package)_config_opts=

View File

@ -1,8 +1,8 @@
package=native_ccache
$(package)_version=4.6.3
$(package)_version=4.8.3
$(package)_download_path=https://github.com/ccache/ccache/releases/download/v$($(package)_version)
$(package)_file_name=ccache-$($(package)_version).tar.gz
$(package)_sha256_hash=f46ba3706ad80c30d4d5874dee2bf9227a7fcd0ccaac31b51919a3053d84bd05
$(package)_sha256_hash=d59dd569ad2bbc826c0bc335c8ebd73e78ed0f2f40ba6b30069347e63585d9ef
$(package)_build_subdir=build
$(package)_dependencies=native_cmake native_zstd

View File

@ -1,8 +1,8 @@
package=native_cmake
$(package)_version=3.26.4
$(package)_version=3.27.6
$(package)_download_path=https://github.com/Kitware/CMake/releases/download/v$($(package)_version)
$(package)_file_name=cmake-$($(package)_version).tar.gz
$(package)_sha256_hash=313b6880c291bd4fe31c0aa51d6e62659282a521e695f30d5cc0d25abbd5c208
$(package)_sha256_hash=ef3056df528569e0e8956f6cf38806879347ac6de6a4ff7e4105dc4578732cfb
define $(package)_set_vars
$(package)_config_opts += -DCMAKE_BUILD_TYPE:STRING=Release

View File

@ -1,14 +1,14 @@
package=native_cxxbridge
# The version needs to match cxx in Cargo.toml
$(package)_version=1.0.95
$(package)_version=1.0.107
$(package)_download_path=https://github.com/dtolnay/cxx/archive/refs/tags
$(package)_file_name=native_cxxbridge-$($(package)_version).tar.gz
$(package)_download_file=$($(package)_version).tar.gz
$(package)_sha256_hash=842926be773c09b4b45d1a2d82556752d5008f1d564b1a04070ec61ef94992ea
$(package)_sha256_hash=961256a942c2369d84db29f6f7d09bce7fa7de221ec729856216a87b0970b1df
$(package)_build_subdir=gen/cmd
$(package)_dependencies=native_rust
# This file is somewhat annoying to update, but can be done like so from the repo base:
# $ export VERSION=1.0.95
# $ export VERSION=1.0.107
# $ rm .cargo/config .cargo/.configured-for-offline
# $ mkdir tmp
# $ cd tmp

View File

@ -1,14 +1,9 @@
package=tl_expected
$(package)_version=96d547c03d2feab8db64c53c3744a9b4a7c8f2c5
$(package)_download_path=https://github.com/TartanLlama/expected/archive
$(package)_download_file=$($(package)_version).tar.gz
$(package)_version=1.1.0
$(package)_download_path=https://github.com/TartanLlama/expected/archive/refs/tags
$(package)_download_file=v$($(package)_version).tar.gz
$(package)_file_name=$(package)_$($(package)_version).tar.gz
$(package)_sha256_hash=64901df1de9a5a3737b331d3e1de146fa6ffb997017368b322c08f45c51b90a7
$(package)_patches=remove-undefined-behaviour.diff
define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/remove-undefined-behaviour.diff
endef
$(package)_sha256_hash=1db357f46dd2b24447156aaf970c4c40a793ef12a8a9c2ad9e096d9801368df6
define $(package)_stage_cmds
mkdir -p $($(package)_staging_dir)$(host_prefix)/include && \

View File

@ -1,9 +1,9 @@
package=utfcpp
$(package)_version=3.2.3
$(package)_version=3.2.5
$(package)_download_path=https://github.com/nemtrif/$(package)/archive/refs/tags
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_download_file=v$($(package)_version).tar.gz
$(package)_sha256_hash=3ba9b0dbbff08767bdffe8f03b10e596ca351228862722e4c9d4d126d2865250
$(package)_sha256_hash=14fd1b3c466814cb4c40771b7f207b61d2c7a0aa6a5e620ca05c00df27f25afd
define $(package)_stage_cmds
mkdir -p $($(package)_staging_dir)$(host_prefix)/include && \

View File

@ -0,0 +1,105 @@
From 7ca2310b15e387258e97e4cd16887f5ee4906b28 Mon Sep 17 00:00:00 2001
From: Peter Dimov <pdimov@gmail.com>
Date: Sun, 3 Sep 2023 17:55:50 +0300
Subject: [PATCH] Support fn.contains(f) where f is a function. Fixes #46.
---
boost/function/function_base.hpp | 17 +++++++++++-
libs/function/test/Jamfile.v2 | 3 +++
libs/function/test/contains3_test.cpp | 33 ++++++++++++++++++++++++
3 files changed, 52 insertions(+), 1 deletion(-)
create mode 100644 test/contains3_test.cpp
diff --git a/boost/function/function_base.hpp b/boost/function/function_base.hpp
index 5693e11e..00c7ce8e 100644
--- a/boost/function/function_base.hpp
+++ b/boost/function/function_base.hpp
@@ -25,6 +25,7 @@
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/is_function.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
@@ -652,7 +653,8 @@ class function_base
}
template<typename F>
- bool contains(const F& f) const
+ typename boost::enable_if_< !boost::is_function<F>::value, bool >::type
+ contains(const F& f) const
{
if (const F* fp = this->template target<F>())
{
@@ -662,6 +664,19 @@ class function_base
}
}
+ template<typename Fn>
+ typename boost::enable_if_< boost::is_function<Fn>::value, bool >::type
+ contains(Fn& f) const
+ {
+ typedef Fn* F;
+ if (const F* fp = this->template target<F>())
+ {
+ return function_equal(*fp, &f);
+ } else {
+ return false;
+ }
+ }
+
#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3
// GCC 3.3 and newer cannot copy with the global operator==, due to
// problems with instantiation of function return types before it
diff --git a/libs/function/test/Jamfile.v2 b/libs/function/test/Jamfile.v2
index 15d401ea..7be87a11 100644
--- a/libs/function/test/Jamfile.v2
+++ b/libs/function/test/Jamfile.v2
@@ -90,3 +90,6 @@ run fn_eq_bind_test.cpp ;
# /usr/include/c++/4.4/bits/shared_ptr.h:146: error: cannot use typeid with -fno-rtti
run contains_test.cpp : : : <rtti>off <toolset>gcc-4.4,<cxxstd>0x:<build>no : contains_test_no_rtti ;
run contains2_test.cpp : : : <rtti>off <toolset>gcc-4.4,<cxxstd>0x:<build>no : contains2_test_no_rtti ;
+
+run contains3_test.cpp ;
+run contains3_test.cpp : : : <rtti>off <toolset>gcc-4.4,<cxxstd>0x:<build>no : contains3_test_no_rtti ;
diff --git a/libs/function/test/contains3_test.cpp b/libs/function/test/contains3_test.cpp
new file mode 100644
index 00000000..e6130bbe
--- /dev/null
+++ b/libs/function/test/contains3_test.cpp
@@ -0,0 +1,33 @@
+// Copyright 2023 Peter Dimov
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/function.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+static int f()
+{
+ return 1;
+}
+
+static int g()
+{
+ return 2;
+}
+
+int main()
+{
+ {
+ boost::function<int()> fn;
+ BOOST_TEST( !fn.contains( f ) );
+ BOOST_TEST( !fn.contains( g ) );
+ }
+
+ {
+ boost::function<int()> fn( f );
+ BOOST_TEST( fn.contains( f ) );
+ BOOST_TEST( !fn.contains( g ) );
+ }
+
+ return boost::report_errors();
+}

View File

@ -10,32 +10,27 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "anstyle"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d"
checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea"
[[package]]
name = "basic-toml"
version = "0.1.2"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1"
checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.79"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"jobserver",
"libc",
]
[[package]]
@ -46,30 +41,30 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-ast"
version = "0.1.17"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02c73a606ccd8c2fe7691f15c6f9b9e2eae203f8356462fe99db91840e3fb964"
checksum = "152da76e4e754905d7f915611170325310a95ab872a15ed8516c64c1ee4c0e13"
dependencies = [
"rustc-hash",
"serde",
]
[[package]]
name = "clap"
version = "4.3.2"
version = "4.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "401a4694d2bf92537b6867d94de48c4842089645fdcdf6c71865b175d836e9c2"
checksum = "fb690e81c7840c0d7aade59f242ea3b41b9bc27bcd5997890e7702ae4b32e487"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.3.1"
version = "4.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980"
checksum = "5ed2e96bc16d8d740f6f48d663eddf4b8a0983e79210fd55479b7bcd0a69860e"
dependencies = [
"anstyle",
"bitflags",
"clap_lex",
"strsim",
]
@ -101,7 +96,7 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.95"
version = "1.0.107"
dependencies = [
"cc",
"cxx-build",
@ -116,7 +111,7 @@ dependencies = [
[[package]]
name = "cxx-build"
version = "1.0.95"
version = "1.0.107"
dependencies = [
"cc",
"codespan-reporting",
@ -132,7 +127,7 @@ dependencies = [
[[package]]
name = "cxx-gen"
version = "0.7.95"
version = "0.7.107"
dependencies = [
"codespan-reporting",
"proc-macro2",
@ -151,7 +146,7 @@ dependencies = [
[[package]]
name = "cxxbridge-cmd"
version = "1.0.95"
version = "1.0.107"
dependencies = [
"clap",
"codespan-reporting",
@ -162,11 +157,11 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.95"
version = "1.0.107"
[[package]]
name = "cxxbridge-macro"
version = "1.0.95"
version = "1.0.107"
dependencies = [
"clang-ast",
"cxx",
@ -175,6 +170,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_derive",
"serde_json",
"syn",
]
@ -189,15 +185,15 @@ dependencies = [
[[package]]
name = "dissimilar"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "210ec60ae7d710bed8683e333e9d2855a8a56a3e9892b38bad3bb0d4d29b0d5e"
checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632"
[[package]]
name = "flate2"
version = "1.0.26"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
dependencies = [
"crc32fast",
"miniz_oxide",
@ -211,9 +207,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "itoa"
version = "1.0.6"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "jobserver"
@ -226,15 +222,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.146"
version = "0.2.148"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
[[package]]
name = "link-cplusplus"
version = "1.0.8"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
dependencies = [
"cc",
]
@ -272,54 +268,60 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "proc-macro2"
version = "1.0.59"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.28"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.12"
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.13"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "scratch"
version = "1.0.5"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
[[package]]
name = "serde"
version = "1.0.163"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.163"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
@ -328,9 +330,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.96"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
dependencies = [
"itoa",
"ryu",
@ -345,9 +347,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "2.0.18"
version = "2.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668"
dependencies = [
"proc-macro2",
"quote",
@ -365,9 +367,9 @@ dependencies = [
[[package]]
name = "trybuild"
version = "1.0.80"
version = "1.0.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a"
checksum = "a5c89fd17b7536f2cf66c97cff6e811e89e728ca0ed13caeed610c779360d8b4"
dependencies = [
"basic-toml",
"dissimilar",
@ -381,9 +383,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.9"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"

View File

@ -1,78 +0,0 @@
diff --recursive --unified tl-expected-1.0.1-orig/include/tl/expected.hpp tl-expected-1.0.1/include/tl/expected.hpp
--- tl-expected-1.0.1-orig/include/tl/expected.hpp 2022-08-30 20:10:13.269489852 +0100
+++ tl-expected-1.0.1/include/tl/expected.hpp 2022-08-30 20:17:35.744258828 +0100
@@ -24,6 +24,7 @@
#include <functional>
#include <type_traits>
#include <utility>
+#include <cassert>
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
#define TL_EXPECTED_EXCEPTIONS_ENABLED
@@ -1862,27 +1863,37 @@
}
}
- constexpr const T *operator->() const { return valptr(); }
- TL_EXPECTED_11_CONSTEXPR T *operator->() { return valptr(); }
+ constexpr const T *operator->() const {
+ assert(has_value());
+ return valptr();
+ }
+ TL_EXPECTED_11_CONSTEXPR T *operator->() {
+ assert(has_value());
+ return valptr();
+ }
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
constexpr const U &operator*() const & {
+ assert(has_value());
return val();
}
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
TL_EXPECTED_11_CONSTEXPR U &operator*() & {
+ assert(has_value());
return val();
}
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
constexpr const U &&operator*() const && {
+ assert(has_value());
return std::move(val());
}
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
TL_EXPECTED_11_CONSTEXPR U &&operator*() && {
+ assert(has_value());
return std::move(val());
}
@@ -1918,10 +1929,22 @@
return std::move(val());
}
- constexpr const E &error() const & { return err().value(); }
- TL_EXPECTED_11_CONSTEXPR E &error() & { return err().value(); }
- constexpr const E &&error() const && { return std::move(err().value()); }
- TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(err().value()); }
+ constexpr const E &error() const & {
+ assert(!has_value());
+ return err().value();
+ }
+ TL_EXPECTED_11_CONSTEXPR E &error() & {
+ assert(!has_value());
+ return err().value();
+ }
+ constexpr const E &&error() const && {
+ assert(!has_value());
+ return std::move(err().value());
+ }
+ TL_EXPECTED_11_CONSTEXPR E &&error() && {
+ assert(!has_value());
+ return std::move(err().value());
+ }
template <class U> constexpr T value_or(U &&v) const & {
static_assert(std::is_copy_constructible<T>::value &&

View File

@ -1,11 +1,11 @@
Zcash Contributors
==================
Jack Grigg (1335)
Kris Nuttycombe (698)
Jack Grigg (1388)
Kris Nuttycombe (702)
Simon Liu (460)
Sean Bowe (404)
Daira Hopwood (396)
Sean Bowe (409)
Daira Hopwood (397)
Eirik Ogilvie-Wigley (216)
Greg Pfeil (208)
Wladimir J. van der Laan (160)
@ -22,7 +22,7 @@ sasha (80)
Cory Fields (78)
Matt Corallo (62)
Nathan Wilcox (57)
Daira Emma Hopwood (47)
Daira Emma Hopwood (49)
practicalswift (43)
Dimitris Apostolou (43)
Kevin Gallagher (38)
@ -35,8 +35,8 @@ Gregory Maxwell (24)
John Newbery (23)
Suhas Daftuar (20)
furszy (18)
Marius Kjærstad (18)
Jonathan "Duke" Leto (18)
Marius Kjærstad (17)
syd (16)
Patick Strateman (16)
Charlie O'Keefe (16)
@ -92,6 +92,7 @@ mruddy (3)
lpescher (3)
isle2983 (3)
elbandi (3)
ebfull (3)
Thomas Snider (3)
NikVolf (3)
Martin Ankerl (3)
@ -113,7 +114,6 @@ kpcyrd (2)
kobake (2)
hexabot (2)
face (2)
ebfull (2)
aniemerg (2)
Yuri Zhykin (2)
UdjinM6 (2)
@ -180,6 +180,7 @@ avnish98 (1)
adityapk00 (1)
Za Wilcox (1)
Yasser Isa (1)
Yasser (1)
William M Peaster (1)
Vidar Holen (1)
Vasil Dimov (1)
@ -240,6 +241,7 @@ Forrest Voight (1)
Florian Schmaus (1)
Eran Tromer (1)
Elliot Olds (1)
Elijah Hampton (1)
Dimitris Tsapakidis (1)
DesWurstes (1)
Denis Lukianov (1)

View File

@ -42,12 +42,9 @@ 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.5.0-rc1 | 2023-04-20 | 2188024 | 2023-08-10 |
| 5.5.0-rc2 | 2023-04-25 | 2193300 | 2023-08-15 |
| 5.5.0-rc3 | 2023-04-27 | 2195224 | 2023-08-17 |
| 5.5.0 | 2023-04-27 | 2196024 | 2023-08-17 |
| 5.5.1 | 2023-05-16 | 2217487 | 2023-09-05 |
| 5.6.0-rc1 | 2023-06-08 | 2243024 | 2023-09-28 |
| 5.6.0 | 2023-06-14 | 2250924 | 2023-10-04 |
| 5.6.1 | 2023-06-21 | 2258800 | 2023-10-11 |
| 5.7.0-rc1 | 2023-09-22 | 2365300 | 2024-01-12 |
| 5.7.0 | 2023-09-28 | 2372200 | 2024-01-18 |
<!-- 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" "June 2023" "zcash-cli v5.6.1" "User Commands"
.TH ZCASH-CLI "1" "September 2023" "zcash-cli v5.7.0" "User Commands"
.SH NAME
zcash-cli \- manual page for zcash-cli v5.6.1
zcash-cli \- manual page for zcash-cli v5.7.0
.SH DESCRIPTION
Zcash RPC client version v5.6.1
Zcash RPC client version v5.7.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" "June 2023" "zcash-tx v5.6.1" "User Commands"
.TH ZCASH-TX "1" "September 2023" "zcash-tx v5.7.0" "User Commands"
.SH NAME
zcash-tx \- manual page for zcash-tx v5.6.1
zcash-tx \- manual page for zcash-tx v5.7.0
.SH DESCRIPTION
Zcash zcash\-tx utility version v5.6.1
Zcash zcash\-tx utility version v5.7.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" "June 2023" "zcashd-wallet-tool v5.6.1" "User Commands"
.TH ZCASHD-WALLET-TOOL "1" "September 2023" "zcashd-wallet-tool v5.7.0" "User Commands"
.SH NAME
zcashd-wallet-tool \- manual page for zcashd-wallet-tool v5.6.1
zcashd-wallet-tool \- manual page for zcashd-wallet-tool v5.7.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" "June 2023" "zcashd v5.6.1" "User Commands"
.TH ZCASHD "1" "September 2023" "zcashd v5.7.0" "User Commands"
.SH NAME
zcashd \- manual page for zcashd v5.6.1
zcashd \- manual page for zcashd v5.7.0
.SH DESCRIPTION
Zcash Daemon version v5.6.1
Zcash Daemon version v5.7.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,132 @@
Notable changes
===============
Deprecation of `fetch-params.sh`
--------------------------------
The `fetch-params.sh` script (also `zcash-fetch-params`) is now deprecated. The
`zcashd` binary now bundles zk-SNARK parameters directly and so parameters do not
need to be downloaded or stored separately. The script will now do nothing but
state that it is deprecated; it will be removed in a future release.
Previously, parameters were stored by default in these locations:
* `~/.zcash-params` (on Linux); or
* `~/Library/Application Support/ZcashParams` (on Mac); or
* `C:\Users\Username\AppData\Roaming\ZcashParams` (on Windows)
Unless you need to generate transactions using the deprecated Sprout shielded
pool, you can delete the parameter files stored in these directories to save
space as they are no longer read or used by `zcashd`. If you do wish to use the
Sprout pool, you will need the `sprout-groth16.params` file in the
aforementioned directory. This file is currently available for download
[here](https://download.z.cash/downloads/sprout-groth16.params).
Mempool metrics
---------------
`zcashd` now reports the following new metrics when `-prometheusport` is set:
- (gauge) `zcash.mempool.actions.unpaid { "bk" = ["< 0.2", "< 0.4", "< 0.6", "< 0.8", "< 1"] }`
- (gauge) `zcash.mempool.actions.paid`
- (gauge) `zcash.mempool.size.weighted { "bk" = ["< 1", "1", "> 1", "> 2", "> 3"] }`
The `zcash.mempool.actions` metrics count the number of [logical actions] across
the transactions in the mempool, while `zcash.mempool.size.weighted` is a
weight-bucketed version of the `zcash.mempool.size.bytes` metric.
The [ZIP 317 weight ratio][weight_ratio] of a transaction is used to bucket its
logical actions and byte size. A weight ratio of at least 1 means that the
transaction's fee is at least the ZIP 317 conventional fee, and all of its
logical actions are considered "paid". A weight ratio lower than 1 corresponds
to the fraction of the transaction's logical actions that are "paid". The
remaining fraction (i.e. 1 - weight ratio) are subject to the unpaid action
limit that miners configure for their blocks with `-blockunpaidactionlimit`.
[logical actions]: https://zips.z.cash/zip-0317#fee-calculation
[weight_ratio]: https://zips.z.cash/zip-0317#recommended-algorithm-for-block-template-construction
Changelog
=========
Daira Emma Hopwood (2):
wallet_listreceived.py: fix an assertion message and remove unnecessary use of LEGACY_DEFAULT_FEE.
Update ed25519-zebra to 4.0.0. This deduplicates sha2, rand-core, block-buffer, digest, and ahash. (It adds duplications for hashbrown and libm which are less important.)
Daira Hopwood (1):
Ensure that the panic when Sprout parameters cannot be loaded says how to fix it by downloading them.
Elijah Hampton (1):
Updates getblockcount help message to the appropriate message.
Jack Grigg (48):
CI: Update `apt` before installing build dependencies
CI: De-duplicate logic to get the number of available processing cores
CI: Use `hw.logicalcpu` instead of `hw.ncpu` on macOS
Move mempool metrics updates into a `CTxMemPool::UpdateMetrics` method
metrics: Track mempool actions and size bucketed by weight
contrib: Update Grafana dashboard to show mempool composition
CI: Add a lint that checks for headers missing from makefiles
Retroactively use Rust to decrypt shielded coinbase before soft fork
Remove now-unused C++ Sapling note encryption logic
test: Skip `WalletTests.WalletNetworkSerialization`
Rename reject reason for invalid shielded coinbase ciphertexts
test: Set `-limitdescendantcount` to match viable iteration limit
qa: Migrate to `cargo-vet 0.8`
qa: Remove audit policies for crates we no longer patch
qa: Replace Windows crate audits with a trust policy for Microsoft
depends: native_ccache 4.8.2
depends: cxx 1.0.97
cargo update
CI: Add `cargo deny check licenses` job
depends: tl_expected 1.1.0
cargo update again
Use `cxx::bridge` for Sprout proofs
Use `cxx::bridge` for `zcash_history`
Use `cxx::bridge` for initialization functions
Use `cxx::bridge` to load ZKP parameters
Use `cxx::bridge` for Sapling specification components
Remove unused Sapling logic
Use `cxx::bridge` for Sapling ZIP 32 wrappers
Use `cxx::bridge` for `getrandom`
rust: Rename modules that no longer contain raw FFI functions
depends: libsodium 1.0.19
depends: utfcpp 3.2.4
depends: native_ccache 4.8.3
depends: Boost 1.83.0
depends: native_cmake 3.27.4
qa: Bump postponed dependencies
qa: cargo vet prune
cargo update
depends: cxx 1.0.107
depends: native_cmake 3.27.5
qa: Postpone Clang and Rust updates
depends: native_cmake 3.27.6
qa: Replace `cargo vet` ECC self-audits with trust declarations
rust: Upgrade Zcash Rust crates
Remove CentOS 8 from CI builder files
doc: Update release notes for 5.7.0
make-release.py: Versioning changes for 5.7.0-rc1.
make-release.py: Updated manpages for 5.7.0-rc1.
Kris Nuttycombe (3):
Update network upgrade golden tests for serialization to include nu5.
Make a few small improvements to the release process doc.
Remove audit claim for allocator-api2
Marius Kjærstad (1):
New checkpoint at block 2200000 for mainnet
Sean Bowe (5):
Bundle the Sprout (Groth16) verification key in librustzcash.
Bundle the Sapling zk-SNARK parameters using the `wagyu-zcash-parameters` crate.
Deprecate the `fetch-params.sh` script.
cargo fmt
Hash the Sprout parameter file during proving before deserialization.
Yasser (1):
Update ZCASH_SIGNING_KEY_ID in Dockerfile
ebfull (1):
Update zcutil/fetch-params.sh

View File

@ -0,0 +1,138 @@
Notable changes
===============
Deprecation of `fetch-params.sh`
--------------------------------
The `fetch-params.sh` script (also `zcash-fetch-params`) is now deprecated. The
`zcashd` binary now bundles zk-SNARK parameters directly and so parameters do not
need to be downloaded or stored separately. The script will now do nothing but
state that it is deprecated; it will be removed in a future release.
Previously, parameters were stored by default in these locations:
* `~/.zcash-params` (on Linux); or
* `~/Library/Application Support/ZcashParams` (on Mac); or
* `C:\Users\Username\AppData\Roaming\ZcashParams` (on Windows)
Unless you need to generate transactions using the deprecated Sprout shielded
pool, you can delete the parameter files stored in these directories to save
space as they are no longer read or used by `zcashd`. If you do wish to use the
Sprout pool, you will need the `sprout-groth16.params` file in the
aforementioned directory. This file is currently available for download
[here](https://download.z.cash/downloads/sprout-groth16.params).
Mempool metrics
---------------
`zcashd` now reports the following new metrics when `-prometheusport` is set:
- (gauge) `zcash.mempool.actions.unpaid { "bk" = ["< 0.2", "< 0.4", "< 0.6", "< 0.8", "< 1"] }`
- (gauge) `zcash.mempool.actions.paid`
- (gauge) `zcash.mempool.size.weighted { "bk" = ["< 1", "1", "> 1", "> 2", "> 3"] }`
The `zcash.mempool.actions` metrics count the number of [logical actions] across
the transactions in the mempool, while `zcash.mempool.size.weighted` is a
weight-bucketed version of the `zcash.mempool.size.bytes` metric.
The [ZIP 317 weight ratio][weight_ratio] of a transaction is used to bucket its
logical actions and byte size. A weight ratio of at least 1 means that the
transaction's fee is at least the ZIP 317 conventional fee, and all of its
logical actions are considered "paid". A weight ratio lower than 1 corresponds
to the fraction of the transaction's logical actions that are "paid". The
remaining fraction (i.e. 1 - weight ratio) are subject to the unpaid action
limit that miners configure for their blocks with `-blockunpaidactionlimit`.
[logical actions]: https://zips.z.cash/zip-0317#fee-calculation
[weight_ratio]: https://zips.z.cash/zip-0317#recommended-algorithm-for-block-template-construction
Changelog
=========
Daira Emma Hopwood (2):
wallet_listreceived.py: fix an assertion message and remove unnecessary use of LEGACY_DEFAULT_FEE.
Update ed25519-zebra to 4.0.0. This deduplicates sha2, rand-core, block-buffer, digest, and ahash. (It adds duplications for hashbrown and libm which are less important.)
Daira Hopwood (1):
Ensure that the panic when Sprout parameters cannot be loaded says how to fix it by downloading them.
Elijah Hampton (1):
Updates getblockcount help message to the appropriate message.
Jack Grigg (53):
CI: Update `apt` before installing build dependencies
CI: De-duplicate logic to get the number of available processing cores
CI: Use `hw.logicalcpu` instead of `hw.ncpu` on macOS
Move mempool metrics updates into a `CTxMemPool::UpdateMetrics` method
metrics: Track mempool actions and size bucketed by weight
contrib: Update Grafana dashboard to show mempool composition
CI: Add a lint that checks for headers missing from makefiles
Retroactively use Rust to decrypt shielded coinbase before soft fork
Remove now-unused C++ Sapling note encryption logic
test: Skip `WalletTests.WalletNetworkSerialization`
Rename reject reason for invalid shielded coinbase ciphertexts
test: Set `-limitdescendantcount` to match viable iteration limit
qa: Migrate to `cargo-vet 0.8`
qa: Remove audit policies for crates we no longer patch
qa: Replace Windows crate audits with a trust policy for Microsoft
depends: native_ccache 4.8.2
depends: cxx 1.0.97
cargo update
CI: Add `cargo deny check licenses` job
depends: tl_expected 1.1.0
cargo update again
Use `cxx::bridge` for Sprout proofs
Use `cxx::bridge` for `zcash_history`
Use `cxx::bridge` for initialization functions
Use `cxx::bridge` to load ZKP parameters
Use `cxx::bridge` for Sapling specification components
Remove unused Sapling logic
Use `cxx::bridge` for Sapling ZIP 32 wrappers
Use `cxx::bridge` for `getrandom`
rust: Rename modules that no longer contain raw FFI functions
depends: libsodium 1.0.19
depends: utfcpp 3.2.4
depends: native_ccache 4.8.3
depends: Boost 1.83.0
depends: native_cmake 3.27.4
qa: Bump postponed dependencies
qa: cargo vet prune
cargo update
depends: cxx 1.0.107
depends: native_cmake 3.27.5
qa: Postpone Clang and Rust updates
depends: native_cmake 3.27.6
qa: Replace `cargo vet` ECC self-audits with trust declarations
rust: Upgrade Zcash Rust crates
Remove CentOS 8 from CI builder files
doc: Update release notes for 5.7.0
make-release.py: Versioning changes for 5.7.0-rc1.
make-release.py: Updated manpages for 5.7.0-rc1.
make-release.py: Updated release notes and changelog for 5.7.0-rc1.
make-release.py: Updated book for 5.7.0-rc1.
depends: utfcpp 3.2.5
make-release.py: Versioning changes for 5.7.0.
make-release.py: Updated manpages for 5.7.0.
Kris Nuttycombe (4):
Update network upgrade golden tests for serialization to include nu5.
Make a few small improvements to the release process doc.
Remove audit claim for allocator-api2
Fix description of transaction weight ratio in v5.7.0 release notes.
Marius Kjærstad (1):
New checkpoint at block 2200000 for mainnet
Sean Bowe (5):
Bundle the Sprout (Groth16) verification key in librustzcash.
Bundle the Sapling zk-SNARK parameters using the `wagyu-zcash-parameters` crate.
Deprecate the `fetch-params.sh` script.
cargo fmt
Hash the Sprout parameter file during proving before deserialization.
Yasser (1):
Update ZCASH_SIGNING_KEY_ID in Dockerfile
ebfull (1):
Update zcutil/fetch-params.sh

View File

@ -22,10 +22,19 @@ Check that there are no surprising performance regressions.
Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc.
Check that dependencies are up-to-date or have been postponed:
Check that dependencies are up-to-date or have been postponed. If necessary,
install `cargo-upgrades` and `cargo-audit`:
```
cargo install cargo-upgrades cargo-audit
```
Then run each of the following:
```
$ ./qa/zcash/updatecheck.py
$ cargo upgrades
$ cargo audit
```
You can optionally create a file `~/.local/share/zcash/updatecheck/token` (or
@ -120,11 +129,11 @@ necessary, but do NOT push these commits to the `version-X.Y.Z` branch on the
upstream repository; they will be included in the release branch that will be
created in the next step.
### Create the release candidate branch
### Create the release branch
Run the release script to create the first release candidate. This will create
a branch based upon the specified commit ID, then commit standard automated
changes to that branch locally:
Run the release script to create the release branch. This will create a branch
based upon the specified commit ID, then commit standard automated changes to
that branch locally:
$ ./zcutil/make-release.py <COMMIT_ID> <RELEASE> <RELEASE_PREV> <RELEASE_FROM> <APPROX_RELEASE_HEIGHT>
@ -133,6 +142,9 @@ Examples:
$ ./zcutil/make-release.py 600c4acee1 v1.1.0-rc1 v1.0.0 v1.0.0 280300
$ ./zcutil/make-release.py b89b48cda1 v1.1.0 v1.1.0-rc1 v1.0.0 300600
Ordinarily, we choose a release height that is a couple hundred blocks in
the future in order to give time for CI to run.
### Create, Review, and Merge the release branch pull request
Review the automated changes in git:
@ -146,7 +158,7 @@ Push the resulting branch to github:
Then create the PR on github targeting the `version-X.Y.0` branch. Complete the
standard review process and wait for CI to complete.
## Make a tag for the tip of the release candidate branch
## Make a tag for the tip of the release branch
NOTE: This has changed from the previously recommended process. The tag should
be created at the tip of the automatically-generated release branch created by
@ -169,16 +181,22 @@ Then create the git tag. The `-s` means the release tag will be signed. Enter
"Release <version>." and save when prompted for a commit message. **CAUTION:**
Remember the `v` at the beginning here:
$ git tag -s vX.Y.Z-rcN
$ git push origin vX.Y.Z-rcN
$ git tag -s vX.Y.Z[-rcN]
## Merge the release candidate branch to the release stabilization branch
For release tags (not release candidates) copy the "Notable Changes" section of
the release notes into the tag body when creating the tag. This makes it easy
for command-line `git` users to review the changes in a release without having
to check out the tag.
Once CI has completed and the release candidate branch has sufficient approving
reviews, merge the release candidate branch back to the release stabilization
branch. Testing proceeds as normal. Any changes that need to be made during the
release candidate period are made by submitting PRs targeting the release
stabilization branch.
$ git push origin vX.Y.Z[-rcN]
## Merge the release branch to the release stabilization branch
Once CI has completed and the release branch has sufficient approving reviews,
merge the release branch back to the release stabilization branch. Testing
proceeds as normal. Any changes that need to be made during the release
candidate period are made by submitting PRs targeting the release stabilization
branch.
Subsequent release candidates, and the creation of the final release, follow
the same process as for release candidates, omitting the `-rcN` suffix for the
@ -198,8 +216,9 @@ release candidates.
- Go to the [GitHub tags page](https://github.com/zcash/zcash/tags).
- Click "Add release notes" beside the tag for this release.
- Copy the release blog post into the release description, and edit to suit
publication on GitHub. See previous release notes for examples.
- Copy the "Notable Changes" section of the release notes into the release
description, and edit to suit publication on GitHub. See previous release
notes for examples.
- Click "Publish release" if publishing the release blog post now, or
"Save draft" to store the notes internally (and then return later to publish
once the blog post is up).

Binary file not shown.

View File

@ -23,12 +23,13 @@ def satoshi_round(amount):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
class MempoolPackagesTest(BitcoinTestFramework):
maxorphantx = 120
limitdescendantcount = 120
def setup_network(self):
base_args = [
'-limitdescendantcount=%d' % (self.limitdescendantcount,),
'-minrelaytxfee=0',
'-maxorphantx=%d' % (self.maxorphantx,),
'-maxorphantx=%d' % (self.limitdescendantcount,),
'-debug',
'-allowdeprecated=getnewaddress',
]
@ -145,19 +146,23 @@ class MempoolPackagesTest(BitcoinTestFramework):
for i in range(10):
transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value})
for i in range(self.maxorphantx):
errored_too_large = False
for i in range(self.limitdescendantcount):
utxo = transaction_package.pop(0)
try:
(txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10)
for j in range(10):
transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value})
if i == self.maxorphantx-2:
if i == self.limitdescendantcount-2:
mempool = self.nodes[0].getrawmempool(True)
assert_equal(mempool[parent_transaction]['descendantcount'], self.maxorphantx)
assert_equal(mempool[parent_transaction]['descendantcount'], self.limitdescendantcount)
except JSONRPCException as e:
print(e.error['message'])
assert_equal(i, self.maxorphantx-1)
assert_equal(i, self.limitdescendantcount-1)
print("tx that would create too large descendant package successfully rejected")
errored_too_large = True
assert errored_too_large
assert_equal(len(transaction_package), self.limitdescendantcount * (10 - 1))
# TODO: check that node1's mempool is as expected

View File

@ -10,7 +10,7 @@ from test_framework.util import (
bitcoind_processes)
from test_framework.util import (
nuparams,
OVERWINTER_BRANCH_ID, SAPLING_BRANCH_ID, BLOSSOM_BRANCH_ID, HEARTWOOD_BRANCH_ID, CANOPY_BRANCH_ID)
OVERWINTER_BRANCH_ID, SAPLING_BRANCH_ID, BLOSSOM_BRANCH_ID, HEARTWOOD_BRANCH_ID, CANOPY_BRANCH_ID, NU5_BRANCH_ID)
import shutil
import logging
@ -22,6 +22,7 @@ HAS_SAPLING = [nuparams(OVERWINTER_BRANCH_ID, 10), nuparams(SAPLING_BRANCH_ID,
HAS_BLOSSOM = HAS_SAPLING + [nuparams(BLOSSOM_BRANCH_ID, 30)]
HAS_HEARTWOOD = HAS_BLOSSOM + [nuparams(HEARTWOOD_BRANCH_ID, 40)]
HAS_CANOPY = HAS_HEARTWOOD + [nuparams(CANOPY_BRANCH_ID, 50)]
HAS_NU5 = HAS_CANOPY + [nuparams(NU5_BRANCH_ID, 60)]
class Upgrade():
def __init__(self, h, p, a):
@ -34,6 +35,7 @@ class UpgradeGoldenTest(BitcoinTestFramework):
self.upgrades = [ Upgrade(35, os.path.dirname(os.path.realpath(__file__))+"/golden/blossom.tar.gz", HAS_BLOSSOM)
, Upgrade(45, os.path.dirname(os.path.realpath(__file__))+"/golden/heartwood.tar.gz", HAS_HEARTWOOD)
, Upgrade(55, os.path.dirname(os.path.realpath(__file__))+"/golden/canopy.tar.gz", HAS_CANOPY)
, Upgrade(65, os.path.dirname(os.path.realpath(__file__))+"/golden/nu5.tar.gz", HAS_NU5)
]
logging.info("Initializing test directory "+self.options.tmpdir)

View File

@ -12,11 +12,10 @@ from test_framework.util import (
assert_raises_message,
connect_nodes_bi,
nuparams,
LEGACY_DEFAULT_FEE,
NU5_BRANCH_ID,
)
from test_framework.util import wait_and_assert_operationid_status, start_nodes
from test_framework.zip317 import conventional_fee, conventional_fee_zats
from test_framework.zip317 import conventional_fee, conventional_fee_zats, ZIP_317_FEE
from decimal import Decimal
my_memo_str = 'c0ffee' # stay awake
@ -66,7 +65,7 @@ class ListReceivedTest (BitcoinTestFramework):
opid = self.nodes[1].z_sendmany(taddr, [
{'address': zaddr1, 'amount': 1, 'memo': my_memo},
{'address': zaddrExt, 'amount': 2},
], 1, LEGACY_DEFAULT_FEE, 'AllowFullyTransparent')
], 1, ZIP_317_FEE, 'AllowFullyTransparent')
txid = wait_and_assert_operationid_status(self.nodes[1], opid)
self.sync_all()
@ -176,7 +175,7 @@ class ListReceivedTest (BitcoinTestFramework):
assert_equal(txid, r[0]['txid'])
assert_equal(Decimal('0.4')-conventional_fee(2), r[0]['amount'])
assert_equal(40000000-conventional_fee_zats(2), r[0]['amountZat'])
assert_equal(r[0]['change'], True, "Note valued at (0.4-"+str(LEGACY_DEFAULT_FEE)+") should be change")
assert_equal(r[0]['change'], True, "Note valued at (0.4-"+str(conventional_fee(2))+") should be change")
assert_equal(no_memo, r[0]['memo'])
# The old note still exists (it's immutable), even though it is spent

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
# cargo-vet config file
[cargo-vet]
version = "0.6"
version = "0.8"
[imports.bytecode-alliance]
url = "https://raw.githubusercontent.com/bytecodealliance/wasmtime/main/supply-chain/audits.toml"
@ -19,47 +19,10 @@ url = "https://raw.githubusercontent.com/divviup/libprio-rs/main/supply-chain/au
[imports.mozilla]
url = "https://raw.githubusercontent.com/mozilla/supply-chain/main/audits.toml"
[policy.bridgetree]
audit-as-crates-io = false
[policy.equihash]
audit-as-crates-io = false
[policy.f4jumble]
audit-as-crates-io = false
[policy.incrementalmerkletree]
audit-as-crates-io = false
[policy.orchard]
audit-as-crates-io = false
[policy.zcash_address]
audit-as-crates-io = false
[policy.zcash_encoding]
audit-as-crates-io = false
[policy.zcash_history]
audit-as-crates-io = false
[policy.zcash_note_encryption]
audit-as-crates-io = false
[policy.zcash_primitives]
audit-as-crates-io = false
[policy.zcash_proofs]
audit-as-crates-io = false
[[exemptions.addr2line]]
version = "0.17.0"
criteria = "safe-to-deploy"
[[exemptions.adler]]
version = "1.0.2"
criteria = "safe-to-deploy"
[[exemptions.aead]]
version = "0.4.3"
criteria = "safe-to-deploy"
@ -68,16 +31,20 @@ criteria = "safe-to-deploy"
version = "0.8.2"
criteria = "safe-to-deploy"
[[exemptions.ahash]]
version = "0.7.6"
criteria = "safe-to-deploy"
[[exemptions.ahash]]
version = "0.8.3"
criteria = "safe-to-deploy"
[[exemptions.aho-corasick]]
version = "0.7.18"
version = "1.0.5"
criteria = "safe-to-deploy"
[[exemptions.allocator-api2]]
version = "0.2.14"
criteria = "safe-to-deploy"
[[exemptions.arrayvec]]
version = "0.7.4"
criteria = "safe-to-deploy"
[[exemptions.backtrace]]
@ -141,7 +108,7 @@ version = "0.1.2"
criteria = "safe-to-deploy"
[[exemptions.cc]]
version = "1.0.79"
version = "1.0.83"
criteria = "safe-to-deploy"
[[exemptions.chacha20]]
@ -161,7 +128,7 @@ version = "1.0.9"
criteria = "safe-to-deploy"
[[exemptions.cpufeatures]]
version = "0.2.2"
version = "0.2.8"
criteria = "safe-to-deploy"
[[exemptions.crossbeam-channel]]
@ -181,7 +148,11 @@ version = "0.8.8"
criteria = "safe-to-deploy"
[[exemptions.curve25519-dalek]]
version = "3.2.0"
version = "4.1.0"
criteria = "safe-to-deploy"
[[exemptions.curve25519-dalek-derive]]
version = "0.1.0"
criteria = "safe-to-deploy"
[[exemptions.cxx]]
@ -196,12 +167,12 @@ criteria = "safe-to-deploy"
version = "1.0.95"
criteria = "safe-to-deploy"
[[exemptions.digest]]
version = "0.9.0"
[[exemptions.deranged]]
version = "0.3.8"
criteria = "safe-to-deploy"
[[exemptions.directories]]
version = "4.0.1"
[[exemptions.digest]]
version = "0.9.0"
criteria = "safe-to-deploy"
[[exemptions.dirs]]
@ -212,12 +183,16 @@ criteria = "safe-to-deploy"
version = "0.3.7"
criteria = "safe-to-deploy"
[[exemptions.ed25519]]
version = "2.2.1"
criteria = "safe-to-deploy"
[[exemptions.ed25519-zebra]]
version = "3.0.0"
criteria = "safe-to-deploy"
[[exemptions.errno-dragonfly]]
version = "0.1.2"
[[exemptions.equivalent]]
version = "1.0.0"
criteria = "safe-to-deploy"
[[exemptions.ff]]
@ -272,16 +247,12 @@ criteria = "safe-to-deploy"
version = "0.3.1"
criteria = "safe-to-deploy"
[[exemptions.hermit-abi]]
version = "0.2.6"
criteria = "safe-to-deploy"
[[exemptions.hermit-abi]]
version = "0.3.1"
criteria = "safe-to-deploy"
[[exemptions.hmac]]
version = "0.12.1"
[[exemptions.home]]
version = "0.5.5"
criteria = "safe-to-deploy"
[[exemptions.http]]
@ -308,20 +279,12 @@ criteria = "safe-to-deploy"
version = "0.2.2"
criteria = "safe-to-deploy"
[[exemptions.incrementalmerkletree]]
version = "0.3.0"
criteria = "safe-to-deploy"
[[exemptions.indexmap]]
version = "1.8.1"
criteria = "safe-to-deploy"
[[exemptions.instant]]
version = "0.1.12"
criteria = "safe-to-deploy"
[[exemptions.io-lifetimes]]
version = "1.0.9"
[[exemptions.indexmap]]
version = "2.0.0"
criteria = "safe-to-deploy"
[[exemptions.ipnet]]
@ -341,23 +304,19 @@ version = "0.9.0"
criteria = "safe-to-deploy"
[[exemptions.libc]]
version = "0.2.141"
version = "0.2.148"
criteria = "safe-to-deploy"
[[exemptions.libm]]
version = "0.2.2"
criteria = "safe-to-deploy"
[[exemptions.link-cplusplus]]
version = "1.0.6"
criteria = "safe-to-deploy"
[[exemptions.linux-raw-sys]]
version = "0.3.8"
version = "0.4.7"
criteria = "safe-to-deploy"
[[exemptions.memchr]]
version = "2.5.0"
version = "2.6.3"
criteria = "safe-to-deploy"
[[exemptions.memoffset]]
@ -388,10 +347,6 @@ criteria = "safe-to-deploy"
version = "0.2.1"
criteria = "safe-to-deploy"
[[exemptions.miniz_oxide]]
version = "0.5.3"
criteria = "safe-to-deploy"
[[exemptions.mio]]
version = "0.8.2"
criteria = "safe-to-deploy"
@ -433,11 +388,11 @@ version = "0.22.0"
criteria = "safe-to-deploy"
[[exemptions.parity-scale-codec]]
version = "3.5.0"
version = "3.6.1"
criteria = "safe-to-deploy"
[[exemptions.parity-scale-codec-derive]]
version = "3.1.3"
version = "3.6.5"
criteria = "safe-to-deploy"
[[exemptions.password-hash]]
@ -468,16 +423,12 @@ criteria = "safe-to-deploy"
version = "0.8.0"
criteria = "safe-to-deploy"
[[exemptions.pin-project-lite]]
version = "0.2.9"
criteria = "safe-to-deploy"
[[exemptions.poly1305]]
version = "0.7.2"
criteria = "safe-to-deploy"
[[exemptions.portable-atomic]]
version = "1.3.3"
version = "1.4.3"
criteria = "safe-to-deploy"
[[exemptions.ppv-lite86]]
@ -512,18 +463,6 @@ criteria = "safe-to-deploy"
version = "0.8.5"
criteria = "safe-to-deploy"
[[exemptions.rand_chacha]]
version = "0.3.1"
criteria = "safe-to-deploy"
[[exemptions.rand_core]]
version = "0.5.1"
criteria = "safe-to-deploy"
[[exemptions.rand_core]]
version = "0.6.4"
criteria = "safe-to-deploy"
[[exemptions.raw-cpuid]]
version = "10.6.0"
criteria = "safe-to-deploy"
@ -545,17 +484,25 @@ version = "0.4.3"
criteria = "safe-to-deploy"
[[exemptions.regex]]
version = "1.6.0"
version = "1.9.5"
criteria = "safe-to-deploy"
[[exemptions.regex-automata]]
version = "0.1.10"
criteria = "safe-to-deploy"
[[exemptions.regex-automata]]
version = "0.3.8"
criteria = "safe-to-deploy"
[[exemptions.regex-syntax]]
version = "0.6.27"
criteria = "safe-to-deploy"
[[exemptions.regex-syntax]]
version = "0.7.2"
criteria = "safe-to-deploy"
[[exemptions.ring]]
version = "0.16.20"
criteria = "safe-to-deploy"
@ -569,7 +516,7 @@ version = "2.1.0"
criteria = "safe-to-deploy"
[[exemptions.rustix]]
version = "0.37.7"
version = "0.38.13"
criteria = "safe-to-deploy"
[[exemptions.rusty-fork]]
@ -608,10 +555,6 @@ criteria = "safe-to-deploy"
version = "1.0.81"
criteria = "safe-to-deploy"
[[exemptions.sha2]]
version = "0.9.9"
criteria = "safe-to-deploy"
[[exemptions.sharded-slab]]
version = "0.1.4"
criteria = "safe-to-deploy"
@ -628,6 +571,10 @@ criteria = "safe-to-deploy"
version = "0.4.9"
criteria = "safe-to-deploy"
[[exemptions.socket2]]
version = "0.5.4"
criteria = "safe-to-deploy"
[[exemptions.spin]]
version = "0.5.2"
criteria = "safe-to-deploy"
@ -657,11 +604,7 @@ version = "1.1.4"
criteria = "safe-to-deploy"
[[exemptions.time]]
version = "0.3.20"
criteria = "safe-to-deploy"
[[exemptions.time-core]]
version = "0.1.0"
version = "0.3.28"
criteria = "safe-to-deploy"
[[exemptions.time-macros]]
@ -669,11 +612,11 @@ version = "0.2.7"
criteria = "safe-to-deploy"
[[exemptions.tokio]]
version = "1.27.0"
version = "1.32.0"
criteria = "safe-to-deploy"
[[exemptions.toml_edit]]
version = "0.19.10"
version = "0.19.15"
criteria = "safe-to-deploy"
[[exemptions.tower-service]]
@ -721,23 +664,23 @@ version = "0.11.0+wasi-snapshot-preview1"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen]]
version = "0.2.84"
version = "0.2.87"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen-backend]]
version = "0.2.84"
version = "0.2.87"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen-macro]]
version = "0.2.84"
version = "0.2.87"
criteria = "safe-to-deploy"
[[exemptions.wasm-bindgen-macro-support]]
version = "0.2.84"
version = "0.2.87"
criteria = "safe-to-deploy"
[[exemptions.web-sys]]
version = "0.3.61"
version = "0.3.64"
criteria = "safe-to-deploy"
[[exemptions.which]]
@ -757,13 +700,17 @@ version = "0.4.0"
criteria = "safe-to-deploy"
[[exemptions.winnow]]
version = "0.4.6"
version = "0.5.15"
criteria = "safe-to-deploy"
[[exemptions.wyz]]
version = "0.5.0"
criteria = "safe-to-deploy"
[[exemptions.xdg]]
version = "2.5.0"
criteria = "safe-to-deploy"
[[exemptions.zeroize]]
version = "1.4.3"
criteria = "safe-to-deploy"

View File

@ -1,6 +1,192 @@
# cargo-vet imports lock
[[publisher.bridgetree]]
version = "0.4.0"
when = "2023-09-08"
user-id = 6289
user-login = "str4d"
[[publisher.bumpalo]]
version = "3.14.0"
when = "2023-09-14"
user-id = 696
user-login = "fitzgen"
user-name = "Nick Fitzgerald"
[[publisher.equihash]]
version = "0.2.0"
when = "2022-06-24"
user-id = 6289
user-login = "str4d"
[[publisher.f4jumble]]
version = "0.1.0"
when = "2022-05-10"
user-id = 6289
user-login = "str4d"
[[publisher.halo2_gadgets]]
version = "0.3.0"
when = "2023-03-22"
user-id = 1244
user-login = "ebfull"
[[publisher.halo2_legacy_pdqsort]]
version = "0.1.0"
when = "2023-03-10"
user-id = 199950
user-login = "daira"
user-name = "Daira Hopwood"
[[publisher.halo2_proofs]]
version = "0.3.0"
when = "2023-03-22"
user-id = 1244
user-login = "ebfull"
[[publisher.incrementalmerkletree]]
version = "0.5.0"
when = "2023-09-08"
user-id = 6289
user-login = "str4d"
[[publisher.orchard]]
version = "0.6.0"
when = "2023-09-08"
user-id = 6289
user-login = "str4d"
[[publisher.windows-sys]]
version = "0.48.0"
when = "2023-03-31"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows-targets]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_aarch64_gnullvm]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_aarch64_msvc]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_i686_gnu]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_i686_msvc]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_x86_64_gnu]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_x86_64_gnullvm]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.windows_x86_64_msvc]]
version = "0.48.5"
when = "2023-08-18"
user-id = 64539
user-login = "kennykerr"
user-name = "Kenny Kerr"
[[publisher.zcash_address]]
version = "0.3.0"
when = "2023-06-06"
user-id = 1244
user-login = "ebfull"
[[publisher.zcash_encoding]]
version = "0.2.0"
when = "2022-10-19"
user-id = 1244
user-login = "ebfull"
[[publisher.zcash_history]]
version = "0.3.0"
when = "2022-05-11"
user-id = 1244
user-login = "ebfull"
[[publisher.zcash_note_encryption]]
version = "0.4.0"
when = "2023-06-06"
user-id = 169181
user-login = "nuttycom"
user-name = "Kris Nuttycombe"
[[publisher.zcash_primitives]]
version = "0.13.0-rc.1"
when = "2023-09-08"
user-id = 6289
user-login = "str4d"
[[publisher.zcash_proofs]]
version = "0.13.0-rc.1"
when = "2023-09-08"
user-id = 6289
user-login = "str4d"
[[audits.bytecode-alliance.wildcard-audits.bumpalo]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
user-id = 696 # Nick Fitzgerald (fitzgen)
start = "2019-03-16"
end = "2024-03-10"
[[audits.bytecode-alliance.audits.addr2line]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.19.0 -> 0.20.0"
notes = "This version brings support for split-dwarf which while it uses the filesystem is always done at the behest of the caller, so everything is as expected for this update."
[[audits.bytecode-alliance.audits.addr2line]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.20.0 -> 0.21.0"
notes = "This version bump updated some dependencies and optimized some internals. All looks good."
[[audits.bytecode-alliance.audits.adler]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
version = "1.0.2"
notes = "This is a small crate which forbids unsafe code and is a straightforward implementation of the adler hashing algorithm."
[[audits.bytecode-alliance.audits.anyhow]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
delta = "1.0.69 -> 1.0.71"
[[audits.bytecode-alliance.audits.arrayref]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
@ -10,32 +196,36 @@ Unsafe code, but its logic looks good to me. Necessary given what it is
doing. Well tested, has quickchecks.
"""
[[audits.bytecode-alliance.audits.arrayvec]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
version = "0.7.2"
notes = """
Well documented invariants, good assertions for those invariants in unsafe code,
and tested with MIRI to boot. LGTM.
"""
[[audits.bytecode-alliance.audits.base64]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
version = "0.21.0"
notes = "This crate has no dependencies, no build.rs, and contains no unsafe code."
[[audits.bytecode-alliance.audits.bitflags]]
who = "Jamey Sharp <jsharp@fastly.com>"
criteria = "safe-to-deploy"
delta = "2.1.0 -> 2.2.1"
notes = """
This version adds unsafe impls of traits from the bytemuck crate when built
with that library enabled, but I believe the impls satisfy the documented
safety requirements for bytemuck. The other changes are minor.
"""
[[audits.bytecode-alliance.audits.bitflags]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "2.3.2 -> 2.3.3"
notes = """
Nothing outside the realm of what one would expect from a bitflags generator,
all as expected.
"""
[[audits.bytecode-alliance.audits.block-buffer]]
who = "Benjamin Bouvier <public@benj.me>"
criteria = "safe-to-deploy"
delta = "0.9.0 -> 0.10.2"
[[audits.bytecode-alliance.audits.bumpalo]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
version = "3.11.1"
notes = "I am the author of this crate."
[[audits.bytecode-alliance.audits.cfg-if]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
@ -64,6 +254,18 @@ criteria = "safe-to-deploy"
version = "0.3.0"
notes = "This crate uses libc and windows-sys APIs to get and set the raw OS error value."
[[audits.bytecode-alliance.audits.errno]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
delta = "0.3.0 -> 0.3.1"
notes = "Just a dependency version bump and a bug fix for redox"
[[audits.bytecode-alliance.audits.errno-dragonfly]]
who = "Jamey Sharp <jsharp@fastly.com>"
criteria = "safe-to-deploy"
version = "0.1.2"
notes = "This should be portable to any POSIX system and seems like it should be part of the libc crate, but at any rate it's safe as is."
[[audits.bytecode-alliance.audits.futures-channel]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
@ -76,6 +278,21 @@ criteria = "safe-to-deploy"
version = "0.3.27"
notes = "Unsafe used to implement a concurrency primitive AtomicWaker. Well-commented and not obviously incorrect. Like my other audits of these concurrency primitives inside the futures family, I couldn't certify that it is correct without formal methods, but that is out of scope for this vetting."
[[audits.bytecode-alliance.audits.gimli]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.27.0 -> 0.27.3"
notes = "More support for more DWARF, nothing major in this update. Some small refactorings and updates to publication of the package but otherwise everything's in order."
[[audits.bytecode-alliance.audits.gimli]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.27.3 -> 0.28.0"
notes = """
Still looks like a good DWARF-parsing crate, nothing major was added or deleted
and no `unsafe` code to review here.
"""
[[audits.bytecode-alliance.audits.hashbrown]]
who = "Chris Fallin <chris@cfallin.org>"
criteria = "safe-to-deploy"
@ -88,11 +305,24 @@ criteria = "safe-to-deploy"
delta = "0.13.1 -> 0.13.2"
notes = "I read through the diff between v0.13.1 and v0.13.2, and verified that the changes made matched up with the changelog entries. There were very few changes between these two releases, and it was easy to verify what they did."
[[audits.bytecode-alliance.audits.httpdate]]
who = "Pat Hickey <phickey@fastly.com>"
[[audits.bytecode-alliance.audits.libm]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
version = "1.0.2"
notes = "No unsafety, no io"
delta = "0.2.2 -> 0.2.4"
notes = """
This diff primarily fixes a few issues with the `fma`-related functions,
but also contains some other minor fixes as well. Everything looks A-OK and
as expected.
"""
[[audits.bytecode-alliance.audits.libm]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.2.4 -> 0.2.7"
notes = """
This is a minor update which has some testing affordances as well as some
updated math algorithms.
"""
[[audits.bytecode-alliance.audits.matchers]]
who = "Pat Hickey <phickey@fastly.com>"
@ -105,6 +335,41 @@ criteria = "safe-to-deploy"
delta = "0.7.1 -> 0.8.0"
notes = "This was a small update to the crate which has to do with Rust language features and compiler versions, no substantial changes."
[[audits.bytecode-alliance.audits.miniz_oxide]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
version = "0.7.1"
notes = """
This crate is a Rust implementation of zlib compression/decompression and has
been used by default by the Rust standard library for quite some time. It's also
a default dependency of the popular `backtrace` crate for decompressing debug
information. This crate forbids unsafe code and does not otherwise access system
resources. It's originally a port of the `miniz.c` library as well, and given
its own longevity should be relatively hardened against some of the more common
compression-related issues.
"""
[[audits.bytecode-alliance.audits.object]]
who = "Jamey Sharp <jsharp@fastly.com>"
criteria = "safe-to-deploy"
delta = "0.30.1 -> 0.30.3"
notes = """
No unsafe blocks or I/O in the diff. The only changes clearly implement what
the changelog says is new in these versions.
"""
[[audits.bytecode-alliance.audits.object]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.30.3 -> 0.31.1"
notes = "A large-ish update to the crate but nothing out of the ordering. Support for new formats like xcoff, new constants, minor refactorings, etc. Nothing out of the ordinary."
[[audits.bytecode-alliance.audits.object]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "0.31.1 -> 0.32.0"
notes = "Various new features and refactorings as one would expect from an object parsing crate, all looks good."
[[audits.bytecode-alliance.audits.pin-utils]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
@ -115,17 +380,31 @@ who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
delta = "1.0.51 -> 1.0.57"
[[audits.bytecode-alliance.audits.proc-macro2]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
delta = "1.0.59 -> 1.0.63"
notes = """
This is a routine update for new nightly features and new syntax popping up on
nightly, nothing out of the ordinary.
"""
[[audits.bytecode-alliance.audits.quote]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
delta = "1.0.23 -> 1.0.27"
[[audits.bytecode-alliance.audits.rustc-demangle]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
version = "0.1.21"
notes = "I am the author of this crate."
[[audits.bytecode-alliance.audits.sha2]]
who = "Benjamin Bouvier <public@benj.me>"
[[audits.bytecode-alliance.audits.semver]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
delta = "0.9.9 -> 0.10.2"
notes = "This upgrade is mostly a code refactor, as far as I can tell. No new uses of unsafe nor any new ambient capabilities usage."
version = "1.0.17"
notes = "plenty of unsafe pointer and vec tricks, but in well-structured and commented code that appears to be correct"
[[audits.bytecode-alliance.audits.tempfile]]
who = "Pat Hickey <phickey@fastly.com>"
@ -158,6 +437,11 @@ criteria = "safe-to-deploy"
version = "0.2.4"
notes = "Implements a concurrency primitive with atomics, and is not obviously incorrect"
[[audits.bytecode-alliance.audits.unicode-ident]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
version = "1.0.8"
[[audits.bytecode-alliance.audits.unicode-normalization]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
@ -175,77 +459,11 @@ who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
version = "0.3.0"
[[audits.bytecode-alliance.audits.windows-sys]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows-sys]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
delta = "0.42.0 -> 0.45.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows-targets]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
version = "0.42.1"
notes = "This is a Windows API bindings library maintained by Microsoft themselves. Additionally, this particular crate is empty and just collects a bunch of dependencies, which are not exported, so I don't understand why it exists at all."
[[audits.bytecode-alliance.audits.windows_aarch64_gnullvm]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows_aarch64_msvc]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows_i686_gnu]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows_i686_msvc]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows_x86_64_gnu]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows_x86_64_gnullvm]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.bytecode-alliance.audits.windows_x86_64_msvc]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
version = "0.42.0"
notes = "This is a Windows API bindings library maintained by Microsoft themselves."
[[audits.embark-studios.audits.anyhow]]
who = "Johan Andersson <opensource@embark-studios.com>"
criteria = "safe-to-deploy"
version = "1.0.58"
[[audits.embark-studios.audits.epaint]]
who = "Johan Andersson <opensource@embark-studios.com>"
criteria = "safe-to-deploy"
violation = "<0.20.0"
notes = "Specified crate license does not include licenses of embedded fonts if using default features or the `default_fonts` feature. Tracked in: https://github.com/emilk/egui/issues/2321"
[[audits.embark-studios.audits.tap]]
who = "Johan Andersson <opensource@embark-studios.com>"
criteria = "safe-to-deploy"
@ -276,6 +494,12 @@ criteria = "safe-to-deploy"
version = "0.1.0"
notes = "No unsafe usage or ambient capabilities, sane build script"
[[audits.google.audits.cxxbridge-flags]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
delta = "1.0.106 -> 1.0.107"
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.fastrand]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
@ -286,12 +510,40 @@ that the RNG here is not cryptographically secure.
"""
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.httpdate]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
version = "1.0.3"
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.link-cplusplus]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
version = "1.0.9"
notes = """
This crate exists simply to link with libcxx or libstdcxx. No assertions
are made about the safety of either of those libraries. :)
"""
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.pin-project-lite]]
who = "David Koloski <dkoloski@google.com>"
criteria = "safe-to-deploy"
version = "0.2.9"
notes = "Reviewed on https://fxrev.dev/824504"
aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT"
[[audits.google.audits.version_check]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
version = "0.9.4"
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.isrg.audits.aes]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "0.8.2 -> 0.8.3"
[[audits.isrg.audits.base64]]
who = "Tim Geoghegan <timg@letsencrypt.org>"
criteria = "safe-to-deploy"
@ -302,6 +554,11 @@ who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "0.21.1 -> 0.21.2"
[[audits.isrg.audits.base64]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.21.2 -> 0.21.3"
[[audits.isrg.audits.block-buffer]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
@ -312,16 +569,105 @@ who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.2.2"
[[audits.isrg.audits.digest]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.10.6 -> 0.10.7"
[[audits.isrg.audits.either]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "1.6.1"
[[audits.isrg.audits.fiat-crypto]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.1.17"
notes = """
This crate does not contain any unsafe code, and does not use any items from
the standard library or other crates, aside from operations backed by
`std::ops`. All paths with array indexing use integer literals for indexes, so
there are no panics due to indexes out of bounds (as rustc would catch an
out-of-bounds literal index). I did not check whether arithmetic overflows
could cause a panic, and I am relying on the Coq code having satisfied the
necessary preconditions to ensure panics due to overflows are unreachable.
"""
[[audits.isrg.audits.fiat-crypto]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "0.1.17 -> 0.1.18"
[[audits.isrg.audits.fiat-crypto]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.1.18 -> 0.1.19"
notes = """
This release renames many items and adds a new module. The code in the new
module is entirely composed of arithmetic and array accesses.
"""
[[audits.isrg.audits.fiat-crypto]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.1.19 -> 0.1.20"
[[audits.isrg.audits.fiat-crypto]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.1.20 -> 0.2.0"
[[audits.isrg.audits.fiat-crypto]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "0.2.0 -> 0.2.1"
[[audits.isrg.audits.getrandom]]
who = "Tim Geoghegan <timg@letsencrypt.org>"
criteria = "safe-to-deploy"
delta = "0.2.9 -> 0.2.10"
notes = "These changes include some new `unsafe` code for the `emscripten` and `psvita` targets, but all it does is call `libc::getentropy`."
[[audits.isrg.audits.hmac]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.12.1"
[[audits.isrg.audits.num-bigint]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.4.3 -> 0.4.4"
[[audits.isrg.audits.num-traits]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.2.15 -> 0.2.16"
[[audits.isrg.audits.once_cell]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.17.1 -> 1.17.2"
[[audits.isrg.audits.once_cell]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "1.17.2 -> 1.18.0"
[[audits.isrg.audits.opaque-debug]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.3.0"
[[audits.isrg.audits.rand_chacha]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.3.1"
[[audits.isrg.audits.rand_core]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.6.3"
[[audits.isrg.audits.rayon]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
@ -352,6 +698,16 @@ who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.156 -> 1.0.159"
[[audits.isrg.audits.serde]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.160 -> 1.0.162"
[[audits.isrg.audits.serde]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "1.0.162 -> 1.0.163"
[[audits.isrg.audits.serde_derive]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
@ -372,6 +728,16 @@ who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.156 -> 1.0.159"
[[audits.isrg.audits.serde_derive]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.160 -> 1.0.162"
[[audits.isrg.audits.serde_derive]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "1.0.162 -> 1.0.163"
[[audits.isrg.audits.serde_json]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
@ -382,21 +748,36 @@ who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.94 -> 1.0.95"
[[audits.isrg.audits.sha2]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.10.2"
[[audits.isrg.audits.syn]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.104 -> 2.0.11"
[[audits.isrg.audits.unicode-ident]]
who = "David Cook <dcook@divviup.org>"
[[audits.isrg.audits.thiserror]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.2 -> 1.0.3"
delta = "1.0.40 -> 1.0.43"
[[audits.isrg.audits.thiserror-impl]]
who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "1.0.40 -> 1.0.43"
[[audits.isrg.audits.universal-hash]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.4.1"
[[audits.isrg.audits.universal-hash]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
delta = "0.5.0 -> 0.5.1"
[[audits.isrg.audits.untrusted]]
who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
@ -407,12 +788,6 @@ who = "David Cook <dcook@divviup.org>"
criteria = "safe-to-deploy"
version = "0.2.83"
[[audits.mozilla.audits.aho-corasick]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.7.18 -> 0.7.20"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.anyhow]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -465,6 +840,25 @@ version = "0.6.3"
notes = "Another crate I own via contain-rs that is ancient and in maintenance mode but otherwise perfectly fine."
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.bitflags]]
who = "Alex Franchuk <afranchuk@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.3.2 -> 2.0.2"
notes = "Removal of some unsafe code/methods. No changes to externals, just some refactoring (mostly internal)."
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.bitflags]]
who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "2.0.2 -> 2.1.0"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.bitflags]]
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
criteria = "safe-to-deploy"
delta = "2.2.1 -> 2.3.2"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.block-buffer]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -595,6 +989,13 @@ criteria = "safe-to-deploy"
version = "0.4.17"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.log]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.4.17 -> 0.4.18"
notes = "One dependency removed, others updated (which we don't rely on), some APIs (which we don't use) changed."
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.mach2]]
who = "Gabriele Svelto <gsvelto@mozilla.com>"
criteria = "safe-to-deploy"
@ -607,12 +1008,6 @@ criteria = "safe-to-deploy"
delta = "0.6.5 -> 0.7.1"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.miniz_oxide]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.5.3 -> 0.6.2"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.nom]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -701,6 +1096,13 @@ delta = "1.0.57 -> 1.0.59"
notes = "Enabled on Wasm"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.proc-macro2]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.0.63 -> 1.0.66"
notes = "Removed special support for some really old Rust versions"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.quote]]
who = "Nika Layzell <nika@thelayzells.com>"
criteria = "safe-to-deploy"
@ -729,6 +1131,26 @@ criteria = "safe-to-deploy"
delta = "1.0.21 -> 1.0.23"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.quote]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.0.27 -> 1.0.28"
notes = "Enabled on wasm targets"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.quote]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.0.28 -> 1.0.31"
notes = "Minimal changes and removal of the build.rs"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.rand_core]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.6.3 -> 0.6.4"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.rayon]]
who = "Josh Stone <jistone@redhat.com>"
criteria = "safe-to-deploy"
@ -761,12 +1183,6 @@ criteria = "safe-to-deploy"
delta = "1.10.1 -> 1.10.2"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.regex]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.6.0 -> 1.7.0"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.regex-syntax]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -797,6 +1213,13 @@ criteria = "safe-to-deploy"
delta = "1.0.151 -> 1.0.152"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.serde]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.0.163 -> 1.0.179"
notes = "Internal refactorings and some new trait implementations"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.serde_derive]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -815,6 +1238,13 @@ criteria = "safe-to-deploy"
delta = "1.0.151 -> 1.0.152"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.serde_derive]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.0.163 -> 1.0.179"
notes = "Internal refactorings and dependency updates"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.serde_json]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -845,6 +1275,19 @@ criteria = "safe-to-deploy"
delta = "0.10.2 -> 0.10.6"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.syn]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "2.0.18 -> 2.0.26"
notes = "Dependency update & internal refactorings"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.time-core]]
who = "Kershaw Chang <kershaw@mozilla.com>"
criteria = "safe-to-deploy"
version = "0.1.0"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.typenum]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -852,10 +1295,11 @@ delta = "1.15.0 -> 1.16.0"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.unicode-ident]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "1.0.3 -> 1.0.6"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
delta = "1.0.8 -> 1.0.9"
notes = "Dependency updates only"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.unicode-normalization]]
who = "Mike Hommey <mh+mozilla@glandium.org>"

View File

@ -4,44 +4,36 @@
# bdb 18.1.40 2020-09-01
#
# CCache 4.7 appears to drop support for Ubuntu 18.04.
# We will drop Ubuntu 18.04 no later than May 2023.
native_ccache 4.7 2023-07-15
native_ccache 4.7.1 2023-07-15
native_ccache 4.7.2 2023-07-15
native_ccache 4.7.3 2023-07-15
native_ccache 4.7.4 2023-07-15
native_ccache 4.7.5 2023-07-15
native_ccache 4.8 2023-07-15
native_ccache 4.8.1 2023-07-15
native_ccache 4.8.2 2023-07-15
# Clang and Rust are currently pinned to LLVM 15
libcxx 15.0.7 2023-07-15
libcxx 16.0.0 2023-07-15
libcxx 16.0.1 2023-07-15
libcxx 16.0.2 2023-07-15
libcxx 16.0.2 2023-07-15
libcxx 16.0.3 2023-07-15
libcxx 16.0.4 2023-07-15
libcxx 16.0.5 2023-07-15
libcxx 16.0.6 2023-07-15
native_clang 15.0.7 2023-07-15
native_clang 16.0.0 2023-07-15
native_clang 16.0.1 2023-07-15
native_clang 16.0.2 2023-07-15
native_clang 16.0.3 2023-07-15
native_clang 16.0.4 2023-07-15
native_clang 16.0.5 2023-07-15
native_clang 16.0.6 2023-07-15
native_cxxbridge 1.0.96 2023-07-15
native_cxxbridge 1.0.97 2023-07-15
native_rust 1.70.0 2023-07-15
rustcxx 1.0.96 2023-07-15
rustcxx 1.0.97 2023-07-15
libcxx 15.0.7 2023-11-15
libcxx 16.0.0 2023-11-15
libcxx 16.0.1 2023-11-15
libcxx 16.0.2 2023-11-15
libcxx 16.0.2 2023-11-15
libcxx 16.0.3 2023-11-15
libcxx 16.0.4 2023-11-15
libcxx 16.0.5 2023-11-15
libcxx 16.0.6 2023-11-15
libcxx 17.0.0 2023-11-15
libcxx 17.0.1 2023-11-15
native_clang 15.0.7 2023-11-15
native_clang 16.0.0 2023-11-15
native_clang 16.0.1 2023-11-15
native_clang 16.0.2 2023-11-15
native_clang 16.0.3 2023-11-15
native_clang 16.0.4 2023-11-15
native_clang 16.0.5 2023-11-15
native_clang 16.0.6 2023-11-15
native_clang 17.0.0 2023-11-15
native_clang 17.0.1 2023-11-15
native_rust 1.70.0 2023-11-15
native_rust 1.71.0 2023-11-15
native_rust 1.71.1 2023-11-15
native_rust 1.72.0 2023-11-15
native_rust 1.72.1 2023-11-15
# We follow upstream Bitcoin Core's LevelDB updates
leveldb 1.23 2023-07-15
leveldb 1.23 2023-11-15
# We're never updating to this version
bdb 18.1.40 2024-03-01

View File

@ -56,18 +56,36 @@ CXXBRIDGE_RS = \
rust/src/blake2b.rs \
rust/src/ed25519.rs \
rust/src/equihash.rs \
rust/src/history.rs \
rust/src/init.rs \
rust/src/random.rs \
rust/src/sapling/spec.rs \
rust/src/sapling/zip32.rs \
rust/src/sprout.rs \
rust/src/streams.rs \
rust/src/bridge.rs
CXXBRIDGE_H = \
rust/gen/include/rust/blake2b.h \
rust/gen/include/rust/ed25519.h \
rust/gen/include/rust/equihash.h \
rust/gen/include/rust/history.h \
rust/gen/include/rust/init.h \
rust/gen/include/rust/random.h \
rust/gen/include/rust/sapling/spec.h \
rust/gen/include/rust/sapling/zip32.h \
rust/gen/include/rust/sprout.h \
rust/gen/include/rust/streams.h \
rust/gen/include/rust/bridge.h
CXXBRIDGE_CPP = \
rust/gen/src/blake2b.cpp \
rust/gen/src/ed25519.cpp \
rust/gen/src/equihash.cpp \
rust/gen/src/history.cpp \
rust/gen/src/init.cpp \
rust/gen/src/random.cpp \
rust/gen/src/sapling/spec.cpp \
rust/gen/src/sapling/zip32.cpp \
rust/gen/src/sprout.cpp \
rust/gen/src/streams.cpp \
rust/gen/src/bridge.cpp
@ -78,7 +96,7 @@ CXXBRIDGE_OPTS = -i rust/cxx.h
$(CXXBRIDGE_RS): ;
$(CXXBRIDGE_H) $(CXXBRIDGE_CPP): $(CXXBRIDGE_RS)
@$(MKDIR_P) $(@D)
$(AM_V_GEN)$(CXXBRIDGE) $(CXXBRIDGE_OPTS) rust/src/$(basename $(@F)).rs -o $@
$(AM_V_GEN)$(CXXBRIDGE) $(CXXBRIDGE_OPTS) $(basename $(patsubst rust/gen/include/rust/%,rust/src/%,$(patsubst rust/gen/src/%,rust/src/%,$@))).rs -o $@
# We pass through CC etc. flags so they are available to Rust dependencies that internally
# compile C or C++ code with the `cc` crate.

View File

@ -11,7 +11,7 @@
#include "main.h"
#include "util/system.h"
#include "librustzcash.h"
#include <rust/init.h>
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
@ -23,24 +23,17 @@ main(int argc, char** argv)
SetupEnvironment();
fPrintToDebugLog = false; // don't want to write to debug log file
fs::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
fs::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
fs::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";
static_assert(
sizeof(fs::path::value_type) == sizeof(codeunit),
"librustzcash not configured correctly");
auto sapling_spend_str = sapling_spend.native();
auto sapling_output_str = sapling_output.native();
auto sprout_groth16_str = sprout_groth16.native();
librustzcash_init_zksnark_params(
reinterpret_cast<const codeunit*>(sapling_spend_str.c_str()),
sapling_spend_str.length(),
reinterpret_cast<const codeunit*>(sapling_output_str.c_str()),
sapling_output_str.length(),
reinterpret_cast<const codeunit*>(sprout_groth16_str.c_str()),
sprout_groth16_str.length(),
init::zksnark_params(
rust::String(
reinterpret_cast<const codeunit*>(sprout_groth16_str.data()),
sprout_groth16_str.size()),
true
);

View File

@ -242,7 +242,7 @@ public:
}
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000c7da51ec335d66c");
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000e5725ff9228d8c9");
/**
* The message start string should be awesome!
@ -301,10 +301,11 @@ public:
(1400000, uint256S("0x0000000001155ecec0ad3924d47ad476c0a5ed7527b8776f53cbda1a780b9f76"))
(1600000, uint256S("0x0000000000aae69fb228f90e77f34c24b7920667eaca726c3a3939536f03dcfc"))
(1860000, uint256S("0x000000000043a968c78af5fb8133e00e6fe340051c19dd969e53ab62bf3dc22a"))
(2000000, uint256S("0x00000000010accaf2f87934765dc2e0bf4823a2b1ae2c1395b334acfce52ad68")),
1677602242, // * UNIX timestamp of last checkpoint block
12380742, // * total number of transactions between genesis and last checkpoint
7131 // * estimated number of transactions per day after checkpoint
(2000000, uint256S("0x00000000010accaf2f87934765dc2e0bf4823a2b1ae2c1395b334acfce52ad68"))
(2200000, uint256S("0x0000000001a0139c4c4d0e8f68cc562227c6003f4b1b640a3d921aeb8c3d2e3d")),
1692680380, // * UNIX timestamp of last checkpoint block
13316603, // * total number of transactions between genesis and last checkpoint
6973 // * estimated number of transactions per day after checkpoint
// (total number of tx * 48 * 24) / checkpoint block height
};

View File

@ -16,8 +16,8 @@
//! 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 6
#define CLIENT_VERSION_REVISION 1
#define CLIENT_VERSION_MINOR 7
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 50
//! Set to true for release, false for prerelease or test build

View File

@ -11,6 +11,8 @@
#include <assert.h>
#include <rust/history.h>
#include <tracing.h>
/**
@ -531,9 +533,7 @@ void CCoinsViewCache::PushHistoryNode(uint32_t epochId, const HistoryNode node)
// special case, it just goes into the cache right away
historyCache.Extend(node);
if (librustzcash_mmr_hash_node(epochId, &node, historyCache.root.begin()) != 0) {
throw std::runtime_error("hashing node failed");
};
historyCache.root = uint256::FromRawBytes(mmr::hash_node(epochId, node));
return;
}
@ -546,27 +546,24 @@ void CCoinsViewCache::PushHistoryNode(uint32_t epochId, const HistoryNode node)
uint256 newRoot;
std::array<HistoryNode, 32> appendBuf = {};
uint32_t appends = librustzcash_mmr_append(
auto effect = mmr::append(
epochId,
historyCache.length,
entry_indices.data(),
entries.data(),
entry_indices.size(),
&node,
newRoot.begin(),
appendBuf.data()
{entry_indices.data(), entry_indices.size()},
{entries.data(), entries.size()},
node,
{appendBuf.data(), 32}
);
for (size_t i = 0; i < appends; i++) {
for (size_t i = 0; i < effect.count; i++) {
historyCache.Extend(appendBuf[i]);
}
historyCache.root = newRoot;
historyCache.root = uint256::FromRawBytes(effect.root);
}
void CCoinsViewCache::PopHistoryNode(uint32_t epochId) {
HistoryCache& historyCache = SelectHistoryCache(epochId);
uint256 newRoot;
switch (historyCache.length) {
case 0:
@ -602,15 +599,11 @@ void CCoinsViewCache::PopHistoryNode(uint32_t epochId) {
// After removing a leaf from a tree with two leaves, we are left
// with a single-node tree, whose root is just the hash of that
// node.
if (librustzcash_mmr_hash_node(
auto newRoot = mmr::hash_node(
epochId,
&tmpHistoryRoot,
newRoot.begin()
) != 0) {
throw std::runtime_error("hashing node failed");
}
tmpHistoryRoot);
historyCache.Truncate(1);
historyCache.root = newRoot;
historyCache.root = uint256::FromRawBytes(newRoot);
return;
}
default:
@ -621,18 +614,16 @@ void CCoinsViewCache::PopHistoryNode(uint32_t epochId) {
uint32_t peak_count = PreloadHistoryTree(epochId, true, entries, entry_indices);
uint32_t numberOfDeletes = librustzcash_mmr_delete(
auto effect = mmr::remove(
epochId,
historyCache.length,
entry_indices.data(),
entries.data(),
peak_count,
entries.size() - peak_count,
newRoot.begin()
{entry_indices.data(), entry_indices.size()},
{entries.data(), entries.size()},
peak_count
);
historyCache.Truncate(historyCache.length - numberOfDeletes);
historyCache.root = newRoot;
historyCache.Truncate(historyCache.length - effect.count);
historyCache.root = uint256::FromRawBytes(effect.root);
return;
}
}

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 = 2129776;
static const int APPROX_RELEASE_HEIGHT = 2243176;
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

@ -1140,7 +1140,7 @@ TEST(ChecktransactionTests, InvalidSaplingShieldedCoinbase) {
RegtestActivateHeartwood(false, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
// From Heartwood, the output description is allowed but invalid (undecryptable).
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-outct", false, "")).Times(1);
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-ct", false, "")).Times(1);
ContextualCheckTransaction(tx, state, Params(), 10, 57);
RegtestDeactivateHeartwood();
@ -1183,7 +1183,7 @@ TEST(ChecktransactionTests, HeartwoodAcceptsSaplingShieldedCoinbase) {
EXPECT_TRUE(tx.IsCoinBase());
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-outct", false, "")).Times(1);
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-ct", false, "")).Times(1);
ContextualCheckTransaction(tx, state, chainparams, 10, 57);
}
@ -1199,11 +1199,12 @@ TEST(ChecktransactionTests, HeartwoodAcceptsSaplingShieldedCoinbase) {
EXPECT_TRUE(tx.IsCoinBase());
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-outct", false, "")).Times(1);
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-ct", false, "")).Times(1);
ContextualCheckTransaction(tx, state, chainparams, 10, 57);
}
// Transaction should fail with a bad encCiphertext.
// Error message is the same because the Rust decryptor doesn't say which failed.
{
sapling::test_only_replace_output_parts(
mtx.saplingBundle.GetDetailsMut(),
@ -1215,7 +1216,7 @@ TEST(ChecktransactionTests, HeartwoodAcceptsSaplingShieldedCoinbase) {
EXPECT_TRUE(tx.IsCoinBase());
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-encct", false, "")).Times(1);
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-output-desc-invalid-ct", false, "")).Times(1);
ContextualCheckTransaction(tx, state, chainparams, 10, 57);
}

View File

@ -143,8 +143,8 @@ TEST(History, GarbageMemoryHash) {
HistoryNode node0Garbage = getLeafN(1);
HistoryNode node1Garbage = getLeafN(2);
node0Garbage.bytes[NODE_SERIALIZED_LENGTH - 1] = node0.bytes[NODE_SERIALIZED_LENGTH - 1] ^ 1;
node1Garbage.bytes[NODE_SERIALIZED_LENGTH - 1] = node1.bytes[NODE_SERIALIZED_LENGTH - 1] ^ 1;
node0Garbage[NODE_SERIALIZED_LENGTH - 1] = node0[NODE_SERIALIZED_LENGTH - 1] ^ 1;
node1Garbage[NODE_SERIALIZED_LENGTH - 1] = node1[NODE_SERIALIZED_LENGTH - 1] ^ 1;
viewGarbage.PushHistoryNode(consensusBranchId, node0Garbage);
viewGarbage.PushHistoryNode(consensusBranchId, node1Garbage);

View File

@ -23,290 +23,6 @@ public:
}
};
TEST(NoteEncryption, NotePlaintext)
{
SelectParams(CBaseChainParams::REGTEST);
std::vector<libzcash::Zip212Enabled> zip_212_enabled = {libzcash::Zip212Enabled::BeforeZip212, libzcash::Zip212Enabled::AfterZip212};
const Consensus::Params& (*activations [])() = {RegtestActivateSapling, RegtestActivateCanopy};
void (*deactivations [])() = {RegtestDeactivateSapling, RegtestDeactivateCanopy};
using namespace libzcash;
auto xsk = SaplingSpendingKey(uint256()).expanded_spending_key();
auto fvk = xsk.full_viewing_key();
auto ivk = fvk.in_viewing_key();
SaplingPaymentAddress addr = *ivk.address({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
Memo::Bytes memo;
for (size_t i = 0; i < Memo::SIZE; i++) {
// Fill the message with dummy data
memo[i] = (unsigned char) i;
}
for (int ver = 0; ver < zip_212_enabled.size(); ver++){
auto params = (*activations[ver])();
auto ovk = random_uint256();
auto value = 39393;
auto builder = sapling::new_builder(*Params().RustNetwork(), 10);
builder->add_recipient(
ovk.GetRawBytes(),
addr.GetRawBytes(),
value,
memo);
auto bundle = sapling::apply_bundle_signatures(sapling::build_bundle(std::move(builder), 10), {});
auto outputs = bundle->outputs();
std::optional<SaplingOutgoingPlaintext> decrypted_out_ct;
uint256 cmu;
uint256 epk;
libzcash::SaplingEncCiphertext ct;
for (auto& output : outputs) {
decrypted_out_ct = SaplingOutgoingPlaintext::decrypt(
output.out_ciphertext(),
ovk,
uint256::FromRawBytes(output.cv()),
uint256::FromRawBytes(output.cmu()),
uint256::FromRawBytes(output.ephemeral_key()));
if (decrypted_out_ct) {
cmu = uint256::FromRawBytes(output.cmu());
epk = uint256::FromRawBytes(output.ephemeral_key());
ct = output.enc_ciphertext();
break;
}
}
ASSERT_TRUE(decrypted_out_ct.has_value());
auto decrypted_out_ct_unwrapped = decrypted_out_ct.value();
ASSERT_TRUE(decrypted_out_ct_unwrapped.pk_d == addr.pk_d);
// Test sender won't accept invalid commitments
ASSERT_FALSE(
SaplingNotePlaintext::decrypt(
params,
1,
ct,
epk,
decrypted_out_ct_unwrapped.esk,
decrypted_out_ct_unwrapped.pk_d,
uint256()
)
);
// Test sender can decrypt the note ciphertext.
auto foo = SaplingNotePlaintext::decrypt(
params,
1,
ct,
epk,
decrypted_out_ct_unwrapped.esk,
decrypted_out_ct_unwrapped.pk_d,
cmu
);
if (!foo) {
FAIL();
}
auto bar = foo.value();
ASSERT_TRUE(bar.value() == value);
ASSERT_TRUE(bar.memo() == Memo::FromBytes(memo));
ASSERT_TRUE(bar.d == addr.d);
(*deactivations[ver])();
}
}
TEST(NoteEncryption, SaplingApi)
{
using namespace libzcash;
// Create recipient addresses
auto sk = SaplingSpendingKey(uint256()).expanded_spending_key();
auto vk = sk.full_viewing_key();
auto ivk = vk.in_viewing_key();
SaplingPaymentAddress pk_1 = *ivk.address({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
SaplingPaymentAddress pk_2 = *ivk.address({4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
// Blob of stuff we're encrypting
std::array<unsigned char, SAPLING_ENCPLAINTEXT_SIZE> message;
for (size_t i = 0; i < SAPLING_ENCPLAINTEXT_SIZE; i++) {
// Fill the message with dummy data
message[i] = (unsigned char) i;
}
std::array<unsigned char, SAPLING_OUTPLAINTEXT_SIZE> small_message;
for (size_t i = 0; i < SAPLING_OUTPLAINTEXT_SIZE; i++) {
// Fill the message with dummy data
small_message[i] = (unsigned char) i;
}
uint256 esk;
librustzcash_sapling_generate_r(esk.begin());
// Invalid diversifier
ASSERT_EQ(std::nullopt, SaplingNoteEncryption::FromDiversifier({1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, esk));
// Encrypt to pk_1
auto enc = *SaplingNoteEncryption::FromDiversifier(pk_1.d, esk);
auto ciphertext_1 = *enc.encrypt_to_recipient(
pk_1.pk_d,
message
);
auto epk_1 = enc.get_epk();
{
uint256 test_epk;
uint256 test_esk = enc.get_esk();
ASSERT_TRUE(librustzcash_sapling_ka_derivepublic(pk_1.d.begin(), test_esk.begin(), test_epk.begin()));
ASSERT_TRUE(test_epk == epk_1);
}
auto cv_1 = random_uint256();
auto cm_1 = random_uint256();
auto out_ciphertext_1 = enc.encrypt_to_ourselves(
sk.ovk,
cv_1,
cm_1,
small_message
);
// Encrypt to pk_2
enc = *SaplingNoteEncryption::FromDiversifier(pk_2.d, esk);
auto ciphertext_2 = *enc.encrypt_to_recipient(
pk_2.pk_d,
message
);
auto epk_2 = enc.get_epk();
auto cv_2 = random_uint256();
auto cm_2 = random_uint256();
auto out_ciphertext_2 = enc.encrypt_to_ourselves(
sk.ovk,
cv_2,
cm_2,
small_message
);
// Test nonce-reuse resistance of API
{
auto tmp_enc = *SaplingNoteEncryption::FromDiversifier(pk_1.d, esk);
tmp_enc.encrypt_to_recipient(
pk_1.pk_d,
message
);
ASSERT_THROW(tmp_enc.encrypt_to_recipient(
pk_1.pk_d,
message
), std::logic_error);
tmp_enc.encrypt_to_ourselves(
sk.ovk,
cv_2,
cm_2,
small_message
);
ASSERT_THROW(tmp_enc.encrypt_to_ourselves(
sk.ovk,
cv_2,
cm_2,
small_message
), std::logic_error);
}
// Try to decrypt
auto plaintext_1 = *AttemptSaplingEncDecryption(
ciphertext_1,
ivk,
epk_1
);
ASSERT_TRUE(message == plaintext_1);
auto small_plaintext_1 = *AttemptSaplingOutDecryption(
out_ciphertext_1,
sk.ovk,
cv_1,
cm_1,
epk_1
);
ASSERT_TRUE(small_message == small_plaintext_1);
auto plaintext_2 = *AttemptSaplingEncDecryption(
ciphertext_2,
ivk,
epk_2
);
ASSERT_TRUE(message == plaintext_2);
auto small_plaintext_2 = *AttemptSaplingOutDecryption(
out_ciphertext_2,
sk.ovk,
cv_2,
cm_2,
epk_2
);
ASSERT_TRUE(small_message == small_plaintext_2);
// Try to decrypt out ciphertext with wrong key material
ASSERT_FALSE(AttemptSaplingOutDecryption(
out_ciphertext_1,
random_uint256(),
cv_1,
cm_1,
epk_1
));
ASSERT_FALSE(AttemptSaplingOutDecryption(
out_ciphertext_1,
sk.ovk,
random_uint256(),
cm_1,
epk_1
));
ASSERT_FALSE(AttemptSaplingOutDecryption(
out_ciphertext_1,
sk.ovk,
cv_1,
random_uint256(),
epk_1
));
ASSERT_FALSE(AttemptSaplingOutDecryption(
out_ciphertext_1,
sk.ovk,
cv_1,
cm_1,
random_uint256()
));
// Try to decrypt with wrong ephemeral key
ASSERT_FALSE(AttemptSaplingEncDecryption(
ciphertext_1,
ivk,
epk_2
));
ASSERT_FALSE(AttemptSaplingEncDecryption(
ciphertext_2,
ivk,
epk_1
));
// Try to decrypt with wrong ivk
ASSERT_FALSE(AttemptSaplingEncDecryption(
ciphertext_1,
uint256(),
epk_1
));
ASSERT_FALSE(AttemptSaplingEncDecryption(
ciphertext_2,
uint256(),
epk_2
));
}
TEST(NoteEncryption, api)
{
uint256 sk_enc = ZCNoteEncryption::generate_privkey(uint252(uint256S("21035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a07")));

View File

@ -1,13 +1,13 @@
#include <gtest/gtest.h>
#include "librustzcash.h"
#include "uint256.h"
#include <rust/sapling/spec.h>
TEST(PedersenHash, TestAPI) {
const uint256 a = uint256S("87a086ae7d2252d58729b30263fb7b66308bf94ef59a76c9c86e7ea016536505");
const uint256 b = uint256S("a75b84a125b2353da7e8d96ee2a15efe4de23df9601b9d9564ba59de57130406");
uint256 result;
librustzcash_merkle_hash(25, a.begin(), b.begin(), result.begin());
uint256 result = uint256::FromRawBytes(sapling::spec::merkle_hash(25, a.GetRawBytes(), b.GetRawBytes()));
uint256 expected_result = uint256S("5bf43b5736c19b714d1f462c9d22ba3492c36e3d9bbd7ca24d94b440550aa561");

View File

@ -7,6 +7,8 @@
#include "zcash/IncrementalMerkleTree.hpp"
#include "transaction_builder.h"
#include <rust/init.h>
int GenZero(int n)
{
return 0;
@ -18,24 +20,17 @@ int GenMax(int n)
}
void LoadProofParameters() {
fs::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
fs::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
fs::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";
static_assert(
sizeof(fs::path::value_type) == sizeof(codeunit),
"librustzcash not configured correctly");
auto sapling_spend_str = sapling_spend.native();
auto sapling_output_str = sapling_output.native();
auto sprout_groth16_str = sprout_groth16.native();
librustzcash_init_zksnark_params(
reinterpret_cast<const codeunit*>(sapling_spend_str.c_str()),
sapling_spend_str.length(),
reinterpret_cast<const codeunit*>(sapling_output_str.c_str()),
sapling_output_str.length(),
reinterpret_cast<const codeunit*>(sprout_groth16_str.c_str()),
sprout_groth16_str.length(),
init::zksnark_params(
rust::String(
reinterpret_cast<const codeunit*>(sprout_groth16_str.data()),
sprout_groth16_str.size()),
true
);
}

View File

@ -850,44 +850,22 @@ static void ZC_LoadParams(
struct timeval tv_start, tv_end;
float elapsed;
fs::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
fs::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
fs::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";
if (!(
fs::exists(sapling_spend) &&
fs::exists(sapling_output) &&
fs::exists(sprout_groth16)
)) {
uiInterface.ThreadSafeMessageBox(strprintf(
_("Cannot find the Zcash network parameters in the following directory:\n"
"%s\n"
"Please run 'zcash-fetch-params' or './zcutil/fetch-params.sh' and then restart."),
ZC_GetParamsDir()),
"", CClientUIInterface::MSG_ERROR);
StartShutdown();
return;
}
static_assert(
sizeof(fs::path::value_type) == sizeof(codeunit),
"librustzcash not configured correctly");
auto sapling_spend_str = sapling_spend.native();
auto sapling_output_str = sapling_output.native();
auto sprout_groth16_str = sprout_groth16.native();
LogPrintf("Loading Sapling (Spend) parameters from %s\n", sapling_spend.string().c_str());
LogPrintf("Loading Sapling (Output) parameters from %s\n", sapling_output.string().c_str());
LogPrintf("Loading Sapling (Sprout Groth16) parameters from %s\n", sprout_groth16.string().c_str());
LogPrintf("Sprout parameters will be fetched from %s if needed\n", sprout_groth16.string().c_str());
LogPrintf("Sapling parameters are bundled in this binary\n");
LogPrintf("Orchard parameters are generated deterministically\n");
gettimeofday(&tv_start, 0);
librustzcash_init_zksnark_params(
reinterpret_cast<const codeunit*>(sapling_spend_str.c_str()),
sapling_spend_str.length(),
reinterpret_cast<const codeunit*>(sapling_output_str.c_str()),
sapling_output_str.length(),
reinterpret_cast<const codeunit*>(sprout_groth16_str.c_str()),
sprout_groth16_str.length(),
init::zksnark_params(
rust::String(
reinterpret_cast<const codeunit*>(sprout_groth16_str.data()),
sprout_groth16_str.size()),
true
);
@ -1086,7 +1064,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
std::set_new_handler(new_handler_terminate);
// Set up global Rayon threadpool.
zcashd_init_rayon_threadpool();
init::rayon_threadpool();
// ********************************************************* Step 2: parameter interactions
const CChainParams& chainparams = Params();

View File

@ -985,13 +985,10 @@ bool ContextualCheckTransaction(
// https://zips.z.cash/zip-0213#specification
uint256 ovk;
for (const auto& output : tx.GetSaplingOutputs()) {
bool zip_212_enabled;
libzcash::SaplingPaymentAddress zaddr;
CAmount value;
bool zip_212_enabled;
libzcash::SaplingPaymentAddress zaddr;
CAmount value;
// EoS height for 5.3.3 and 5.4.2 is 2121024 (mainnet).
// On testnet this height will be in the past, as of the 5.5.0 release.
if (nHeight >= 2121200) {
try {
auto decrypted = wallet::try_sapling_output_recovery(
*chainparams.RustNetwork(),
@ -1013,48 +1010,9 @@ bool ContextualCheckTransaction(
return state.DoS(
DOS_LEVEL_BLOCK,
error("ContextualCheckTransaction(): failed to recover plaintext of coinbase output description"),
REJECT_INVALID, "bad-cb-output-desc-invalid-outct");
}
} else {
auto outPlaintext = SaplingOutgoingPlaintext::decrypt(
output.out_ciphertext(),
ovk,
uint256::FromRawBytes(output.cv()),
uint256::FromRawBytes(output.cmu()),
uint256::FromRawBytes(output.ephemeral_key()));
if (!outPlaintext) {
return state.DoS(
DOS_LEVEL_BLOCK,
error("ContextualCheckTransaction(): coinbase output description has invalid outCiphertext"),
REJECT_INVALID, "bad-cb-output-desc-invalid-outct");
REJECT_INVALID, "bad-cb-output-desc-invalid-ct");
}
// SaplingNotePlaintext::decrypt() checks note commitment validity.
auto encPlaintext = SaplingNotePlaintext::decrypt(
consensus,
nHeight,
output.enc_ciphertext(),
uint256::FromRawBytes(output.ephemeral_key()),
outPlaintext->esk,
outPlaintext->pk_d,
uint256::FromRawBytes(output.cmu()));
if (!encPlaintext) {
return state.DoS(
DOS_LEVEL_BLOCK,
error("ContextualCheckTransaction(): coinbase output description has invalid encCiphertext"),
REJECT_INVALID, "bad-cb-output-desc-invalid-encct");
}
auto leadByte = encPlaintext->get_leadbyte();
assert(leadByte == 0x01 || leadByte == 0x02);
zip_212_enabled = (leadByte == 0x02);
zaddr = libzcash::SaplingPaymentAddress(encPlaintext->d, outPlaintext->pk_d);
value = encPlaintext->value();
}
{
// ZIP 207: detect shielded funding stream elements
if (canopyActive) {
for (auto it = fundingStreamElements.begin(); it != fundingStreamElements.end(); ++it) {
@ -1078,7 +1036,6 @@ bool ContextualCheckTransaction(
REJECT_INVALID,
"bad-cb-output-desc-invalid-note-plaintext-version");
}
}
}
}
} else {
@ -2019,10 +1976,7 @@ bool AcceptToMemoryPool(
}
pool.EnsureSizeLimit();
MetricsGauge("zcash.mempool.size.transactions", pool.size());
MetricsGauge("zcash.mempool.size.bytes", pool.GetTotalTxSize());
MetricsGauge("zcash.mempool.usage.bytes", pool.DynamicMemoryUsage());
pool.UpdateMetrics();
}
}

View File

@ -8,7 +8,7 @@
#include <variant>
#include <librustzcash.h>
#include <rust/sprout.h>
class SproutProofVerifier
{
@ -34,16 +34,16 @@ public:
{
uint256 h_sig = ZCJoinSplit::h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
return librustzcash_sprout_verify(
proof.begin(),
jsdesc.anchor.begin(),
h_sig.begin(),
jsdesc.macs[0].begin(),
jsdesc.macs[1].begin(),
jsdesc.nullifiers[0].begin(),
jsdesc.nullifiers[1].begin(),
jsdesc.commitments[0].begin(),
jsdesc.commitments[1].begin(),
return sprout::verify(
proof,
jsdesc.anchor.GetRawBytes(),
h_sig.GetRawBytes(),
jsdesc.macs[0].GetRawBytes(),
jsdesc.macs[1].GetRawBytes(),
jsdesc.nullifiers[0].GetRawBytes(),
jsdesc.nullifiers[1].GetRawBytes(),
jsdesc.commitments[0].GetRawBytes(),
jsdesc.commitments[1].GetRawBytes(),
jsdesc.vpub_old,
jsdesc.vpub_new
);

View File

@ -20,7 +20,7 @@
#include <sys/time.h>
#endif
#include <librustzcash.h>
#include <rust/random.h>
static inline int64_t GetPerformanceCounter()
{
@ -37,7 +37,7 @@ static inline int64_t GetPerformanceCounter()
void GetRandBytes(unsigned char* buf, size_t num)
{
librustzcash_getrandom(buf, num);
rust::getrandom({buf, num});
}
uint128_t GetRandUInt128(uint128_t nMax)

View File

@ -308,9 +308,10 @@ UniValue getblockcount(const UniValue& params, bool fHelp)
if (fHelp || params.size() != 0)
throw runtime_error(
"getblockcount\n"
"\nReturns the number of blocks in the best valid block chain.\n"
"\nReturns the height of the most recent block in the best valid block chain (equivalently,\n"
"the number of blocks in this chain excluding the genesis block).\n"
"\nResult:\n"
"n (numeric) The current block count\n"
"n (numeric) The height of the most recent block.\n"
"\nExamples:\n"
+ HelpExampleCli("getblockcount", "")
+ HelpExampleRpc("getblockcount", "")

View File

@ -11,288 +11,4 @@
#include <stdalign.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
void librustzcash_to_scalar(const unsigned char *input, unsigned char *result);
void librustzcash_ask_to_ak(const unsigned char *ask, unsigned char *result);
void librustzcash_nsk_to_nk(const unsigned char *nsk, unsigned char *result);
void librustzcash_crh_ivk(const unsigned char *ak, const unsigned char *nk, unsigned char *result);
bool librustzcash_check_diversifier(const unsigned char *diversifier);
bool librustzcash_ivk_to_pkd(const unsigned char *ivk, const unsigned char *diversifier, unsigned char *result);
/// Loads the zk-SNARK parameters into memory and saves
/// paths as necessary. Only called once.
void librustzcash_init_zksnark_params(
const codeunit* spend_path,
size_t spend_path_len,
const codeunit* output_path,
size_t output_path_len,
const codeunit* sprout_path,
size_t sprout_path_len,
bool load_proving_keys
);
/// Writes the "uncommitted" note value for empty leaves
/// of the merkle tree. `result` must be a valid pointer
/// to 32 bytes which will be written.
void librustzcash_tree_uncommitted(
unsigned char *result
);
/// Computes a merkle tree hash for a given depth.
/// The `depth` parameter should not be larger than
/// 62.
///
/// `a` and `b` each must be of length 32, and must each
/// be scalars of BLS12-381.
///
/// The result of the merkle tree hash is placed in
/// `result`, which must also be of length 32.
void librustzcash_merkle_hash(
size_t depth,
const unsigned char *a,
const unsigned char *b,
unsigned char *result
);
/// Computes the signature for each Spend description, given the key
/// `ask`, the re-randomization `ar`, the 32-byte sighash `sighash`,
/// and an output `result` buffer of 64-bytes for the signature.
///
/// This function will fail if the provided `ask` or `ar` are invalid.
bool librustzcash_sapling_spend_sig(
const unsigned char *ask,
const unsigned char *ar,
const unsigned char *sighash,
unsigned char *result
);
/// Compute a Sapling nullifier.
///
/// The `diversifier` parameter must be 11 bytes in length.
/// The `pk_d`, `r`, and `nk` parameters must be of length 32.
/// The result is also of length 32 and placed in `result`.
/// Returns false if the diversifier or pk_d is not valid
bool librustzcash_sapling_compute_nf(
const unsigned char *diversifier,
const unsigned char *pk_d,
const uint64_t value,
const unsigned char *rcm,
const unsigned char *nk,
const uint64_t position,
unsigned char *result
);
/// Compute a Sapling commitment.
///
/// The `diversifier` parameter must be 11 bytes in length.
/// The `pk_d` and `r` parameters must be of length 32.
/// The result is also of length 32 and placed in `result`.
/// Returns false if the diversifier or pk_d is not valid
bool librustzcash_sapling_compute_cmu(
const unsigned char *diversifier,
const unsigned char *pk_d,
const uint64_t value,
const unsigned char *rcm,
unsigned char *result
);
/// Compute KDF^Sapling(KA^Agree(sk, P), ephemeral_key).
///
/// P and sk must point to 32-byte buffers. If P does not
/// represent a Jubjub point or sk does not represent a
/// canonical Jubjub scalar, this function returns false.
/// Otherwise, it writes the result to the 32-byte `result`
/// buffer and returns true.
bool librustzcash_sapling_ka_derive_symmetric_key(
const unsigned char *p,
const unsigned char *sk,
const unsigned char *ephemeral_key,
unsigned char *result
);
/// Compute g_d = GH(diversifier) and returns
/// false if the diversifier is invalid.
/// Computes [esk] g_d and writes the result
/// to the 32-byte `result` buffer. Returns
/// false if `esk` is not a valid scalar.
bool librustzcash_sapling_ka_derivepublic(
const unsigned char *diversifier,
const unsigned char *esk,
unsigned char *result
);
/// Generate uniformly random scalar in Jubjub.
/// The result is of length 32.
void librustzcash_sapling_generate_r(
unsigned char *result
);
/// Sprout JoinSplit proof generation.
void librustzcash_sprout_prove(
unsigned char *proof_out,
const unsigned char *phi,
const unsigned char *rt,
const unsigned char *h_sig,
const unsigned char *in_sk1,
uint64_t in_value1,
const unsigned char *in_rho1,
const unsigned char *in_r1,
const unsigned char *in_auth1,
const unsigned char *in_sk2,
uint64_t in_value2,
const unsigned char *in_rho2,
const unsigned char *in_r2,
const unsigned char *in_auth2,
const unsigned char *out_pk1,
uint64_t out_value1,
const unsigned char *out_r1,
const unsigned char *out_pk2,
uint64_t out_value2,
const unsigned char *out_r2,
uint64_t vpub_old,
uint64_t vpub_new
);
/// Sprout JoinSplit proof verification.
bool librustzcash_sprout_verify(
const unsigned char *proof,
const unsigned char *rt,
const unsigned char *h_sig,
const unsigned char *mac1,
const unsigned char *mac2,
const unsigned char *nf1,
const unsigned char *nf2,
const unsigned char *cm1,
const unsigned char *cm2,
uint64_t vpub_old,
uint64_t vpub_new
);
/// Derive the master ExtendedSpendingKey from a seed.
void librustzcash_zip32_sapling_xsk_master(
const unsigned char *seed,
size_t seedlen,
unsigned char *xsk_master
);
/// Derive a child ExtendedSpendingKey from a parent.
void librustzcash_zip32_sapling_xsk_derive(
const unsigned char *xsk_parent,
uint32_t i,
unsigned char *xsk_i
);
/// Derive a internal ExtendedSpendingKey from an external key
void librustzcash_zip32_sapling_xsk_derive_internal(
const unsigned char *xsk_external,
unsigned char *xsk_internal
);
/// Derive a child ExtendedFullViewingKey from a parent.
bool librustzcash_zip32_sapling_xfvk_derive(
const unsigned char *xfvk_parent,
uint32_t i,
unsigned char *xfvk_i
);
/**
* Derive the Sapling internal FVK corresponding to the given
* Sapling external FVK.
*/
void librustzcash_zip32_sapling_derive_internal_fvk(
const unsigned char *fvk,
const unsigned char *dk,
unsigned char *fvk_ret,
unsigned char *dk_ret
);
/**
* Derive a PaymentAddress from a (SaplingFullViewingKey, DiversifierKey)
* pair. Returns 'false' if no valid address can be derived for the
* specified diversifier index.
*
* Arguments:
* - fvk: [c_uchar; 96] the serialized form of a Sapling full viewing key
* - dk: [c_uchar; 32] the byte representation of a Sapling diversifier key
* - j: [c_uchar; 11] the 88-bit diversifier index, encoded in little-endian
* order
* - addr_ret: [c_uchar; 43] array to which the returned address will be
* written, if the specified diversifier index `j` produces a valid
* address.
*/
bool librustzcash_zip32_sapling_address(
const unsigned char *fvk,
const unsigned char *dk,
const unsigned char *j,
unsigned char *addr_ret
);
/**
* Derive a PaymentAddress from a (SaplingFullViewingKey, DiversifierKey)
* pair by searching the space of valid diversifiers starting at
* diversifier index `j`. This will always return a valid address along
* with the diversifier index that produced the address unless no addresses
* can be derived at any diversifier index >= `j`, in which case this
* function will return `false`.
*
* Arguments:
* - fvk: [c_uchar; 96] the serialized form of a Sapling full viewing key
* - dk: [c_uchar; 32] the byte representation of a Sapling diversifier key
* - j: [c_uchar; 11] the 88-bit diversifier index at which to start
* searching, encoded in little-endian order
* - j_ret: [c_uchar; 11] array that will store the diversifier index at
* which the returned address was found
* - addr_ret: [c_uchar; 43] array to which the returned address will be
* written
*/
bool librustzcash_zip32_find_sapling_address(
const unsigned char *fvk,
const unsigned char *dk,
const unsigned char *j,
unsigned char *j_ret,
unsigned char *addr_ret
);
/**
* Decrypts a Sapling diversifier using the specified diversifier key
* to obtain the diversifier index `j` at which the diversifier was
* derived.
*
* Arguments:
* - dk: [c_uchar; 32] the byte representation of a Sapling diversifier key
* - addr: [c_uchar; 11] the bytes of the diversifier
* - j_ret: [c_uchar; 11] array that will store the resulting diversifier index
*/
void librustzcash_sapling_diversifier_index(
const unsigned char *dk,
const unsigned char *d,
unsigned char *j_ret
);
/// Fills the provided buffer with random bytes. This is intended to
/// be a cryptographically secure RNG; it uses Rust's `OsRng`, which
/// is implemented in terms of the `getrandom` crate. The first call
/// to this function may block until sufficient randomness is available.
void librustzcash_getrandom(
unsigned char *buf,
size_t buf_len
);
#ifdef __cplusplus
}
#endif
#endif // ZCASH_RUST_INCLUDE_LIBRUSTZCASH_H

View File

@ -1,74 +0,0 @@
// Copyright (c) 2020-2023 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#ifndef ZCASH_RUST_INCLUDE_RUST_HISTORY_H
#define ZCASH_RUST_INCLUDE_RUST_HISTORY_H
#include <stddef.h>
#include <stdint.h>
#define NODE_V1_SERIALIZED_LENGTH 171
#define NODE_SERIALIZED_LENGTH 244
#define ENTRY_SERIALIZED_LENGTH (NODE_SERIALIZED_LENGTH + 9)
typedef struct HistoryNode {
unsigned char bytes[NODE_SERIALIZED_LENGTH];
} HistoryNode;
static_assert(
sizeof(HistoryNode) == NODE_SERIALIZED_LENGTH,
"HistoryNode struct is not the same size as the underlying byte array");
static_assert(alignof(HistoryNode) == 1, "HistoryNode struct alignment is not 1");
typedef struct HistoryEntry {
unsigned char bytes[ENTRY_SERIALIZED_LENGTH];
} HistoryEntry;
static_assert(
sizeof(HistoryEntry) == ENTRY_SERIALIZED_LENGTH,
"HistoryEntry struct is not the same size as the underlying byte array");
static_assert(alignof(HistoryEntry) == 1, "HistoryEntry struct alignment is not 1");
#ifdef __cplusplus
extern "C" {
#endif
/// Appends a leaf to the given history tree.
///
/// `t_len` must be at least 1.
///
/// Aborts if `cbranch` is not a valid consensus branch ID.
uint32_t librustzcash_mmr_append(
uint32_t cbranch,
uint32_t t_len,
const uint32_t* ni_ptr,
const HistoryEntry* n_ptr,
size_t p_len,
const HistoryNode* nn_ptr,
unsigned char* rt_ret,
HistoryNode* buf_ret);
/// Deletes the most recently-appended leaf from the given history tree.
///
/// `t_len` must be at least 1.
///
/// Aborts if `cbranch` is not a valid consensus branch ID.
uint32_t librustzcash_mmr_delete(
uint32_t cbranch,
uint32_t t_len,
const uint32_t* ni_ptr,
const HistoryEntry* n_ptr,
size_t p_len,
size_t e_len,
unsigned char* rt_ret);
/// Returns the hash of the given history tree node.
///
/// Aborts if `cbranch` is not a valid consensus branch ID.
uint32_t librustzcash_mmr_hash_node(
uint32_t cbranch,
const HistoryNode* n_ptr,
unsigned char* h_ret);
#ifdef __cplusplus
}
#endif
#endif // ZCASH_RUST_INCLUDE_RUST_HISTORY_H

View File

@ -1,19 +0,0 @@
// Copyright (c) 2022-2023 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#ifndef ZCASH_RUST_INCLUDE_RUST_INIT_H
#define ZCASH_RUST_INCLUDE_RUST_INIT_H
#ifdef __cplusplus
extern "C" {
#endif
/// Initializes the global Rayon threadpool.
void zcashd_init_rayon_threadpool();
#ifdef __cplusplus
}
#endif
#endif // ZCASH_RUST_INCLUDE_RUST_INIT_H

View File

@ -8,9 +8,9 @@
#include <stdint.h>
#ifdef WIN32
typedef uint16_t codeunit;
typedef char16_t codeunit;
#else
typedef uint8_t codeunit;
typedef char codeunit;
#endif
#endif // ZCASH_RUST_INCLUDE_RUST_TYPES_H

View File

@ -0,0 +1,241 @@
use std::convert::TryFrom;
use zcash_history::{Entry as MMREntry, Tree as MMRTree, Version, V1, V2};
use zcash_primitives::consensus::BranchId;
#[cxx::bridge]
mod ffi {
struct Effect {
// Root commitment after the called method is applied to the tree.
root: [u8; 32],
// Count associated with the result of the called method.
count: usize,
}
#[namespace = "mmr"]
extern "Rust" {
fn append(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len
indices: &[u32],
// Provided tree nodes data, length of p_len
nodes: &[[u8; 253]], // zcash_history::MAX_ENTRY_SIZE
// New node
new_node_bytes: &[u8; 244], // zcash_history::MAX_NODE_DATA_SIZE
// Return buffer for appended leaves, should be pre-allocated of ceiling(log2(t_len)) length
buf_ret: &mut [[u8; 244]], // zcash_history::MAX_NODE_DATA_SIZE
) -> Result<Effect>;
fn remove(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
indices: &[u32],
// Provided tree nodes data, length of p_len+e_len
nodes: &[[u8; 253]], // zcash_history::MAX_ENTRY_SIZE
// Peaks count
p_len: usize,
) -> Result<Effect>;
fn hash_node(cbranch: u32, node_bytes: &[u8; 244]) -> Result<[u8; 32]>;
}
}
/// Switch the tree version on the epoch it is for.
fn dispatch<S, T>(cbranch: u32, input: S, v1: impl FnOnce(S) -> T, v2: impl FnOnce(S) -> T) -> T {
match BranchId::try_from(cbranch).unwrap() {
BranchId::Sprout
| BranchId::Overwinter
| BranchId::Sapling
| BranchId::Heartwood
| BranchId::Canopy => v1(input),
_ => v2(input),
}
}
fn construct_mmr_tree<V: Version>(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
indices: &[u32],
// Provided tree nodes data, length of p_len+e_len
nodes: &[[u8; zcash_history::MAX_ENTRY_SIZE]],
// Peaks count
p_len: usize,
) -> Result<MMRTree<V>, &'static str> {
let mut peaks: Vec<_> = indices
.iter()
.zip(nodes.iter())
.map(
|(index, node)| match MMREntry::from_bytes(cbranch, &node[..]) {
Ok(entry) => Ok((*index, entry)),
Err(_) => Err("Invalid encoding"),
},
)
.collect::<Result<_, _>>()?;
let extra = peaks.split_off(p_len);
Ok(MMRTree::new(t_len, peaks, extra))
}
/// Appends a leaf to the given history tree.
///
/// `t_len` must be at least 1.
///
/// Aborts if `cbranch` is not a valid consensus branch ID.
pub(crate) fn append(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len
indices: &[u32],
// Provided tree nodes data, length of p_len
nodes: &[[u8; zcash_history::MAX_ENTRY_SIZE]],
// New node
new_node_bytes: &[u8; zcash_history::MAX_NODE_DATA_SIZE],
// Return buffer for appended leaves, should be pre-allocated of ceiling(log2(t_len)) length
buf_ret: &mut [[u8; zcash_history::MAX_NODE_DATA_SIZE]],
) -> Result<ffi::Effect, String> {
dispatch(
cbranch,
buf_ret,
|buf_ret| append_inner::<V1>(cbranch, t_len, indices, nodes, new_node_bytes, buf_ret),
|buf_ret| append_inner::<V2>(cbranch, t_len, indices, nodes, new_node_bytes, buf_ret),
)
}
#[allow(clippy::too_many_arguments)]
fn append_inner<V: Version>(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len
indices: &[u32],
// Provided tree nodes data, length of p_len
nodes: &[[u8; zcash_history::MAX_ENTRY_SIZE]],
// New node pointer
new_node_bytes: &[u8; zcash_history::MAX_NODE_DATA_SIZE],
// Return buffer for appended leaves, should be pre-allocated of ceiling(log2(t_len)) length
buf_ret: &mut [[u8; zcash_history::MAX_NODE_DATA_SIZE]],
) -> Result<ffi::Effect, String> {
let mut tree = construct_mmr_tree::<V>(cbranch, t_len, indices, nodes, indices.len())?;
let node = V::from_bytes(cbranch, &new_node_bytes[..])
.map_err(|e| format!("Invalid node encoding: {}", e))?;
let appended = tree
.append_leaf(node)
.map_err(|e| format!("Failed to append leaf: {}", e))?;
let return_count = appended.len();
let root_node = tree
.root_node()
.expect("Just added, should resolve always; qed");
let ret = ffi::Effect {
root: V::hash(root_node.data()),
count: return_count,
};
for (idx, next_buf) in buf_ret[..return_count].iter_mut().enumerate() {
V::write(
tree.resolve_link(appended[idx])
.expect("This was generated by the tree and thus resolvable; qed")
.data(),
&mut &mut next_buf[..],
)
.expect("Write using cursor with enough buffer size cannot fail; qed");
}
Ok(ret)
}
/// Removes the most recently-appended leaf from the given history tree.
///
/// `t_len` must be at least 1.
///
/// Aborts if `cbranch` is not a valid consensus branch ID.
pub(crate) fn remove(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
indices: &[u32],
// Provided tree nodes data, length of p_len+e_len
nodes: &[[u8; zcash_history::MAX_ENTRY_SIZE]],
// Peaks count
p_len: usize,
) -> Result<ffi::Effect, String> {
dispatch(
cbranch,
(),
|()| remove_inner::<V1>(cbranch, t_len, indices, nodes, p_len),
|()| remove_inner::<V2>(cbranch, t_len, indices, nodes, p_len),
)
}
fn remove_inner<V: Version>(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
indices: &[u32],
// Provided tree nodes data, length of p_len+e_len
nodes: &[[u8; zcash_history::MAX_ENTRY_SIZE]],
// Peaks count
p_len: usize,
) -> Result<ffi::Effect, String> {
let mut tree = construct_mmr_tree::<V>(cbranch, t_len, indices, nodes, p_len)?;
let truncate_len = tree
.truncate_leaf()
.map_err(|e| format!("Failed to truncate leaf: {}", e))?;
Ok(ffi::Effect {
root: V::hash(
tree.root_node()
.expect("Just generated without errors, root should be resolving")
.data(),
),
count: truncate_len as usize,
})
}
/// Returns the hash of the given history tree node.
///
/// Aborts if `cbranch` is not a valid consensus branch ID.
fn hash_node(
cbranch: u32,
node_bytes: &[u8; zcash_history::MAX_NODE_DATA_SIZE],
) -> Result<[u8; 32], String> {
dispatch(
cbranch,
(),
|()| hash_node_inner::<V1>(cbranch, node_bytes),
|()| hash_node_inner::<V2>(cbranch, node_bytes),
)
}
fn hash_node_inner<V: Version>(
cbranch: u32,
node_bytes: &[u8; zcash_history::MAX_NODE_DATA_SIZE],
) -> Result<[u8; 32], String> {
let node = V::from_bytes(cbranch, &node_bytes[..])
.map_err(|e| format!("Invalid node encoding: {}", e))?;
Ok(V::hash(&node))
}

View File

@ -1,265 +0,0 @@
use std::{convert::TryFrom, slice};
use libc::{c_uchar, size_t};
use zcash_history::{Entry as MMREntry, Tree as MMRTree, Version, V1, V2};
use zcash_primitives::consensus::BranchId;
/// Switch the tree version on the epoch it is for.
fn dispatch<T>(cbranch: u32, v1: impl FnOnce() -> T, v2: impl FnOnce() -> T) -> T {
match BranchId::try_from(cbranch).unwrap() {
BranchId::Sprout
| BranchId::Overwinter
| BranchId::Sapling
| BranchId::Heartwood
| BranchId::Canopy => v1(),
_ => v2(),
}
}
fn construct_mmr_tree<V: Version>(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
ni_ptr: *const u32,
// Provided tree nodes data, length of p_len+e_len
n_ptr: *const [c_uchar; zcash_history::MAX_ENTRY_SIZE],
// Peaks count
p_len: size_t,
// Extra nodes loaded (for deletion) count
e_len: size_t,
) -> Result<MMRTree<V>, &'static str> {
let (indices, nodes) = unsafe {
(
slice::from_raw_parts(ni_ptr, p_len + e_len),
slice::from_raw_parts(n_ptr, p_len + e_len),
)
};
let mut peaks: Vec<_> = indices
.iter()
.zip(nodes.iter())
.map(
|(index, node)| match MMREntry::from_bytes(cbranch, &node[..]) {
Ok(entry) => Ok((*index, entry)),
Err(_) => Err("Invalid encoding"),
},
)
.collect::<Result<_, _>>()?;
let extra = peaks.split_off(p_len);
Ok(MMRTree::new(t_len, peaks, extra))
}
#[no_mangle]
pub extern "system" fn librustzcash_mmr_append(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len
ni_ptr: *const u32,
// Provided tree nodes data, length of p_len
n_ptr: *const [c_uchar; zcash_history::MAX_ENTRY_SIZE],
// Peaks count
p_len: size_t,
// New node pointer
nn_ptr: *const [u8; zcash_history::MAX_NODE_DATA_SIZE],
// Return of root commitment
rt_ret: *mut [u8; 32],
// Return buffer for appended leaves, should be pre-allocated of ceiling(log2(t_len)) length
buf_ret: *mut [c_uchar; zcash_history::MAX_NODE_DATA_SIZE],
) -> u32 {
dispatch(
cbranch,
|| {
librustzcash_mmr_append_inner::<V1>(
cbranch, t_len, ni_ptr, n_ptr, p_len, nn_ptr, rt_ret, buf_ret,
)
},
|| {
librustzcash_mmr_append_inner::<V2>(
cbranch, t_len, ni_ptr, n_ptr, p_len, nn_ptr, rt_ret, buf_ret,
)
},
)
}
#[allow(clippy::too_many_arguments)]
fn librustzcash_mmr_append_inner<V: Version>(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len
ni_ptr: *const u32,
// Provided tree nodes data, length of p_len
n_ptr: *const [c_uchar; zcash_history::MAX_ENTRY_SIZE],
// Peaks count
p_len: size_t,
// New node pointer
nn_ptr: *const [u8; zcash_history::MAX_NODE_DATA_SIZE],
// Return of root commitment
rt_ret: *mut [u8; 32],
// Return buffer for appended leaves, should be pre-allocated of ceiling(log2(t_len)) length
buf_ret: *mut [c_uchar; zcash_history::MAX_NODE_DATA_SIZE],
) -> u32 {
let new_node_bytes: &[u8; zcash_history::MAX_NODE_DATA_SIZE] = unsafe {
match nn_ptr.as_ref() {
Some(r) => r,
None => {
return 0;
} // Null pointer passed, error
}
};
let mut tree = match construct_mmr_tree::<V>(cbranch, t_len, ni_ptr, n_ptr, p_len, 0) {
Ok(t) => t,
_ => {
return 0;
} // error
};
let node = match V::from_bytes(cbranch, &new_node_bytes[..]) {
Ok(node) => node,
_ => {
return 0;
} // error
};
let appended = match tree.append_leaf(node) {
Ok(appended) => appended,
_ => {
return 0;
}
};
let return_count = appended.len();
let root_node = tree
.root_node()
.expect("Just added, should resolve always; qed");
unsafe {
*rt_ret = V::hash(root_node.data());
for (idx, next_buf) in slice::from_raw_parts_mut(buf_ret, return_count)
.iter_mut()
.enumerate()
{
V::write(
tree.resolve_link(appended[idx])
.expect("This was generated by the tree and thus resolvable; qed")
.data(),
&mut &mut next_buf[..],
)
.expect("Write using cursor with enough buffer size cannot fail; qed");
}
}
return_count as u32
}
#[no_mangle]
pub extern "system" fn librustzcash_mmr_delete(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
ni_ptr: *const u32,
// Provided tree nodes data, length of p_len+e_len
n_ptr: *const [c_uchar; zcash_history::MAX_ENTRY_SIZE],
// Peaks count
p_len: size_t,
// Extra nodes loaded (for deletion) count
e_len: size_t,
// Return of root commitment
rt_ret: *mut [u8; 32],
) -> u32 {
dispatch(
cbranch,
|| librustzcash_mmr_delete_inner::<V1>(cbranch, t_len, ni_ptr, n_ptr, p_len, e_len, rt_ret),
|| librustzcash_mmr_delete_inner::<V2>(cbranch, t_len, ni_ptr, n_ptr, p_len, e_len, rt_ret),
)
}
fn librustzcash_mmr_delete_inner<V: Version>(
// Consensus branch id
cbranch: u32,
// Length of tree in array representation
t_len: u32,
// Indices of provided tree nodes, length of p_len+e_len
ni_ptr: *const u32,
// Provided tree nodes data, length of p_len+e_len
n_ptr: *const [c_uchar; zcash_history::MAX_ENTRY_SIZE],
// Peaks count
p_len: size_t,
// Extra nodes loaded (for deletion) count
e_len: size_t,
// Return of root commitment
rt_ret: *mut [u8; 32],
) -> u32 {
let mut tree = match construct_mmr_tree::<V>(cbranch, t_len, ni_ptr, n_ptr, p_len, e_len) {
Ok(t) => t,
_ => {
return 0;
} // error
};
let truncate_len = match tree.truncate_leaf() {
Ok(v) => v,
_ => {
return 0;
} // Error
};
unsafe {
*rt_ret = V::hash(
tree.root_node()
.expect("Just generated without errors, root should be resolving")
.data(),
);
}
truncate_len
}
#[no_mangle]
pub extern "system" fn librustzcash_mmr_hash_node(
cbranch: u32,
n_ptr: *const [u8; zcash_history::MAX_NODE_DATA_SIZE],
h_ret: *mut [u8; 32],
) -> u32 {
dispatch(
cbranch,
|| librustzcash_mmr_hash_node_inner::<V1>(cbranch, n_ptr, h_ret),
|| librustzcash_mmr_hash_node_inner::<V2>(cbranch, n_ptr, h_ret),
)
}
fn librustzcash_mmr_hash_node_inner<V: Version>(
cbranch: u32,
n_ptr: *const [u8; zcash_history::MAX_NODE_DATA_SIZE],
h_ret: *mut [u8; 32],
) -> u32 {
let node_bytes: &[u8; zcash_history::MAX_NODE_DATA_SIZE] = unsafe {
match n_ptr.as_ref() {
Some(r) => r,
None => return 1,
}
};
let node = match V::from_bytes(cbranch, &node_bytes[..]) {
Ok(n) => n,
_ => return 1, // error
};
unsafe {
*h_ret = V::hash(&node);
}
0
}

View File

@ -0,0 +1,86 @@
use std::ffi::OsString;
use std::path::PathBuf;
use std::sync::Once;
use bellman::groth16::Parameters;
use bls12_381::Bls12;
use tracing::info;
use crate::{
ORCHARD_PK, ORCHARD_VK, SAPLING_OUTPUT_PARAMS, SAPLING_OUTPUT_VK, SAPLING_SPEND_PARAMS,
SAPLING_SPEND_VK, SPROUT_GROTH16_PARAMS_PATH, SPROUT_GROTH16_VK,
};
#[cxx::bridge]
mod ffi {
#[namespace = "init"]
extern "Rust" {
fn rayon_threadpool();
fn zksnark_params(sprout_path: String, load_proving_keys: bool);
}
}
static PROOF_PARAMETERS_LOADED: Once = Once::new();
fn rayon_threadpool() {
rayon::ThreadPoolBuilder::new()
.thread_name(|i| format!("zc-rayon-{}", i))
.build_global()
.expect("Only initialized once");
}
/// Loads the zk-SNARK parameters into memory and saves paths as necessary.
/// Only called once.
///
/// If `load_proving_keys` is `false`, the proving keys will not be loaded, making it
/// impossible to create proofs. This flag is for the Boost test suite, which never
/// creates shielded transactions, but exercises code that requires the verifying keys to
/// be present even if there are no shielded components to verify.
fn zksnark_params(sprout_path: String, load_proving_keys: bool) {
PROOF_PARAMETERS_LOADED.call_once(|| {
let sprout_path = PathBuf::from(OsString::from(sprout_path));
let sprout_vk = {
use bellman::groth16::{prepare_verifying_key, VerifyingKey};
let sprout_vk_bytes = include_bytes!("sprout-groth16.vk");
let vk = VerifyingKey::<Bls12>::read(&sprout_vk_bytes[..])
.expect("should be able to parse Sprout verification key");
prepare_verifying_key(&vk)
};
// 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)
};
// 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();
// Generate Orchard parameters.
info!(target: "main", "Loading Orchard parameters");
let orchard_pk = load_proving_keys.then(orchard::circuit::ProvingKey::build);
let orchard_vk = orchard::circuit::VerifyingKey::build();
// Caller is responsible for calling this function once, so
// these global mutations are safe.
unsafe {
SAPLING_SPEND_PARAMS = load_proving_keys.then_some(sapling_spend_params);
SAPLING_OUTPUT_PARAMS = load_proving_keys.then_some(sapling_output_params);
SPROUT_GROTH16_PARAMS_PATH = Some(sprout_path);
SAPLING_SPEND_VK = Some(sapling_spend_vk);
SAPLING_OUTPUT_VK = Some(sapling_output_vk);
SPROUT_GROTH16_VK = Some(sprout_vk);
ORCHARD_PK = orchard_pk;
ORCHARD_VK = Some(orchard_vk);
}
});
}

View File

@ -1,7 +0,0 @@
#[no_mangle]
pub extern "C" fn zcashd_init_rayon_threadpool() {
rayon::ThreadPoolBuilder::new()
.thread_name(|i| format!("zc-rayon-{}", i))
.build_global()
.expect("Only initialized once");
}

View File

@ -0,0 +1,86 @@
//! FFI between the C++ zcashd codebase and the Rust Zcash crates.
//!
//! This is internal to zcashd and is not an officially-supported API.
// Catch documentation errors caused by code changes.
#![deny(broken_intra_doc_links)]
// Clippy has a default-deny lint to prevent dereferencing raw pointer arguments
// in a non-unsafe function. However, declaring a function as unsafe has the
// side-effect that the entire function body is treated as an unsafe {} block,
// and rustc will not enforce full safety checks on the parts of the function
// that would otherwise be safe.
//
// The functions in this crate are all for FFI usage, so it's obvious to the
// caller (which is only ever zcashd) that the arguments must satisfy the
// necessary assumptions. We therefore ignore this lint to retain the benefit of
// explicitly annotating the parts of each function that must themselves satisfy
// assumptions of underlying code.
//
// 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 bls12_381::Bls12;
use std::path::PathBuf;
use subtle::CtOption;
mod blake2b;
mod ed25519;
mod equihash;
mod metrics_ffi;
mod random;
mod streams_ffi;
mod tracing_ffi;
mod zcashd_orchard;
mod bridge;
mod address_ffi;
mod builder_ffi;
mod bundlecache;
mod history;
mod incremental_merkle_tree;
mod init;
mod merkle_frontier;
mod note_encryption;
mod orchard_bundle;
mod orchard_ffi;
mod orchard_keys_ffi;
mod params;
mod sapling;
mod sprout;
mod streams;
mod transaction_ffi;
mod unified_keys_ffi;
mod wallet;
mod wallet_scanner;
mod zip339_ffi;
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 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 SPROUT_GROTH16_PARAMS_PATH: Option<PathBuf> = None;
static mut ORCHARD_PK: Option<orchard::circuit::ProvingKey> = None;
static mut ORCHARD_VK: Option<orchard::circuit::VerifyingKey> = None;
/// Converts CtOption<t> into Option<T>
fn de_ct<T>(ct: CtOption<T>) -> Option<T> {
if ct.is_some().into() {
Some(ct.unwrap())
} else {
None
}
}
const GROTH_PROOF_SIZE: usize = 48 // π_A
+ 96 // π_B
+ 48; // π_C

View File

@ -0,0 +1,9 @@
use getrandom::getrandom;
#[cxx::bridge]
mod ffi {
#[namespace = "rust"]
extern "Rust" {
fn getrandom(dest: &mut [u8]) -> Result<()>;
}
}

View File

@ -1,861 +0,0 @@
//! FFI between the C++ zcashd codebase and the Rust Zcash crates.
//!
//! This is internal to zcashd and is not an officially-supported API.
// Catch documentation errors caused by code changes.
#![deny(broken_intra_doc_links)]
// Clippy has a default-deny lint to prevent dereferencing raw pointer arguments
// in a non-unsafe function. However, declaring a function as unsafe has the
// side-effect that the entire function body is treated as an unsafe {} block,
// and rustc will not enforce full safety checks on the parts of the function
// that would otherwise be safe.
//
// The functions in this crate are all for FFI usage, so it's obvious to the
// caller (which is only ever zcashd) that the arguments must satisfy the
// necessary assumptions. We therefore ignore this lint to retain the benefit of
// explicitly annotating the parts of each function that must themselves satisfy
// assumptions of underlying code.
//
// 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 blake2s_simd::Params as Blake2sParams;
use bls12_381::Bls12;
use group::{cofactor::CofactorGroup, GroupEncoding};
use incrementalmerkletree::Hashable;
use libc::{c_uchar, size_t};
use rand_core::{OsRng, RngCore};
use std::fs::File;
use std::io::BufReader;
use std::path::{Path, PathBuf};
use std::slice;
use std::sync::Once;
use subtle::CtOption;
use tracing::info;
#[cfg(not(target_os = "windows"))]
use std::ffi::OsStr;
#[cfg(not(target_os = "windows"))]
use std::os::unix::ffi::OsStrExt;
#[cfg(target_os = "windows")]
use std::ffi::OsString;
#[cfg(target_os = "windows")]
use std::os::windows::ffi::OsStringExt;
use zcash_note_encryption::{Domain, EphemeralKeyBytes};
use zcash_primitives::{
consensus::Network,
constants::{CRH_IVK_PERSONALIZATION, PROOF_GENERATION_KEY_GENERATOR, SPENDING_KEY_GENERATOR},
merkle_tree::HashSer,
sapling::{
keys::FullViewingKey,
merkle_hash,
note::{ExtractedNoteCommitment, NoteCommitment},
note_encryption::{PreparedIncomingViewingKey, SaplingDomain},
redjubjub, spend_sig,
value::NoteValue,
Diversifier, Node, Note, NullifierDerivingKey, PaymentAddress, Rseed, SaplingIvk,
},
zip32::{self, sapling_address, sapling_derive_internal_fvk, sapling_find_address},
};
use zcash_proofs::{load_parameters, sprout};
mod blake2b;
mod ed25519;
mod equihash;
mod metrics_ffi;
mod streams_ffi;
mod tracing_ffi;
mod zcashd_orchard;
mod bridge;
mod address_ffi;
mod builder_ffi;
mod bundlecache;
mod history_ffi;
mod incremental_merkle_tree;
mod init_ffi;
mod merkle_frontier;
mod note_encryption;
mod orchard_bundle;
mod orchard_ffi;
mod orchard_keys_ffi;
mod params;
mod sapling;
mod streams;
mod transaction_ffi;
mod unified_keys_ffi;
mod wallet;
mod wallet_scanner;
mod zip339_ffi;
mod test_harness_ffi;
#[cfg(test)]
mod tests;
static PROOF_PARAMETERS_LOADED: Once = Once::new();
static mut SAPLING_SPEND_VK: Option<groth16::VerifyingKey<Bls12>> = None;
static mut SAPLING_OUTPUT_VK: Option<groth16::VerifyingKey<Bls12>> = 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 SPROUT_GROTH16_PARAMS_PATH: Option<PathBuf> = None;
static mut ORCHARD_PK: Option<orchard::circuit::ProvingKey> = None;
static mut ORCHARD_VK: Option<orchard::circuit::VerifyingKey> = None;
/// Converts CtOption<t> into Option<T>
fn de_ct<T>(ct: CtOption<T>) -> Option<T> {
if ct.is_some().into() {
Some(ct.unwrap())
} else {
None
}
}
/// Reads an FsRepr from a [u8; 32]
/// and multiplies it by the given base.
fn fixed_scalar_mult(from: &[u8; 32], p_g: &jubjub::SubgroupPoint) -> jubjub::SubgroupPoint {
// We only call this with `from` being a valid jubjub::Scalar.
let f = jubjub::Scalar::from_bytes(from).unwrap();
p_g * f
}
/// Loads the zk-SNARK parameters into memory and saves paths as necessary.
/// Only called once.
///
/// If `load_proving_keys` is `false`, the proving keys will not be loaded, making it
/// impossible to create proofs. This flag is for the Boost test suite, which never
/// creates shielded transactions, but exercises code that requires the verifying keys to
/// be present even if there are no shielded components to verify.
#[no_mangle]
pub extern "C" fn librustzcash_init_zksnark_params(
#[cfg(not(target_os = "windows"))] spend_path: *const u8,
#[cfg(target_os = "windows")] spend_path: *const u16,
spend_path_len: usize,
#[cfg(not(target_os = "windows"))] output_path: *const u8,
#[cfg(target_os = "windows")] output_path: *const u16,
output_path_len: usize,
#[cfg(not(target_os = "windows"))] sprout_path: *const u8,
#[cfg(target_os = "windows")] sprout_path: *const u16,
sprout_path_len: usize,
load_proving_keys: bool,
) {
PROOF_PARAMETERS_LOADED.call_once(|| {
#[cfg(not(target_os = "windows"))]
let (spend_path, output_path, sprout_path) = {
(
OsStr::from_bytes(unsafe { slice::from_raw_parts(spend_path, spend_path_len) }),
OsStr::from_bytes(unsafe { slice::from_raw_parts(output_path, output_path_len) }),
if sprout_path.is_null() {
None
} else {
Some(OsStr::from_bytes(unsafe {
slice::from_raw_parts(sprout_path, sprout_path_len)
}))
},
)
};
#[cfg(target_os = "windows")]
let (spend_path, output_path, sprout_path) = {
(
OsString::from_wide(unsafe { slice::from_raw_parts(spend_path, spend_path_len) }),
OsString::from_wide(unsafe { slice::from_raw_parts(output_path, output_path_len) }),
if sprout_path.is_null() {
None
} else {
Some(OsString::from_wide(unsafe {
slice::from_raw_parts(sprout_path, sprout_path_len)
}))
},
)
};
let (spend_path, output_path, sprout_path) = (
Path::new(&spend_path),
Path::new(&output_path),
sprout_path.as_ref().map(Path::new),
);
// Load params
let params = load_parameters(spend_path, output_path, sprout_path);
let sapling_spend_params = params.spend_params;
let sapling_output_params = params.output_params;
// 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();
// Generate Orchard parameters.
info!(target: "main", "Loading Orchard parameters");
let orchard_pk = load_proving_keys.then(orchard::circuit::ProvingKey::build);
let orchard_vk = orchard::circuit::VerifyingKey::build();
// Caller is responsible for calling this function once, so
// these global mutations are safe.
unsafe {
SAPLING_SPEND_PARAMS = load_proving_keys.then_some(sapling_spend_params);
SAPLING_OUTPUT_PARAMS = load_proving_keys.then_some(sapling_output_params);
SPROUT_GROTH16_PARAMS_PATH = sprout_path.map(|p| p.to_owned());
SAPLING_SPEND_VK = Some(sapling_spend_vk);
SAPLING_OUTPUT_VK = Some(sapling_output_vk);
SPROUT_GROTH16_VK = params.sprout_vk;
ORCHARD_PK = orchard_pk;
ORCHARD_VK = Some(orchard_vk);
}
});
}
/// Writes the "uncommitted" note value for empty leaves of the Merkle tree.
///
/// `result` must be a valid pointer to 32 bytes which will be written.
#[no_mangle]
pub extern "C" fn librustzcash_tree_uncommitted(result: *mut [c_uchar; 32]) {
// Should be okay, caller is responsible for ensuring the pointer
// is a valid pointer to 32 bytes that can be mutated.
let result = unsafe { &mut *result };
Node::empty_leaf()
.write(&mut result[..])
.expect("Sapling leaves are 32 bytes");
}
/// Computes a merkle tree hash for a given depth. The `depth` parameter should
/// not be larger than 62.
///
/// `a` and `b` each must be of length 32, and must each be scalars of BLS12-381.
///
/// The result of the merkle tree hash is placed in `result`, which must also be
/// of length 32.
#[no_mangle]
pub extern "C" fn librustzcash_merkle_hash(
depth: size_t,
a: *const [c_uchar; 32],
b: *const [c_uchar; 32],
result: *mut [c_uchar; 32],
) {
// Should be okay, because caller is responsible for ensuring
// the pointers are valid pointers to 32 bytes.
let tmp = merkle_hash(depth, unsafe { &*a }, unsafe { &*b });
// Should be okay, caller is responsible for ensuring the pointer
// is a valid pointer to 32 bytes that can be mutated.
let result = unsafe { &mut *result };
*result = tmp;
}
#[no_mangle] // ToScalar
pub extern "C" fn librustzcash_to_scalar(input: *const [c_uchar; 64], result: *mut [c_uchar; 32]) {
// Should be okay, because caller is responsible for ensuring
// the pointer is a valid pointer to 32 bytes, and that is the
// size of the representation
let scalar = jubjub::Scalar::from_bytes_wide(unsafe { &*input });
let result = unsafe { &mut *result };
*result = scalar.to_bytes();
}
#[no_mangle]
pub extern "C" fn librustzcash_ask_to_ak(ask: *const [c_uchar; 32], result: *mut [c_uchar; 32]) {
let ask = unsafe { &*ask };
let ak = fixed_scalar_mult(ask, &SPENDING_KEY_GENERATOR);
let result = unsafe { &mut *result };
*result = ak.to_bytes();
}
#[no_mangle]
pub extern "C" fn librustzcash_nsk_to_nk(nsk: *const [c_uchar; 32], result: *mut [c_uchar; 32]) {
let nsk = unsafe { &*nsk };
let nk = fixed_scalar_mult(nsk, &PROOF_GENERATION_KEY_GENERATOR);
let result = unsafe { &mut *result };
*result = nk.to_bytes();
}
#[no_mangle]
pub extern "C" fn librustzcash_crh_ivk(
ak: *const [c_uchar; 32],
nk: *const [c_uchar; 32],
result: *mut [c_uchar; 32],
) {
let ak = unsafe { &*ak };
let nk = unsafe { &*nk };
let mut h = Blake2sParams::new()
.hash_length(32)
.personal(CRH_IVK_PERSONALIZATION)
.to_state();
h.update(ak);
h.update(nk);
let mut h = h.finalize().as_ref().to_vec();
// Drop the last five bits, so it can be interpreted as a scalar.
h[31] &= 0b0000_0111;
let result = unsafe { &mut *result };
result.copy_from_slice(&h);
}
#[no_mangle]
pub extern "C" fn librustzcash_check_diversifier(diversifier: *const [c_uchar; 11]) -> bool {
let diversifier = Diversifier(unsafe { *diversifier });
diversifier.g_d().is_some()
}
#[no_mangle]
pub extern "C" fn librustzcash_ivk_to_pkd(
ivk: *const [c_uchar; 32],
diversifier: *const [c_uchar; 11],
result: *mut [c_uchar; 32],
) -> bool {
let ivk = de_ct(jubjub::Scalar::from_bytes(unsafe { &*ivk }));
let diversifier = Diversifier(unsafe { *diversifier });
if let (Some(ivk), Some(g_d)) = (ivk, diversifier.g_d()) {
let pk_d = g_d * ivk;
let result = unsafe { &mut *result };
*result = pk_d.to_bytes();
true
} else {
false
}
}
/// Test generation of commitment randomness
#[test]
fn test_gen_r() {
let mut r1 = [0u8; 32];
let mut r2 = [0u8; 32];
// Verify different r values are generated
librustzcash_sapling_generate_r(&mut r1);
librustzcash_sapling_generate_r(&mut r2);
assert_ne!(r1, r2);
// Verify r values are valid in the field
let _ = jubjub::Scalar::from_bytes(&r1).unwrap();
let _ = jubjub::Scalar::from_bytes(&r2).unwrap();
}
/// Generate uniformly random scalar in Jubjub. The result is of length 32.
#[no_mangle]
pub extern "C" fn librustzcash_sapling_generate_r(result: *mut [c_uchar; 32]) {
// create random 64 byte buffer
let mut rng = OsRng;
let mut buffer = [0u8; 64];
rng.fill_bytes(&mut buffer);
// reduce to uniform value
let r = jubjub::Scalar::from_bytes_wide(&buffer);
let result = unsafe { &mut *result };
*result = r.to_bytes();
}
// Private utility function to get Note from C parameters
fn priv_get_note(
diversifier: *const [c_uchar; 11],
pk_d: *const [c_uchar; 32],
value: u64,
rcm: *const [c_uchar; 32],
) -> Result<Note, ()> {
let recipient_bytes = {
let mut tmp = [0; 43];
tmp[..11].copy_from_slice(unsafe { &*diversifier });
tmp[11..].copy_from_slice(unsafe { &*pk_d });
tmp
};
let recipient = PaymentAddress::from_bytes(&recipient_bytes).ok_or(())?;
// Deserialize randomness
// If this is after ZIP 212, the caller has calculated rcm, and we don't need to call
// Note::derive_esk, so we just pretend the note was using this rcm all along.
let rseed = Rseed::BeforeZip212(de_ct(jubjub::Scalar::from_bytes(unsafe { &*rcm })).ok_or(())?);
Ok(Note::from_parts(
recipient,
NoteValue::from_raw(value),
rseed,
))
}
/// Compute a Sapling nullifier.
///
/// The `diversifier` parameter must be 11 bytes in length.
/// The `pk_d`, `r`, `ak` and `nk` parameters must be of length 32.
/// The result is also of length 32 and placed in `result`.
/// Returns false if `diversifier` or `pk_d` is not valid.
#[no_mangle]
pub extern "C" fn librustzcash_sapling_compute_nf(
diversifier: *const [c_uchar; 11],
pk_d: *const [c_uchar; 32],
value: u64,
rcm: *const [c_uchar; 32],
nk: *const [c_uchar; 32],
position: u64,
result: *mut [c_uchar; 32],
) -> bool {
// ZIP 216: Nullifier derivation is not consensus-critical
// (nullifiers are revealed, not calculated by consensus).
// In any case, ZIP 216 is now enabled retroactively.
let note = match priv_get_note(diversifier, pk_d, value, rcm) {
Ok(p) => p,
Err(_) => return false,
};
let nk = match de_ct(jubjub::ExtendedPoint::from_bytes(unsafe { &*nk })) {
Some(p) => p,
None => return false,
};
let nk = match de_ct(nk.into_subgroup()) {
Some(nk) => NullifierDerivingKey(nk),
None => return false,
};
let nf = note.nf(&nk, position);
let result = unsafe { &mut *result };
result.copy_from_slice(&nf.0);
true
}
/// Compute a Sapling commitment.
///
/// The `diversifier` parameter must be 11 bytes in length.
/// The `pk_d` and `r` parameters must be of length 32.
/// The result is also of length 32 and placed in `result`.
/// Returns false if `diversifier` or `pk_d` is not valid.
#[no_mangle]
pub extern "C" fn librustzcash_sapling_compute_cmu(
diversifier: *const [c_uchar; 11],
pk_d: *const [c_uchar; 32],
value: u64,
rcm: *const [c_uchar; 32],
result: *mut [c_uchar; 32],
) -> bool {
let get_cm = || -> Result<NoteCommitment, ()> {
let diversifier = Diversifier(unsafe { *diversifier });
let g_d = diversifier.g_d().ok_or(())?;
let pk_d = de_ct(jubjub::ExtendedPoint::from_bytes(unsafe { &*pk_d })).ok_or(())?;
let pk_d = de_ct(pk_d.into_subgroup()).ok_or(())?;
let rcm = de_ct(jubjub::Scalar::from_bytes(unsafe { &*rcm })).ok_or(())?;
Ok(NoteCommitment::temporary_zcashd_derive(
g_d.to_bytes(),
pk_d.to_bytes(),
NoteValue::from_raw(value),
rcm,
))
};
let cmu = match get_cm() {
Ok(cm) => ExtractedNoteCommitment::from(cm),
Err(()) => return false,
};
let result = unsafe { &mut *result };
*result = cmu.to_bytes();
true
}
/// Computes KDF^Sapling(KA^Agree(sk, P), ephemeral_key).
///
/// `p` and `sk` must point to 32-byte buffers. If `p` does not represent a compressed
/// Jubjub point or `sk` does not represent a canonical Jubjub scalar, this function
/// returns `false`. Otherwise, it writes the result to the 32-byte `result` buffer and
/// returns `true`.
#[no_mangle]
pub extern "C" fn librustzcash_sapling_ka_derive_symmetric_key(
p: *const [c_uchar; 32],
sk: *const [c_uchar; 32],
ephemeral_key: *const [c_uchar; 32],
result: *mut [c_uchar; 32],
) -> bool {
// Deserialize p (representing either epk or pk_d; we can handle them identically).
let epk = match SaplingDomain::<Network>::epk(&EphemeralKeyBytes(unsafe { *p })) {
Some(p) => SaplingDomain::<Network>::prepare_epk(p),
None => return false,
};
// Deserialize sk (either ivk or esk; we can handle them identically).
let ivk = match de_ct(jubjub::Scalar::from_bytes(unsafe { &*sk })) {
Some(p) => PreparedIncomingViewingKey::new(&SaplingIvk(p)),
None => return false,
};
// Compute key agreement
let secret = SaplingDomain::<Network>::ka_agree_dec(&ivk, &epk);
// Produce result
let result = unsafe { &mut *result };
result.clone_from_slice(
SaplingDomain::<Network>::kdf(secret, &EphemeralKeyBytes(unsafe { *ephemeral_key }))
.as_bytes(),
);
true
}
/// Compute g_d = GH(diversifier) and returns false if the diversifier is
/// invalid. Computes \[esk\] g_d and writes the result to the 32-byte `result`
/// buffer. Returns false if `esk` is not a valid scalar.
#[no_mangle]
pub extern "C" fn librustzcash_sapling_ka_derivepublic(
diversifier: *const [c_uchar; 11],
esk: *const [c_uchar; 32],
result: *mut [c_uchar; 32],
) -> bool {
let diversifier = Diversifier(unsafe { *diversifier });
// Compute g_d from the diversifier
let g_d = match diversifier.g_d() {
Some(g) => g,
None => return false,
};
// Deserialize esk
let esk = match de_ct(jubjub::Scalar::from_bytes(unsafe { &*esk })) {
Some(p) => p,
None => return false,
};
let p = g_d * esk;
let result = unsafe { &mut *result };
*result = p.to_bytes();
true
}
const GROTH_PROOF_SIZE: usize = 48 // π_A
+ 96 // π_B
+ 48; // π_C
/// Sprout JoinSplit proof generation.
#[no_mangle]
pub extern "C" fn librustzcash_sprout_prove(
proof_out: *mut [c_uchar; GROTH_PROOF_SIZE],
phi: *const [c_uchar; 32],
rt: *const [c_uchar; 32],
h_sig: *const [c_uchar; 32],
// First input
in_sk1: *const [c_uchar; 32],
in_value1: u64,
in_rho1: *const [c_uchar; 32],
in_r1: *const [c_uchar; 32],
in_auth1: *const [c_uchar; sprout::WITNESS_PATH_SIZE],
// Second input
in_sk2: *const [c_uchar; 32],
in_value2: u64,
in_rho2: *const [c_uchar; 32],
in_r2: *const [c_uchar; 32],
in_auth2: *const [c_uchar; sprout::WITNESS_PATH_SIZE],
// First output
out_pk1: *const [c_uchar; 32],
out_value1: u64,
out_r1: *const [c_uchar; 32],
// Second output
out_pk2: *const [c_uchar; 32],
out_value2: u64,
out_r2: *const [c_uchar; 32],
// Public value
vpub_old: u64,
vpub_new: u64,
) {
// Load parameters from disk
let sprout_fs =
File::open(unsafe { &SPROUT_GROTH16_PARAMS_PATH }.as_ref().expect(
"Parameters not loaded: SPROUT_GROTH16_PARAMS_PATH should have been initialized",
))
.expect("couldn't load Sprout groth16 parameters file");
let mut sprout_fs = BufReader::with_capacity(1024 * 1024, sprout_fs);
let params = Parameters::read(&mut sprout_fs, false)
.expect("couldn't deserialize Sprout JoinSplit parameters file");
drop(sprout_fs);
let proof = sprout::create_proof(
unsafe { *phi },
unsafe { *rt },
unsafe { *h_sig },
unsafe { *in_sk1 },
in_value1,
unsafe { *in_rho1 },
unsafe { *in_r1 },
unsafe { &*in_auth1 },
unsafe { *in_sk2 },
in_value2,
unsafe { *in_rho2 },
unsafe { *in_r2 },
unsafe { &*in_auth2 },
unsafe { *out_pk1 },
out_value1,
unsafe { *out_r1 },
unsafe { *out_pk2 },
out_value2,
unsafe { *out_r2 },
vpub_old,
vpub_new,
&params,
);
proof
.write(&mut (unsafe { &mut *proof_out })[..])
.expect("should be able to serialize a proof");
}
/// Sprout JoinSplit proof verification.
#[no_mangle]
pub extern "C" fn librustzcash_sprout_verify(
proof: *const [c_uchar; GROTH_PROOF_SIZE],
rt: *const [c_uchar; 32],
h_sig: *const [c_uchar; 32],
mac1: *const [c_uchar; 32],
mac2: *const [c_uchar; 32],
nf1: *const [c_uchar; 32],
nf2: *const [c_uchar; 32],
cm1: *const [c_uchar; 32],
cm2: *const [c_uchar; 32],
vpub_old: u64,
vpub_new: u64,
) -> bool {
sprout::verify_proof(
unsafe { &*proof },
unsafe { &*rt },
unsafe { &*h_sig },
unsafe { &*mac1 },
unsafe { &*mac2 },
unsafe { &*nf1 },
unsafe { &*nf2 },
unsafe { &*cm1 },
unsafe { &*cm2 },
vpub_old,
vpub_new,
unsafe { SPROUT_GROTH16_VK.as_ref() }
.expect("Parameters not loaded: SPROUT_GROTH16_VK should have been initialized"),
)
}
/// Computes the signature for each Spend description, given the key `ask`, the
/// re-randomization `ar`, the 32-byte sighash `sighash`, and an output `result`
/// buffer of 64-bytes for the signature.
///
/// This function will fail if the provided `ask` or `ar` are invalid.
#[no_mangle]
pub extern "C" fn librustzcash_sapling_spend_sig(
ask: *const [c_uchar; 32],
ar: *const [c_uchar; 32],
sighash: *const [c_uchar; 32],
result: *mut [c_uchar; 64],
) -> bool {
// The caller provides the re-randomization of `ak`.
let ar = match de_ct(jubjub::Scalar::from_bytes(unsafe { &*ar })) {
Some(p) => p,
None => return false,
};
// The caller provides `ask`, the spend authorizing key.
let ask = match redjubjub::PrivateKey::read(&(unsafe { &*ask })[..]) {
Ok(p) => p,
Err(_) => return false,
};
// Initialize secure RNG
let mut rng = OsRng;
// Do the signing
let sig = spend_sig(ask, ar, unsafe { &*sighash }, &mut rng);
// Write out the signature
sig.write(&mut (unsafe { &mut *result })[..])
.expect("result should be 64 bytes");
true
}
/// Derive the master ExtendedSpendingKey from a seed.
#[no_mangle]
pub extern "C" fn librustzcash_zip32_sapling_xsk_master(
seed: *const c_uchar,
seedlen: size_t,
xsk_master: *mut [c_uchar; 169],
) {
let seed = unsafe { std::slice::from_raw_parts(seed, seedlen) };
let xsk = zip32::ExtendedSpendingKey::master(seed);
xsk.write(&mut (unsafe { &mut *xsk_master })[..])
.expect("should be able to serialize an ExtendedSpendingKey");
}
/// Derive a child ExtendedSpendingKey from a parent.
#[no_mangle]
pub extern "C" fn librustzcash_zip32_sapling_xsk_derive(
xsk_parent: *const [c_uchar; 169],
i: u32,
xsk_i: *mut [c_uchar; 169],
) {
let xsk_parent = zip32::ExtendedSpendingKey::read(&unsafe { *xsk_parent }[..])
.expect("valid ExtendedSpendingKey");
let i = zip32::ChildIndex::from_index(i);
let xsk = xsk_parent.derive_child(i);
xsk.write(&mut (unsafe { &mut *xsk_i })[..])
.expect("should be able to serialize an ExtendedSpendingKey");
}
/// Derive the Sapling internal spending key from the external extended
/// spending key
#[no_mangle]
pub extern "C" fn librustzcash_zip32_sapling_xsk_derive_internal(
xsk_external: *const [c_uchar; 169],
xsk_internal_ret: *mut [c_uchar; 169],
) {
let xsk_external = zip32::ExtendedSpendingKey::read(&unsafe { *xsk_external }[..])
.expect("valid ExtendedSpendingKey");
let xsk_internal = xsk_external.derive_internal();
xsk_internal
.write(&mut (unsafe { &mut *xsk_internal_ret })[..])
.expect("should be able to serialize an ExtendedSpendingKey");
}
/// Derive a child ExtendedFullViewingKey from a parent.
#[no_mangle]
pub extern "C" fn librustzcash_zip32_sapling_xfvk_derive(
xfvk_parent: *const [c_uchar; 169],
i: u32,
xfvk_i: *mut [c_uchar; 169],
) -> bool {
let xfvk_parent = zip32::ExtendedFullViewingKey::read(&unsafe { *xfvk_parent }[..])
.expect("valid ExtendedFullViewingKey");
let i = zip32::ChildIndex::from_index(i);
let xfvk = match xfvk_parent.derive_child(i) {
Ok(xfvk) => xfvk,
Err(_) => return false,
};
xfvk.write(&mut (unsafe { &mut *xfvk_i })[..])
.expect("should be able to serialize an ExtendedFullViewingKey");
true
}
/// Derive the Sapling internal full viewing key from the corresponding external full viewing key
#[no_mangle]
pub extern "C" fn librustzcash_zip32_sapling_derive_internal_fvk(
fvk: *const [c_uchar; 96],
dk: *const [c_uchar; 32],
fvk_ret: *mut [c_uchar; 96],
dk_ret: *mut [c_uchar; 32],
) {
let fvk = FullViewingKey::read(&unsafe { *fvk }[..]).expect("valid Sapling FullViewingKey");
let dk = zip32::sapling::DiversifierKey::from_bytes(unsafe { *dk });
let (fvk_internal, dk_internal) = sapling_derive_internal_fvk(&fvk, &dk);
let fvk_ret = unsafe { &mut *fvk_ret };
let dk_ret = unsafe { &mut *dk_ret };
fvk_ret.copy_from_slice(&fvk_internal.to_bytes());
dk_ret.copy_from_slice(dk_internal.as_bytes());
}
/// Derive a PaymentAddress from an ExtendedFullViewingKey.
#[no_mangle]
pub extern "C" fn librustzcash_zip32_sapling_address(
fvk: *const [c_uchar; 96],
dk: *const [c_uchar; 32],
j: *const [c_uchar; 11],
addr_ret: *mut [c_uchar; 43],
) -> bool {
let fvk = FullViewingKey::read(&unsafe { *fvk }[..]).expect("valid Sapling FullViewingKey");
let dk = zip32::sapling::DiversifierKey::from_bytes(unsafe { *dk });
let j = zip32::DiversifierIndex(unsafe { *j });
match sapling_address(&fvk, &dk, j) {
Some(addr) => {
let addr_ret = unsafe { &mut *addr_ret };
addr_ret.copy_from_slice(&addr.to_bytes());
true
}
None => false,
}
}
/// Derive a PaymentAddress from an ExtendedFullViewingKey.
#[no_mangle]
pub extern "C" fn librustzcash_zip32_find_sapling_address(
fvk: *const [c_uchar; 96],
dk: *const [c_uchar; 32],
j: *const [c_uchar; 11],
j_ret: *mut [c_uchar; 11],
addr_ret: *mut [c_uchar; 43],
) -> bool {
let fvk = FullViewingKey::read(&unsafe { *fvk }[..]).expect("valid Sapling FullViewingKey");
let dk = zip32::sapling::DiversifierKey::from_bytes(unsafe { *dk });
let j = zip32::DiversifierIndex(unsafe { *j });
match sapling_find_address(&fvk, &dk, j) {
Some((j, addr)) => {
let j_ret = unsafe { &mut *j_ret };
let addr_ret = unsafe { &mut *addr_ret };
j_ret.copy_from_slice(&j.0);
addr_ret.copy_from_slice(&addr.to_bytes());
true
}
None => false,
}
}
#[no_mangle]
pub extern "C" fn librustzcash_sapling_diversifier_index(
dk: *const [c_uchar; 32],
d: *const [c_uchar; 11],
j_ret: *mut [c_uchar; 11],
) {
let dk = zip32::sapling::DiversifierKey::from_bytes(unsafe { *dk });
let diversifier = Diversifier(unsafe { *d });
let j_ret = unsafe { &mut *j_ret };
let j = dk.diversifier_index(&diversifier);
j_ret.copy_from_slice(&j.0);
}
#[no_mangle]
pub extern "C" fn librustzcash_getrandom(buf: *mut u8, buf_len: usize) {
let buf = unsafe { slice::from_raw_parts_mut(buf, buf_len) };
OsRng.fill_bytes(buf);
}

View File

@ -45,6 +45,9 @@ use crate::{
streams::CppStream,
};
pub(crate) mod spec;
mod zip32;
const SAPLING_TREE_DEPTH: usize = 32;
pub(crate) struct Spend(sapling::SpendDescription<sapling::Authorized>);

View File

@ -0,0 +1,229 @@
use std::convert::TryInto;
use blake2s_simd::Params as Blake2sParams;
use group::{cofactor::CofactorGroup, GroupEncoding};
use incrementalmerkletree::Hashable;
use rand_core::{OsRng, RngCore};
use zcash_primitives::{
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,
},
};
use crate::de_ct;
#[cxx::bridge]
mod ffi {
#[namespace = "sapling::spec"]
extern "Rust" {
fn tree_uncommitted() -> [u8; 32];
fn merkle_hash(depth: usize, lhs: &[u8; 32], rhs: &[u8; 32]) -> [u8; 32];
fn to_scalar(input: &[u8; 64]) -> [u8; 32];
fn ask_to_ak(ask: &[u8; 32]) -> [u8; 32];
fn nsk_to_nk(nsk: &[u8; 32]) -> [u8; 32];
fn crh_ivk(ak: &[u8; 32], nk: &[u8; 32]) -> [u8; 32];
fn check_diversifier(diversifier: [u8; 11]) -> bool;
fn ivk_to_pkd(ivk: &[u8; 32], diversifier: [u8; 11]) -> Result<[u8; 32]>;
fn generate_r() -> [u8; 32];
fn compute_nf(
diversifier: &[u8; 11],
pk_d: &[u8; 32],
value: u64,
rcm: &[u8; 32],
nk: &[u8; 32],
position: u64,
) -> Result<[u8; 32]>;
fn compute_cmu(
diversifier: [u8; 11],
pk_d: &[u8; 32],
value: u64,
rcm: &[u8; 32],
) -> Result<[u8; 32]>;
}
}
/// Reads an FsRepr from a [u8; 32]
/// and multiplies it by the given base.
fn fixed_scalar_mult(from: &[u8; 32], p_g: &jubjub::SubgroupPoint) -> jubjub::SubgroupPoint {
// We only call this with `from` being a valid jubjub::Scalar.
let f = jubjub::Scalar::from_bytes(from).unwrap();
p_g * f
}
/// Writes the "uncommitted" note value for empty leaves of the Merkle tree.
///
/// `result` must be a valid pointer to 32 bytes which will be written.
fn tree_uncommitted() -> [u8; 32] {
// Should be okay, caller is responsible for ensuring the pointer
// is a valid pointer to 32 bytes that can be mutated.
let mut result = [0; 32];
Node::empty_leaf()
.write(&mut result[..])
.expect("Sapling leaves are 32 bytes");
result
}
fn to_scalar(input: &[u8; 64]) -> [u8; 32] {
jubjub::Scalar::from_bytes_wide(input).to_bytes()
}
pub(crate) fn ask_to_ak(ask: &[u8; 32]) -> [u8; 32] {
let ak = fixed_scalar_mult(ask, &SPENDING_KEY_GENERATOR);
ak.to_bytes()
}
pub(crate) fn nsk_to_nk(nsk: &[u8; 32]) -> [u8; 32] {
let nk = fixed_scalar_mult(nsk, &PROOF_GENERATION_KEY_GENERATOR);
nk.to_bytes()
}
pub(crate) fn crh_ivk(ak: &[u8; 32], nk: &[u8; 32]) -> [u8; 32] {
let mut h = Blake2sParams::new()
.hash_length(32)
.personal(CRH_IVK_PERSONALIZATION)
.to_state();
h.update(ak);
h.update(nk);
let mut h: [u8; 32] = h.finalize().as_ref().try_into().unwrap();
// Drop the last five bits, so it can be interpreted as a scalar.
h[31] &= 0b0000_0111;
h
}
pub(crate) fn check_diversifier(diversifier: [u8; 11]) -> bool {
let diversifier = Diversifier(diversifier);
diversifier.g_d().is_some()
}
pub(crate) fn ivk_to_pkd(ivk: &[u8; 32], diversifier: [u8; 11]) -> Result<[u8; 32], String> {
let ivk = de_ct(jubjub::Scalar::from_bytes(ivk));
let diversifier = Diversifier(diversifier);
if let (Some(ivk), Some(g_d)) = (ivk, diversifier.g_d()) {
let pk_d = g_d * ivk;
Ok(pk_d.to_bytes())
} else {
Err("Diversifier is invalid".to_owned())
}
}
/// Test generation of commitment randomness
#[test]
fn test_gen_r() {
// Verify different r values are generated
let r1 = generate_r();
let r2 = generate_r();
assert_ne!(r1, r2);
// Verify r values are valid in the field
let _ = jubjub::Scalar::from_bytes(&r1).unwrap();
let _ = jubjub::Scalar::from_bytes(&r2).unwrap();
}
/// Generates a uniformly random scalar in Jubjub.
fn generate_r() -> [u8; 32] {
// create random 64 byte buffer
let mut rng = OsRng;
let mut buffer = [0u8; 64];
rng.fill_bytes(&mut buffer);
// reduce to uniform value
let r = jubjub::Scalar::from_bytes_wide(&buffer);
r.to_bytes()
}
// Private utility function to get Note from C parameters
fn priv_get_note(
diversifier: &[u8; 11],
pk_d: &[u8; 32],
value: u64,
rcm: &[u8; 32],
) -> Result<Note, String> {
let recipient_bytes = {
let mut tmp = [0; 43];
tmp[..11].copy_from_slice(&diversifier[..]);
tmp[11..].copy_from_slice(&pk_d[..]);
tmp
};
let recipient = PaymentAddress::from_bytes(&recipient_bytes)
.ok_or_else(|| "Invalid recipient encoding".to_string())?;
// Deserialize randomness
// If this is after ZIP 212, the caller has calculated rcm, and we don't need to call
// Note::derive_esk, so we just pretend the note was using this rcm all along.
let rseed = Rseed::BeforeZip212(
de_ct(jubjub::Scalar::from_bytes(rcm)).ok_or_else(|| "Invalid rcm encoding".to_string())?,
);
Ok(Note::from_parts(
recipient,
NoteValue::from_raw(value),
rseed,
))
}
/// Computes a Sapling nullifier.
pub(crate) fn compute_nf(
diversifier: &[u8; 11],
pk_d: &[u8; 32],
value: u64,
rcm: &[u8; 32],
nk: &[u8; 32],
position: u64,
) -> Result<[u8; 32], String> {
// ZIP 216: Nullifier derivation is not consensus-critical
// (nullifiers are revealed, not calculated by consensus).
// In any case, ZIP 216 is now enabled retroactively.
let note = priv_get_note(diversifier, pk_d, value, rcm)?;
let nk = match de_ct(jubjub::ExtendedPoint::from_bytes(nk)) {
Some(p) => p,
None => return Err("Invalid nk encoding".to_owned()),
};
let nk = match de_ct(nk.into_subgroup()) {
Some(nk) => NullifierDerivingKey(nk),
None => return Err("nk is not in the prime-order subgroup".to_owned()),
};
let nf = note.nf(&nk, position);
Ok(nf.0)
}
/// Computes a Sapling commitment.
pub(crate) fn compute_cmu(
diversifier: [u8; 11],
pk_d: &[u8; 32],
value: u64,
rcm: &[u8; 32],
) -> Result<[u8; 32], String> {
let diversifier = Diversifier(diversifier);
let g_d = diversifier
.g_d()
.ok_or_else(|| "Invalid diversifier".to_string())?;
let pk_d =
de_ct(jubjub::ExtendedPoint::from_bytes(pk_d)).ok_or_else(|| "Invalid pk_d".to_string())?;
let pk_d = de_ct(pk_d.into_subgroup())
.ok_or_else(|| "pk_d is not in the prime-order subgroup".to_string())?;
let rcm = de_ct(jubjub::Scalar::from_bytes(rcm)).ok_or_else(|| "Invalid rcm".to_string())?;
let cmu = ExtractedNoteCommitment::from(NoteCommitment::temporary_zcashd_derive(
g_d.to_bytes(),
pk_d.to_bytes(),
NoteValue::from_raw(value),
rcm,
));
Ok(cmu.to_bytes())
}

View File

@ -0,0 +1,134 @@
use zcash_primitives::{
sapling::{keys::FullViewingKey, Diversifier},
zip32::{self, sapling_address, sapling_derive_internal_fvk, sapling_find_address},
};
#[cxx::bridge]
mod ffi {
struct FfiFullViewingKey {
fvk: [u8; 96],
dk: [u8; 32],
}
struct FfiPaymentAddress {
j: [u8; 11],
addr: [u8; 43],
}
#[namespace = "sapling::zip32"]
extern "Rust" {
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>;
fn diversifier_index(dk: [u8; 32], d: [u8; 11]) -> [u8; 11];
}
}
/// Derives the master ExtendedSpendingKey from a seed.
fn xsk_master(seed: &[u8]) -> [u8; 169] {
let xsk = zip32::ExtendedSpendingKey::master(seed);
let mut xsk_master = [0; 169];
xsk.write(&mut xsk_master[..])
.expect("should be able to serialize an ExtendedSpendingKey");
xsk_master
}
/// 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 = xsk_parent.derive_child(i);
let mut xsk_i = [0; 169];
xsk.write(&mut xsk_i[..])
.expect("should be able to serialize an ExtendedSpendingKey");
xsk_i
}
/// 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_internal = xsk_external.derive_internal();
let mut xsk_internal_ret = [0; 169];
xsk_internal
.write(&mut xsk_internal_ret[..])
.expect("should be able to serialize an ExtendedSpendingKey");
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 (fvk_internal, dk_internal) = sapling_derive_internal_fvk(&fvk, &dk);
ffi::FfiFullViewingKey {
fvk: fvk_internal.to_bytes(),
dk: *dk_internal.as_bytes(),
}
}
/// 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);
sapling_address(&fvk, &dk, j)
.ok_or_else(|| "Diversifier index does not produce a valid diversifier".to_string())
.map(|addr| addr.to_bytes())
}
/// Derive a PaymentAddress from an ExtendedFullViewingKey.
fn find_address(
fvk: &[u8; 96],
dk: [u8; 32],
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);
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,
addr: addr.to_bytes(),
})
}
fn diversifier_index(dk: [u8; 32], d: [u8; 11]) -> [u8; 11] {
let dk = zip32::sapling::DiversifierKey::from_bytes(dk);
let diversifier = Diversifier(d);
let j = dk.diversifier_index(&diversifier);
j.0
}

Binary file not shown.

View File

@ -0,0 +1,178 @@
use std::fs::File;
use std::io::BufReader;
use bellman::groth16::Parameters;
use zcash_proofs::sprout;
use crate::{GROTH_PROOF_SIZE, SPROUT_GROTH16_PARAMS_PATH, SPROUT_GROTH16_VK};
#[allow(clippy::too_many_arguments)]
#[cxx::bridge]
mod ffi {
#[namespace = "sprout"]
extern "Rust" {
fn prove(
phi: [u8; 32],
rt: [u8; 32],
h_sig: [u8; 32],
in_sk1: [u8; 32],
in_value1: u64,
in_rho1: [u8; 32],
in_r1: [u8; 32],
in_auth1: &[u8; 966], // sprout::WITNESS_PATH_SIZE
in_sk2: [u8; 32],
in_value2: u64,
in_rho2: [u8; 32],
in_r2: [u8; 32],
in_auth2: &[u8; 966], // sprout::WITNESS_PATH_SIZE
out_pk1: [u8; 32],
out_value1: u64,
out_r1: [u8; 32],
out_pk2: [u8; 32],
out_value2: u64,
out_r2: [u8; 32],
vpub_old: u64,
vpub_new: u64,
) -> [u8; 192]; // GROTH_PROOF_SIZE
fn verify(
proof: &[u8; 192], // GROTH_PROOF_SIZE
rt: &[u8; 32],
h_sig: &[u8; 32],
mac1: &[u8; 32],
mac2: &[u8; 32],
nf1: &[u8; 32],
nf2: &[u8; 32],
cm1: &[u8; 32],
cm2: &[u8; 32],
vpub_old: u64,
vpub_new: u64,
) -> bool;
}
}
/// Sprout JoinSplit proof generation.
#[allow(clippy::too_many_arguments)]
fn prove(
phi: [u8; 32],
rt: [u8; 32],
h_sig: [u8; 32],
// First input
in_sk1: [u8; 32],
in_value1: u64,
in_rho1: [u8; 32],
in_r1: [u8; 32],
in_auth1: &[u8; sprout::WITNESS_PATH_SIZE],
// Second input
in_sk2: [u8; 32],
in_value2: u64,
in_rho2: [u8; 32],
in_r2: [u8; 32],
in_auth2: &[u8; sprout::WITNESS_PATH_SIZE],
// First output
out_pk1: [u8; 32],
out_value1: u64,
out_r1: [u8; 32],
// Second output
out_pk2: [u8; 32],
out_value2: u64,
out_r2: [u8; 32],
// Public value
vpub_old: u64,
vpub_new: u64,
) -> [u8; GROTH_PROOF_SIZE] {
let params = {
use std::io::Read;
// Load parameters from disk
let sprout_path = unsafe { &SPROUT_GROTH16_PARAMS_PATH }.as_ref().expect(
"Parameters not loaded: SPROUT_GROTH16_PARAMS_PATH should have been initialized",
);
const HOW_TO_FIX: &str = "
Please download this file from https://download.z.cash/downloads/sprout-groth16.params
and put it at ";
let sprout_fs = File::open(sprout_path).unwrap_or_else(|err| {
panic!(
"Couldn't load Sprout Groth16 parameters file: {}{}{}",
err,
HOW_TO_FIX,
&sprout_path.to_string_lossy()
)
});
let mut sprout_fs = BufReader::with_capacity(1024 * 1024, sprout_fs);
let mut sprout_params_file = vec![];
sprout_fs
.read_to_end(&mut sprout_params_file)
.unwrap_or_else(|err| {
panic!(
"Couldn't read Sprout Groth16 parameters file: {}{}{}",
err,
HOW_TO_FIX,
&sprout_path.to_string_lossy()
)
});
let hash = blake2b_simd::Params::new()
.hash_length(64)
.hash(&sprout_params_file);
// b2sum sprout-groth16.params
if hash.as_bytes() != hex::decode("e9b238411bd6c0ec4791e9d04245ec350c9c5744f5610dfcce4365d5ca49dfefd5054e371842b3f88fa1b9d7e8e075249b3ebabd167fa8b0f3161292d36c180a").unwrap().as_slice() {
panic!("Hash of Sprout Groth16 parameters file is incorrect.{}{}", HOW_TO_FIX, &sprout_path.to_string_lossy());
}
Parameters::read(&sprout_params_file[..], false)
.expect("Couldn't deserialize Sprout Groth16 parameters file")
};
let proof = sprout::create_proof(
phi, rt, h_sig, in_sk1, in_value1, in_rho1, in_r1, in_auth1, in_sk2, in_value2, in_rho2,
in_r2, in_auth2, out_pk1, out_value1, out_r1, out_pk2, out_value2, out_r2, vpub_old,
vpub_new, &params,
);
let mut proof_out = [0; GROTH_PROOF_SIZE];
proof
.write(&mut proof_out[..])
.expect("should be able to serialize a proof");
proof_out
}
/// Sprout JoinSplit proof verification.
#[allow(clippy::too_many_arguments)]
fn verify(
proof: &[u8; GROTH_PROOF_SIZE],
rt: &[u8; 32],
h_sig: &[u8; 32],
mac1: &[u8; 32],
mac2: &[u8; 32],
nf1: &[u8; 32],
nf2: &[u8; 32],
cm1: &[u8; 32],
cm2: &[u8; 32],
vpub_old: u64,
vpub_new: u64,
) -> bool {
sprout::verify_proof(
proof,
rt,
h_sig,
mac1,
mac2,
nf1,
nf2,
cm1,
cm2,
vpub_old,
vpub_new,
unsafe { SPROUT_GROTH16_VK.as_ref() }
.expect("Parameters not loaded: SPROUT_GROTH16_VK should have been initialized"),
)
}

View File

@ -1,74 +0,0 @@
use std::convert::TryInto;
use group::Group;
use rand_core::{OsRng, RngCore};
use zcash_primitives::sapling::{Diversifier, NullifierDerivingKey, ViewingKey};
use crate::{
librustzcash_sapling_generate_r, librustzcash_sapling_ka_derive_symmetric_key,
librustzcash_sapling_ka_derivepublic,
};
#[test]
fn test_key_agreement() {
let mut rng = OsRng;
// Create random viewing key
let vk = ViewingKey {
ak: jubjub::SubgroupPoint::random(&mut rng),
nk: NullifierDerivingKey(jubjub::SubgroupPoint::random(&mut rng)),
};
// Create a random address with the viewing key
let addr = loop {
let mut d = [0; 11];
rng.fill_bytes(&mut d);
if let Some(a) = vk.to_payment_address(Diversifier(d)) {
break a;
}
};
// Grab ivk from our viewing key in serialized form
let ivk = vk.ivk();
let ivk_serialized = ivk.to_repr();
// Create random esk
let mut esk = [0u8; 32];
librustzcash_sapling_generate_r(&mut esk);
// The sender will create a shared secret with the recipient
// by multiplying the pk_d from their address with the esk
// we randomly generated
let mut shared_secret_sender = [0u8; 32];
// Serialize pk_d for the call to librustzcash_sapling_ka_derive_symmetric_key
let addr_pk_d = addr.to_bytes()[11..].try_into().unwrap();
// Create epk for the recipient, placed in the transaction. Computed
// using the diversifier and esk.
let mut epk = [0u8; 32];
assert!(librustzcash_sapling_ka_derivepublic(
&addr.diversifier().0,
&esk,
&mut epk
));
assert!(librustzcash_sapling_ka_derive_symmetric_key(
&addr_pk_d,
&esk,
&epk,
&mut shared_secret_sender
));
// Create sharedSecret with ephemeral key
let mut shared_secret_recipient = [0u8; 32];
assert!(librustzcash_sapling_ka_derive_symmetric_key(
&epk,
&ivk_serialized,
&epk,
&mut shared_secret_recipient
));
assert!(!shared_secret_sender.iter().all(|&v| v == 0));
assert_eq!(shared_secret_sender, shared_secret_recipient);
}

View File

@ -4,10 +4,7 @@ use zcash_primitives::{
sapling::{Diversifier, Nullifier, ProofGenerationKey, Rseed},
};
use crate::{
librustzcash_ask_to_ak, librustzcash_check_diversifier, librustzcash_crh_ivk,
librustzcash_ivk_to_pkd, librustzcash_nsk_to_nk,
};
use crate::sapling::spec::{ask_to_ak, check_diversifier, crh_ivk, ivk_to_pkd, nsk_to_nk};
#[test]
fn key_components() {
@ -660,8 +657,7 @@ fn key_components() {
let ak = SPENDING_KEY_GENERATOR * ask;
assert_eq!(&ak.to_bytes(), &tv.ak);
{
let mut ak = [0u8; 32];
librustzcash_ask_to_ak(&tv.ask, &mut ak);
let ak = ask_to_ak(&tv.ask);
assert_eq!(&ak, &tv.ak);
}
@ -669,26 +665,23 @@ fn key_components() {
let fvk = pgk.to_viewing_key();
assert_eq!(&fvk.nk.0.to_bytes(), &tv.nk);
{
let mut nk = [0u8; 32];
librustzcash_nsk_to_nk(&tv.nsk, &mut nk);
let nk = nsk_to_nk(&tv.nsk);
assert_eq!(&nk, &tv.nk);
}
assert_eq!(&fvk.ivk().to_repr(), &tv.ivk);
{
let mut ivk = [0u8; 32];
librustzcash_crh_ivk(&tv.ak, &tv.nk, &mut ivk);
let ivk = crh_ivk(&tv.ak, &tv.nk);
assert_eq!(&ivk, &tv.ivk);
}
let diversifier = Diversifier(tv.default_d);
assert!(librustzcash_check_diversifier(&tv.default_d));
assert!(check_diversifier(tv.default_d));
let addr = fvk.to_payment_address(diversifier).unwrap();
assert_eq!(&addr.to_bytes()[11..], &tv.default_pk_d);
{
let mut default_pk_d = [0u8; 32];
librustzcash_ivk_to_pkd(&tv.ivk, &tv.default_d, &mut default_pk_d);
let default_pk_d = ivk_to_pkd(&tv.ivk, tv.default_d).unwrap();
assert_eq!(&default_pk_d, &tv.default_pk_d);
}

View File

@ -1,6 +1,6 @@
use zcash_history::{Entry, EntryLink, NodeData, V1};
use crate::history_ffi::{librustzcash_mmr_append, librustzcash_mmr_delete};
use crate::history::{append as mmr_append, remove as mmr_remove};
const NODE_DATA_16L: &[u8] = include_bytes!("./res/tree16.dat");
const NODE_DATA_1023L: &[u8] = include_bytes!("./res/tree1023.dat");
@ -148,9 +148,7 @@ fn append() {
let nodes = load_nodes(NODE_DATA_16L);
let (indices, peaks) = preload_tree_append(&nodes);
let mut rt_ret = [0u8; 32];
let mut buf_ret = Vec::<[u8; zcash_history::MAX_NODE_DATA_SIZE]>::with_capacity(32);
let mut buf_ret = vec![[0; zcash_history::MAX_NODE_DATA_SIZE]; 32];
let mut new_node_data = [0u8; zcash_history::MAX_NODE_DATA_SIZE];
let new_node = NodeData {
@ -171,22 +169,21 @@ fn append() {
.write(&mut &mut new_node_data[..])
.expect("Failed to write node data");
let result = librustzcash_mmr_append(
let result = mmr_append(
0,
nodes.len() as u32,
indices.as_ptr(),
peaks.as_ptr(),
peaks.len(),
&indices,
&peaks,
&new_node_data,
&mut rt_ret,
buf_ret.as_mut_ptr(),
);
&mut buf_ret,
)
.unwrap();
unsafe {
buf_ret.set_len(result as usize);
buf_ret.set_len(result.count);
}
assert_eq!(result, 2);
assert_eq!(result.count, 2);
let new_node_1 =
NodeData::from_bytes(0, &buf_ret[0][..]).expect("Failed to reconstruct return node #1");
@ -208,18 +205,8 @@ fn delete() {
let nodes = load_nodes(NODE_DATA_1023L);
let (indices, nodes, peak_count) = preload_tree_delete(&nodes);
let mut rt_ret = [0u8; 32];
let result = librustzcash_mmr_delete(
0,
nodes.len() as u32,
indices.as_ptr(),
nodes.as_ptr(),
peak_count,
indices.len() - peak_count,
&mut rt_ret,
);
let result = mmr_remove(0, nodes.len() as u32, &indices, &nodes, peak_count).unwrap();
// Deleting from full tree of 9 height would result in cascade deleting of 10 nodes
assert_eq!(result, 10);
assert_eq!(result.count, 10);
}

View File

@ -5,7 +5,6 @@ use zcash_primitives::constants::{
VALUE_COMMITMENT_VALUE_GENERATOR,
};
mod key_agreement;
mod key_components;
mod mmr;
mod notes;

View File

@ -1,5 +1,4 @@
use crate::librustzcash_sapling_compute_cmu;
use crate::librustzcash_sapling_compute_nf;
use crate::sapling::spec::{compute_cmu, compute_nf};
#[test]
fn notes() {
@ -647,26 +646,19 @@ fn notes() {
for tv in test_vectors {
// Compute commitment and compare with test vector
let mut result = [0u8; 32];
assert!(librustzcash_sapling_compute_cmu(
&tv.default_d,
&tv.default_pk_d,
tv.note_v,
&tv.note_r,
&mut result
));
let result = compute_cmu(tv.default_d, &tv.default_pk_d, tv.note_v, &tv.note_r).unwrap();
assert_eq!(&result, &tv.note_cm);
// Compute nullifier and compare with test vector
assert!(librustzcash_sapling_compute_nf(
let result = compute_nf(
&tv.default_d,
&tv.default_pk_d,
tv.note_v,
&tv.note_r,
&tv.nk,
tv.note_pos,
&mut result
));
)
.unwrap();
assert_eq!(&result, &tv.note_nf);
}
}

View File

@ -172,6 +172,12 @@ public:
Init(nTypeIn, nVersionIn);
}
template <size_t _N>
CBaseDataStream(const std::array<unsigned char, _N>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
template <typename... Args>
CBaseDataStream(int nTypeIn, int nVersionIn, Args&&... args)
{
@ -428,6 +434,10 @@ public:
CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
template <size_t _N>
CDataStream(const std::array<unsigned char, _N>& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
template <typename... Args>
CDataStream(int nTypeIn, int nVersionIn, Args&&... args) :
CBaseDataStream(nTypeIn, nVersionIn, args...) { }

View File

@ -32,9 +32,8 @@
#include <sodium.h>
#include <tracing.h>
#include "librustzcash.h"
#include <rust/bridge.h>
#include <rust/init.h>
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
@ -81,24 +80,17 @@ BasicTestingSetup::~BasicTestingSetup()
TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
fs::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
fs::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
fs::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";
static_assert(
sizeof(fs::path::value_type) == sizeof(codeunit),
"librustzcash not configured correctly");
auto sapling_spend_str = sapling_spend.native();
auto sapling_output_str = sapling_output.native();
auto sprout_groth16_str = sprout_groth16.native();
librustzcash_init_zksnark_params(
reinterpret_cast<const codeunit*>(sapling_spend_str.c_str()),
sapling_spend_str.length(),
reinterpret_cast<const codeunit*>(sapling_output_str.c_str()),
sapling_output_str.length(),
reinterpret_cast<const codeunit*>(sprout_groth16_str.c_str()),
sprout_groth16_str.length(),
init::zksnark_params(
rust::String(
reinterpret_cast<const codeunit*>(sprout_groth16_str.data()),
sprout_groth16_str.size()),
// Only load the verifying keys, which some tests need.
false
);

View File

@ -186,16 +186,11 @@ HistoryNode CCoinsViewDB::GetHistoryAt(uint32_t epochId, HistoryIndex index) con
if (!db.Read(make_pair(DB_MMR_NODE, make_pair(epochId, index)), tmpMmrNode)) {
throw runtime_error("History data inconsistent (expected node not found) - reindex?");
}
std::copy(std::begin(tmpMmrNode), std::end(tmpMmrNode), mmrNode.bytes);
std::copy(std::begin(tmpMmrNode), std::end(tmpMmrNode), mmrNode.begin());
} else {
// Read mmrNode into tmp std::array
std::array<unsigned char, NODE_SERIALIZED_LENGTH> tmpMmrNode;
if (!db.Read(make_pair(DB_MMR_NODE, make_pair(epochId, index)), tmpMmrNode)) {
if (!db.Read(make_pair(DB_MMR_NODE, make_pair(epochId, index)), mmrNode)) {
throw runtime_error("History data inconsistent (expected node not found) - reindex?");
}
std::copy(std::begin(tmpMmrNode), std::end(tmpMmrNode), mmrNode.bytes);
}
return mmrNode;
@ -274,10 +269,7 @@ void BatchWriteHistory(CDBBatch& batch, CHistoryCacheMap& historyCacheMap) {
// replace/append new/updated entries
for (auto it = historyCache.appends.begin(); it != historyCache.appends.end(); it++) {
// Write mmrNode into tmp std::array
std::array<unsigned char, NODE_SERIALIZED_LENGTH> tmpMmrNode;
std::copy((it->second).bytes, (it->second).bytes + NODE_SERIALIZED_LENGTH, std::begin(tmpMmrNode));
batch.Write(make_pair(DB_MMR_NODE, make_pair(epochId, it->first)), tmpMmrNode);
batch.Write(make_pair(DB_MMR_NODE, make_pair(epochId, it->first)), it->second);
}
// write new length

View File

@ -19,6 +19,8 @@
#include "mempool_limit.h"
#include "zip317.h"
#include <rust/metrics.h>
#include <optional>
using namespace std;
@ -1231,6 +1233,79 @@ size_t CTxMemPool::DynamicMemoryUsage() const {
return total;
}
void CTxMemPool::UpdateMetrics() const {
LOCK(cs);
static const int64_t WEIGHT_RATIO_20_PCT = WEIGHT_RATIO_SCALE / 5;
// Track the sum of unpaid actions within each transaction (as they are subject to the
// unpaid action limit). Transactions that have weight >= 1 have no unpaid actions by
// definition.
size_t unpaidActionsWithWeightLt20pct = 0;
size_t unpaidActionsWithWeightLt40pct = 0;
size_t unpaidActionsWithWeightLt60pct = 0;
size_t unpaidActionsWithWeightLt80pct = 0;
size_t unpaidActionsWithWeightLt1 = 0;
// Track the total number of paid actions across all transactions in the mempool. This
// added to the bucketed unpaid actions above is equal to the total number of
// conventional actions in the mempool.
size_t paidActions = 0;
// Track the sum of transaction sizes (the metric by which they are mainly
// limited) across several buckets.
size_t sizeWithWeightLt1 = 0;
size_t sizeWithWeightEq1 = 0;
size_t sizeWithWeightGt1 = 0;
size_t sizeWithWeightGt2 = 0;
size_t sizeWithWeightGt3 = 0;
for (auto entry : mapTx) {
size_t txSize = entry.GetTxSize();
size_t unpaidActions = entry.GetUnpaidActionCount();
paidActions += std::max(GRACE_ACTIONS, entry.GetTx().GetLogicalActionCount()) - unpaidActions;
int128_t weightRatio = entry.GetWeightRatio();
if (weightRatio > 3 * WEIGHT_RATIO_SCALE) {
sizeWithWeightGt3 += txSize;
} else if (weightRatio > 2 * WEIGHT_RATIO_SCALE) {
sizeWithWeightGt2 += txSize;
} else if (weightRatio > WEIGHT_RATIO_SCALE) {
sizeWithWeightGt1 += txSize;
} else if (weightRatio == WEIGHT_RATIO_SCALE) {
sizeWithWeightEq1 += txSize;
} else {
sizeWithWeightLt1 += txSize;
if (weightRatio < WEIGHT_RATIO_20_PCT) {
unpaidActionsWithWeightLt20pct += unpaidActions;
} else if (weightRatio < 2 * WEIGHT_RATIO_20_PCT) {
unpaidActionsWithWeightLt40pct += unpaidActions;
} else if (weightRatio < 3 * WEIGHT_RATIO_20_PCT) {
unpaidActionsWithWeightLt60pct += unpaidActions;
} else if (weightRatio < 4 * WEIGHT_RATIO_20_PCT) {
unpaidActionsWithWeightLt80pct += unpaidActions;
} else {
unpaidActionsWithWeightLt1 += unpaidActions;
}
}
}
MetricsGauge("zcash.mempool.actions.unpaid", unpaidActionsWithWeightLt20pct, "bk", "< 0.2");
MetricsGauge("zcash.mempool.actions.unpaid", unpaidActionsWithWeightLt40pct, "bk", "< 0.4");
MetricsGauge("zcash.mempool.actions.unpaid", unpaidActionsWithWeightLt60pct, "bk", "< 0.6");
MetricsGauge("zcash.mempool.actions.unpaid", unpaidActionsWithWeightLt80pct, "bk", "< 0.8");
MetricsGauge("zcash.mempool.actions.unpaid", unpaidActionsWithWeightLt1, "bk", "< 1");
MetricsGauge("zcash.mempool.actions.paid", paidActions);
MetricsGauge("zcash.mempool.size.transactions", size());
MetricsGauge("zcash.mempool.size.weighted", sizeWithWeightLt1, "bk", "< 1");
MetricsGauge("zcash.mempool.size.weighted", sizeWithWeightEq1, "bk", "1");
MetricsGauge("zcash.mempool.size.weighted", sizeWithWeightGt1, "bk", "> 1");
MetricsGauge("zcash.mempool.size.weighted", sizeWithWeightGt2, "bk", "> 2");
MetricsGauge("zcash.mempool.size.weighted", sizeWithWeightGt3, "bk", "> 3");
MetricsGauge("zcash.mempool.size.bytes", GetTotalTxSize());
MetricsGauge("zcash.mempool.usage.bytes", DynamicMemoryUsage());
}
void CTxMemPool::SetMempoolCostLimit(int64_t totalCostLimit, int64_t evictionMemorySeconds) {
LOCK(cs);
LogPrint("mempool", "Setting mempool cost limit: (limit=%d, time=%d)\n", totalCostLimit, evictionMemorySeconds);

View File

@ -558,13 +558,13 @@ public:
void SetNotifiedSequence(uint64_t recentlyAddedSequence);
bool IsFullyNotified();
unsigned long size()
unsigned long size() const
{
LOCK(cs);
return mapTx.size();
}
uint64_t GetTotalTxSize()
uint64_t GetTotalTxSize() const
{
LOCK(cs);
return totalTxSize;
@ -582,6 +582,8 @@ public:
size_t DynamicMemoryUsage() const;
void UpdateMetrics() const;
/** Return nCheckFrequency */
uint32_t GetCheckFrequency() const {
return nCheckFrequency;

View File

@ -16,6 +16,7 @@
#include "zip317.h"
#include <librustzcash.h>
#include <rust/bridge.h>
#include <rust/ed25519.h>
namespace
@ -270,6 +271,7 @@ TEST(WalletRPCTests, RPCZsendmanyTaddrToSapling)
auto pa = pwalletMain->GenerateNewLegacySaplingZKey();
const Consensus::Params& consensusParams = Params().GetConsensus();
auto rustNetwork = Params().RustNetwork();
int nextBlockHeight = chainActive.Height() + 1;
@ -329,43 +331,64 @@ TEST(WalletRPCTests, RPCZsendmanyTaddrToSapling)
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 = uint256::FromRawBytes(outputs[0].cv());
auto cmu = uint256::FromRawBytes(outputs[0].cmu());
auto ephemeral_key = uint256::FromRawBytes(outputs[0].ephemeral_key());
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_FALSE(AttemptSaplingOutDecryption(
out_ciphertext,
uint256(),
cv,
cmu,
ephemeral_key));
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_FALSE(AttemptSaplingOutDecryption(
out_ciphertext,
random_uint256(),
cv,
cmu,
ephemeral_key));
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_FALSE(AttemptSaplingOutDecryption(
out_ciphertext,
ovks.first,
cv,
cmu,
ephemeral_key));
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_TRUE(AttemptSaplingOutDecryption(
out_ciphertext,
ovks.second,
cv,
cmu,
ephemeral_key));
EXPECT_NO_THROW(wallet::try_sapling_output_recovery(
*rustNetwork,
nextBlockHeight,
ovks.second.GetRawBytes(),
{
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
}));
// Tear down
chainActive.SetTip(NULL);

View File

@ -138,6 +138,7 @@ TEST(WalletTests, SetupDatadirLocationRunAsFirstTest) {
}
TEST(WalletTests, WalletNetworkSerialization) {
GTEST_SKIP() << "Skipping because it has a race condition and cannot be run in parallel.";
SelectParams(CBaseChainParams::TESTNET);
// Get temporary and unique path for file.

View File

@ -78,7 +78,7 @@ HistoryNode NewNode(
}
assert(buf.size() <= NODE_SERIALIZED_LENGTH);
std::copy(std::begin(buf), std::end(buf), result.bytes);
std::copy(std::begin(buf), std::end(buf), result.begin());
return result;
}
@ -146,14 +146,10 @@ HistoryEntry NodeToEntry(const HistoryNode node, uint32_t left, uint32_t right)
buf << code;
buf << left;
buf << right;
std::array<unsigned char, NODE_SERIALIZED_LENGTH> tmpMmrNode;
std::copy(node.bytes, node.bytes + NODE_SERIALIZED_LENGTH, std::begin(tmpMmrNode));
buf << tmpMmrNode;
buf << node;
assert(buf.size() <= ENTRY_SERIALIZED_LENGTH);
std::copy(std::begin(buf), std::end(buf), result.bytes);
std::copy(std::begin(buf), std::end(buf), result.begin());
return result;
}
@ -164,14 +160,10 @@ HistoryEntry LeafToEntry(const HistoryNode node) {
uint8_t code = 1;
buf << code;
std::array<unsigned char, NODE_SERIALIZED_LENGTH> tmpMmrNode;
std::copy(node.bytes, node.bytes + NODE_SERIALIZED_LENGTH, std::begin(tmpMmrNode));
buf << tmpMmrNode;
buf << node;
assert(buf.size() <= ENTRY_SERIALIZED_LENGTH);
std::copy(std::begin(buf), std::end(buf), result.bytes);
std::copy(std::begin(buf), std::end(buf), result.begin());
return result;
}

View File

@ -9,10 +9,15 @@
#include "streams.h"
#include "uint256.h"
#include <rust/history.h>
#include "librustzcash.h"
#define NODE_V1_SERIALIZED_LENGTH 171
#define NODE_SERIALIZED_LENGTH 244
#define ENTRY_SERIALIZED_LENGTH (NODE_SERIALIZED_LENGTH + 9)
typedef std::array<unsigned char, NODE_SERIALIZED_LENGTH> HistoryNode;
typedef std::array<unsigned char, ENTRY_SERIALIZED_LENGTH> HistoryEntry;
namespace libzcash {
typedef uint64_t HistoryIndex;

View File

@ -4,7 +4,8 @@
#include "zcash/IncrementalMerkleTree.hpp"
#include "crypto/sha256.h"
#include "zcash/util.h"
#include "librustzcash.h"
#include <rust/sapling/spec.h>
namespace libzcash {
@ -14,24 +15,15 @@ PedersenHash PedersenHash::combine(
size_t depth
)
{
PedersenHash res = PedersenHash();
librustzcash_merkle_hash(
return uint256::FromRawBytes(sapling::spec::merkle_hash(
depth,
a.begin(),
b.begin(),
res.begin()
);
return res;
a.GetRawBytes(),
b.GetRawBytes()
));
}
PedersenHash PedersenHash::uncommitted() {
PedersenHash res = PedersenHash();
librustzcash_tree_uncommitted(res.begin());
return res;
return uint256::FromRawBytes(sapling::spec::tree_uncommitted());
}
static const std::array<PedersenHash, 65> pedersen_empty_roots = {

View File

@ -16,6 +16,7 @@
#include "version.h"
#include <rust/blake2b.h>
#include <rust/sprout.h>
namespace libzcash {
@ -156,48 +157,44 @@ namespace libzcash {
return GrothProof();
}
GrothProof proof;
CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION);
ss1 << inputs[0].witness.path();
std::vector<unsigned char> auth1(ss1.begin(), ss1.end());
std::array<unsigned char, 966> auth1;
std::copy(ss1.begin(), ss1.end(), auth1.begin());
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
ss2 << inputs[1].witness.path();
std::vector<unsigned char> auth2(ss2.begin(), ss2.end());
std::array<unsigned char, 966> auth2;
std::copy(ss2.begin(), ss2.end(), auth2.begin());
librustzcash_sprout_prove(
proof.begin(),
return sprout::prove(
phi.inner().GetRawBytes(),
rt.GetRawBytes(),
h_sig.GetRawBytes(),
phi.begin(),
rt.begin(),
h_sig.begin(),
inputs[0].key.begin(),
inputs[0].key.inner().GetRawBytes(),
inputs[0].note.value(),
inputs[0].note.rho.begin(),
inputs[0].note.r.begin(),
auth1.data(),
inputs[0].note.rho.GetRawBytes(),
inputs[0].note.r.GetRawBytes(),
auth1,
inputs[1].key.begin(),
inputs[1].key.inner().GetRawBytes(),
inputs[1].note.value(),
inputs[1].note.rho.begin(),
inputs[1].note.r.begin(),
auth2.data(),
inputs[1].note.rho.GetRawBytes(),
inputs[1].note.r.GetRawBytes(),
auth2,
out_notes[0].a_pk.begin(),
out_notes[0].a_pk.GetRawBytes(),
out_notes[0].value(),
out_notes[0].r.begin(),
out_notes[0].r.GetRawBytes(),
out_notes[1].a_pk.begin(),
out_notes[1].a_pk.GetRawBytes(),
out_notes[1].value(),
out_notes[1].r.begin(),
out_notes[1].r.GetRawBytes(),
vpub_old,
vpub_new
);
return proof;
}
template<size_t NumInputs, size_t NumOutputs>

View File

@ -10,7 +10,8 @@
#include "streams.h"
#include "zcash/util.h"
#include "librustzcash.h"
#include <rust/sapling/spec.h>
#include <boost/thread/exceptions.hpp>
@ -58,7 +59,7 @@ SaplingNote::SaplingNote(
// Per ZIP 212, the rseed field is 32 random bytes.
rseed = random_uint256();
} else {
librustzcash_sapling_generate_r(rseed.begin());
rseed = uint256::FromRawBytes(sapling::spec::generate_r());
}
}
@ -69,14 +70,14 @@ std::optional<uint256> SaplingNote::cmu() const {
// 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.
if (!librustzcash_sapling_compute_cmu(
d.data(),
pk_d.begin(),
try {
result = uint256::FromRawBytes(sapling::spec::compute_cmu(
d,
pk_d.GetRawBytes(),
value(),
rcm_tmp.begin(),
result.begin()
))
{
rcm_tmp.GetRawBytes()
));
} catch (rust::Error) {
return std::nullopt;
}
@ -90,16 +91,16 @@ std::optional<uint256> SaplingNote::nullifier(const SaplingFullViewingKey& vk, c
uint256 result;
uint256 rcm_tmp = rcm();
if (!librustzcash_sapling_compute_nf(
d.data(),
pk_d.begin(),
try {
result = uint256::FromRawBytes(sapling::spec::compute_nf(
d,
pk_d.GetRawBytes(),
value(),
rcm_tmp.begin(),
nk.begin(),
position,
result.begin()
))
{
rcm_tmp.GetRawBytes(),
nk.GetRawBytes(),
position
));
} catch (rust::Error) {
return std::nullopt;
}
@ -205,140 +206,6 @@ std::pair<SaplingNotePlaintext, SaplingPaymentAddress> SaplingNotePlaintext::fro
return std::make_pair(notePt, pa);
}
std::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt(
const SaplingOutCiphertext &ciphertext,
const uint256& ovk,
const uint256& cv,
const uint256& cm,
const uint256& epk
)
{
auto pt = AttemptSaplingOutDecryption(ciphertext, ovk, cv, cm, epk);
if (!pt) {
return std::nullopt;
}
// Deserialize from the plaintext
try {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << pt.value();
SaplingOutgoingPlaintext ret;
ss >> ret;
assert(ss.size() == 0);
return ret;
} catch (const boost::thread_interrupted&) {
throw;
} catch (...) {
return std::nullopt;
}
}
std::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
const Consensus::Params& params,
int height,
const SaplingEncCiphertext &ciphertext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d,
const uint256 &cmu
)
{
// 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.
auto ret = attempt_sapling_enc_decryption_deserialization(ciphertext, epk, esk, pk_d);
if (!ret) {
return std::nullopt;
} else {
SaplingNotePlaintext plaintext = *ret;
// Check leadbyte is allowed at block height
if (!plaintext_version_is_valid(params, height, plaintext.get_leadbyte())) {
LogPrint("receiveunsafe", "Received note plaintext with invalid lead byte %d at height %d",
plaintext.get_leadbyte(), height);
return std::nullopt;
}
return plaintext_checks_without_height(plaintext, epk, esk, pk_d, cmu);
}
}
std::optional<SaplingNotePlaintext> SaplingNotePlaintext::attempt_sapling_enc_decryption_deserialization(
const SaplingEncCiphertext &ciphertext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d
)
{
auto encPlaintext = AttemptSaplingEncDecryption(ciphertext, epk, esk, pk_d);
if (!encPlaintext) {
return std::nullopt;
};
// Deserialize from the plaintext
SaplingNotePlaintext ret;
try {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << encPlaintext.value();
ss >> ret;
assert(ss.size() == 0);
return ret;
} catch (const boost::thread_interrupted&) {
throw;
} catch (...) {
return std::nullopt;
}
}
std::optional<SaplingNotePlaintext> SaplingNotePlaintext::plaintext_checks_without_height(
const SaplingNotePlaintext &plaintext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d,
const uint256 &cmu
)
{
if (plaintext.get_leadbyte() != 0x01) {
assert(plaintext.get_leadbyte() == 0x02);
// ZIP 212: Additionally check that the esk provided to this function
// is consistent with the esk we can derive
if (esk != plaintext.generate_or_derive_esk()) {
return std::nullopt;
}
}
// ZIP 212: The recipient MUST derive esk and check that epk is consistent with it.
// https://zips.z.cash/zip-0212#changes-to-the-process-of-receiving-sapling-notes
uint256 expected_epk;
if (!librustzcash_sapling_ka_derivepublic(plaintext.d.data(), esk.begin(), expected_epk.begin())) {
return std::nullopt;
}
if (expected_epk != epk) {
return std::nullopt;
}
uint256 cmu_expected;
uint256 rcm = plaintext.rcm();
if (!librustzcash_sapling_compute_cmu(
plaintext.d.data(),
pk_d.begin(),
plaintext.value(),
rcm.begin(),
cmu_expected.begin()
))
{
return std::nullopt;
}
if (cmu_expected != cmu) {
return std::nullopt;
}
return plaintext;
}
uint256 SaplingNotePlaintext::rcm() const {
if (leadbyte != 0x01) {
assert(leadbyte == 0x02);
@ -355,15 +222,3 @@ uint256 SaplingNote::rcm() const {
return rseed;
}
}
uint256 SaplingNotePlaintext::generate_or_derive_esk() const {
if (leadbyte != 0x01) {
assert(leadbyte == 0x02);
return PRF_esk(rseed);
} else {
uint256 esk;
// Pick random esk
librustzcash_sapling_generate_r(esk.begin());
return esk;
}
}

View File

@ -47,25 +47,6 @@ public:
uint256 nullifier(const SproutSpendingKey& a_sk) const;
};
inline bool plaintext_version_is_valid(const Consensus::Params& params, int height, unsigned char leadbyte) {
if (params.NetworkUpgradeActive(height, Consensus::UPGRADE_CANOPY)) {
int gracePeriodEndHeight = params.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight + ZIP212_GRACE_PERIOD;
if (height < gracePeriodEndHeight && leadbyte != 0x01 && leadbyte != 0x02) {
// non-{0x01,0x02} received after Canopy activation and before grace period has elapsed
return false;
}
if (height >= gracePeriodEndHeight && leadbyte != 0x02) {
// non-0x02 received past (Canopy activation height + grace period)
return false;
}
return true;
} else {
// return false if non-0x01 received when Canopy is not active
return leadbyte == 0x01;
}
};
enum class Zip212Enabled {
BeforeZip212,
AfterZip212
@ -154,8 +135,6 @@ public:
) const;
};
typedef std::pair<SaplingEncCiphertext, SaplingNoteEncryption> SaplingNotePlaintextEncryptionResult;
class SaplingNotePlaintext : public BaseNotePlaintext {
private:
uint256 rseed;
@ -170,31 +149,6 @@ public:
static std::pair<SaplingNotePlaintext, SaplingPaymentAddress> from_rust(
rust::Box<wallet::DecryptedSaplingOutput> decrypted);
static std::optional<SaplingNotePlaintext> decrypt(
const Consensus::Params& params,
int height,
const SaplingEncCiphertext &ciphertext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d,
const uint256 &cmu
);
static std::optional<SaplingNotePlaintext> plaintext_checks_without_height(
const SaplingNotePlaintext &plaintext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d,
const uint256 &cmu
);
static std::optional<SaplingNotePlaintext> attempt_sapling_enc_decryption_deserialization(
const SaplingEncCiphertext &ciphertext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d
);
std::optional<SaplingNote> note(const SaplingIncomingViewingKey& ivk) const;
virtual ~SaplingNotePlaintext() {}
@ -216,10 +170,6 @@ public:
}
uint256 rcm() const;
uint256 generate_or_derive_esk() const;
unsigned char get_leadbyte() const {
return leadbyte;
}
};
class SaplingOutgoingPlaintext
@ -239,14 +189,6 @@ public:
READWRITE(pk_d); // 8 bytes
READWRITE(esk); // 8 bytes
}
static std::optional<SaplingOutgoingPlaintext> decrypt(
const SaplingOutCiphertext &ciphertext,
const uint256& ovk,
const uint256& cv,
const uint256& cm,
const uint256& epk
);
};

Some files were not shown because too many files have changed in this diff Show More