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:
parent
36de9309bf
commit
3fdf588c23
|
@ -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",
|
||||
|
|
21
Cargo.toml
21
Cargo.toml
|
@ -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"
|
||||
|
|
65
build.rs
65
build.rs
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }}"
|
||||
|
|
|
@ -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()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
Zcash 5.6.1
|
||||
Zcash 5.7.0
|
||||
<img align="right" width="120" height="80" src="doc/imgs/logo.png">
|
||||
===========
|
||||
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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"]
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "zcash-5.6.1"
|
||||
name: "zcash-5.7.0"
|
||||
enable_cache: true
|
||||
distro: "debian"
|
||||
suites:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "zcash-5.6.1"
|
||||
name: "zcash-5.7.0"
|
||||
enable_cache: true
|
||||
distro: "debian"
|
||||
suites:
|
||||
|
|
|
@ -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": ""
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
]
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 && \
|
||||
|
|
|
@ -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 && \
|
||||
|
|
|
@ -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();
|
||||
+}
|
||||
|
|
@ -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"
|
||||
|
|
|
@ -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 &&
|
|
@ -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)
|
||||
|
|
|
@ -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 -->
|
||||
|
|
|
@ -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/>.
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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/>.
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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"
|
||||
|
|
|
@ -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>"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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")));
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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", "")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,9 @@
|
|||
use getrandom::getrandom;
|
||||
|
||||
#[cxx::bridge]
|
||||
mod ffi {
|
||||
#[namespace = "rust"]
|
||||
extern "Rust" {
|
||||
fn getrandom(dest: &mut [u8]) -> Result<()>;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
¶ms,
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
|
@ -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>);
|
||||
|
|
|
@ -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())
|
||||
}
|
|
@ -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.
|
@ -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, ¶ms,
|
||||
);
|
||||
|
||||
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"),
|
||||
)
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ use zcash_primitives::constants::{
|
|||
VALUE_COMMITMENT_VALUE_GENERATOR,
|
||||
};
|
||||
|
||||
mod key_agreement;
|
||||
mod key_components;
|
||||
mod mmr;
|
||||
mod notes;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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...) { }
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue