Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable ZIP 216 for blocks prior to NU5 activation #6000

Merged
merged 6 commits into from Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/Makefile.am
Expand Up @@ -48,15 +48,18 @@ endif
CXXBRIDGE_RS = \
rust/src/blake2b.rs \
rust/src/equihash.rs \
rust/src/orchard_bundle.rs
rust/src/orchard_bundle.rs \
rust/src/sapling.rs
Comment on lines -51 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to keep this alphabetical 😅 I'll fix the ordering in my next PR that adds something here.

CXXBRIDGE_H = \
rust/gen/include/rust/blake2b.h \
rust/gen/include/rust/equihash.h \
rust/gen/include/rust/orchard_bundle.h
rust/gen/include/rust/orchard_bundle.h \
rust/gen/include/rust/sapling.h
CXXBRIDGE_CPP = \
rust/gen/src/blake2b.cpp \
rust/gen/src/equihash.cpp \
rust/gen/src/orchard_bundle.cpp
rust/gen/src/orchard_bundle.cpp \
rust/gen/src/sapling.cpp

# We add a rust/cxx.h include to indicate that we provide this (via the rustcxx depends
# package), so that cxxbridge doesn't include it within the generated headers and code.
Expand Down
39 changes: 18 additions & 21 deletions src/bench/verification.cpp
Expand Up @@ -16,6 +16,7 @@

#include "librustzcash.h"
#include <rust/ed25519.h>
#include <rust/sapling.h>

static void ECDSA(benchmark::State& state)
{
Expand Down Expand Up @@ -106,21 +107,19 @@ static void SaplingSpend(benchmark::State& state)
ss >> spend;
uint256 dataToBeSigned = uint256S("0x2dbf83fe7b88a7cbd80fac0c719483906bb9a0c4fc69071e4780d5f2c76e592c");

auto ctx = librustzcash_sapling_verification_ctx_init(true);
auto ctx = sapling::init_verifier();

while (state.KeepRunning()) {
librustzcash_sapling_check_spend(
ctx,
spend.cv.begin(),
spend.anchor.begin(),
spend.nullifier.begin(),
spend.rk.begin(),
spend.zkproof.begin(),
spend.spendAuthSig.begin(),
dataToBeSigned.begin());
ctx->check_spend(
spend.cv.GetRawBytes(),
spend.anchor.GetRawBytes(),
spend.nullifier.GetRawBytes(),
spend.rk.GetRawBytes(),
spend.zkproof,
spend.spendAuthSig,
dataToBeSigned.GetRawBytes()
);
}

librustzcash_sapling_verification_ctx_free(ctx);
}

static void SaplingOutput(benchmark::State& state)
Expand All @@ -132,18 +131,16 @@ static void SaplingOutput(benchmark::State& state)
PROTOCOL_VERSION);
ss >> output;

auto ctx = librustzcash_sapling_verification_ctx_init(true);
auto ctx = sapling::init_verifier();

while (state.KeepRunning()) {
librustzcash_sapling_check_output(
ctx,
output.cv.begin(),
output.cmu.begin(),
output.ephemeralKey.begin(),
output.zkproof.begin());
ctx->check_output(
output.cv.GetRawBytes(),
output.cmu.GetRawBytes(),
output.ephemeralKey.GetRawBytes(),
output.zkproof
);
}

librustzcash_sapling_verification_ctx_free(ctx);
}

BENCHMARK(ECDSA);
Expand Down
5 changes: 3 additions & 2 deletions src/chainparams.cpp
Expand Up @@ -135,7 +135,8 @@ class CMainParams : public CChainParams {
uint256S("00000000002038016f976744c369dce7419fca30e7171dfac703af5e5f7ad1d4");
consensus.vUpgrades[Consensus::UPGRADE_NU5].nProtocolVersion = 170100;
consensus.vUpgrades[Consensus::UPGRADE_NU5].nActivationHeight = 1687104;

consensus.vUpgrades[Consensus::UPGRADE_NU5].hashActivationBlock =
uint256S("0000000000d723156d9b65ffcf4984da7a19675ed7e2f06d9e5d5188af087bf8");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this hash.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also checked this hash.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check this hash.

consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nProtocolVersion = 0x7FFFFFFF;
consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nActivationHeight =
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
Expand Down Expand Up @@ -239,7 +240,7 @@ class CMainParams : public CChainParams {
}

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("00000000000000000000000000000000000000000000000004a90edff47bbdc6");
consensus.nMinimumChainWork = uint256S("000000000000000000000000000000000000000000000000098e5c63248dcb28");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not check this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirmed that this minimum chain work is greater than the chain work at the NU5 activation block, as required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check this either.


/**
* The message start string should be awesome! ⓩ❤
Expand Down
59 changes: 22 additions & 37 deletions src/main.cpp
Expand Up @@ -47,6 +47,7 @@

#include <rust/ed25519.h>
#include <rust/metrics.h>
#include <rust/sapling.h>

using namespace std;

Expand Down Expand Up @@ -1317,26 +1318,18 @@ bool ContextualCheckShieldedInputs(
if (!tx.vShieldedSpend.empty() ||
!tx.vShieldedOutput.empty())
{
// The nu5Active flag passed in here enables the new consensus rules from ZIP 216
// (https://zips.z.cash/zip-0216#specification) on the following fields:
//
// - spendAuthSig in Sapling Spend descriptions
// - bindingSigSapling
auto ctx = librustzcash_sapling_verification_ctx_init(nu5Active);
auto ctx = sapling::init_verifier();
ebfull marked this conversation as resolved.
Show resolved Hide resolved

for (const SpendDescription &spend : tx.vShieldedSpend) {
if (!librustzcash_sapling_check_spend(
ctx,
spend.cv.begin(),
spend.anchor.begin(),
spend.nullifier.begin(),
spend.rk.begin(),
spend.zkproof.begin(),
spend.spendAuthSig.begin(),
dataToBeSigned.begin()
))
{
librustzcash_sapling_verification_ctx_free(ctx);
if (!ctx->check_spend(
spend.cv.GetRawBytes(),
spend.anchor.GetRawBytes(),
spend.nullifier.GetRawBytes(),
spend.rk.GetRawBytes(),
spend.zkproof,
spend.spendAuthSig,
dataToBeSigned.GetRawBytes()
)) {
return state.DoS(
dosLevelPotentiallyRelaxing,
error("ContextualCheckShieldedInputs(): Sapling spend description invalid"),
Expand All @@ -1345,38 +1338,30 @@ bool ContextualCheckShieldedInputs(
}

for (const OutputDescription &output : tx.vShieldedOutput) {
if (!librustzcash_sapling_check_output(
ctx,
output.cv.begin(),
output.cmu.begin(),
output.ephemeralKey.begin(),
output.zkproof.begin()
))
{
librustzcash_sapling_verification_ctx_free(ctx);
if (!ctx->check_output(
output.cv.GetRawBytes(),
output.cmu.GetRawBytes(),
output.ephemeralKey.GetRawBytes(),
output.zkproof
)) {
// This should be a non-contextual check, but we check it here
// as we need to pass over the outputs anyway in order to then
// call librustzcash_sapling_final_check().
// call ctx->final_check().
return state.DoS(100, error("ContextualCheckShieldedInputs(): Sapling output description invalid"),
REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
}
}

if (!librustzcash_sapling_final_check(
ctx,
if (!ctx->final_check(
tx.GetValueBalanceSapling(),
tx.bindingSig.begin(),
dataToBeSigned.begin()
))
{
librustzcash_sapling_verification_ctx_free(ctx);
tx.bindingSig,
dataToBeSigned.GetRawBytes()
)) {
return state.DoS(
dosLevelPotentiallyRelaxing,
error("ContextualCheckShieldedInputs(): Sapling binding signature invalid"),
REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
}

librustzcash_sapling_verification_ctx_free(ctx);
}

// Queue Orchard bundle to be batch-validated.
Expand Down
42 changes: 0 additions & 42 deletions src/rust/include/librustzcash.h
Expand Up @@ -123,48 +123,6 @@ extern "C" {
/// `librustzcash_sapling_proving_ctx_init`.
void librustzcash_sapling_proving_ctx_free(void *);

/// Creates a Sapling verification context. Please free this
/// when you're done.
void * librustzcash_sapling_verification_ctx_init(
bool zip216Enabled
);

/// Check the validity of a Sapling Spend description,
/// accumulating the value commitment into the context.
bool librustzcash_sapling_check_spend(
void *ctx,
const unsigned char *cv,
const unsigned char *anchor,
const unsigned char *nullifier,
const unsigned char *rk,
const unsigned char *zkproof,
const unsigned char *spendAuthSig,
const unsigned char *sighashValue
);

/// Check the validity of a Sapling Output description,
/// accumulating the value commitment into the context.
bool librustzcash_sapling_check_output(
void *ctx,
const unsigned char *cv,
const unsigned char *cm,
const unsigned char *ephemeralKey,
const unsigned char *zkproof
);

/// Finally checks the validity of the entire Sapling
/// transaction given valueBalance and the binding signature.
bool librustzcash_sapling_final_check(
void *ctx,
int64_t valueBalance,
const unsigned char *bindingSig,
const unsigned char *sighashValue
);

/// Frees a Sapling verification context returned from
/// `librustzcash_sapling_verification_ctx_init`.
void librustzcash_sapling_verification_ctx_free(void *);

/// Compute a Sapling nullifier.
///
/// The `diversifier` parameter must be 11 bytes in length.
Expand Down