Add a field `strDebugMessage` which can be passed to DoS or Invalid,
and queried using GetDebugMessage() to add extra troubleshooting
information to the validation state.
(cherry picked from commit bitcoin/bitcoin@fbf44e6f3e)
The Rust parser is stricter than the C++ parser, so we can reach errors
now non-contextually that previously were thrown by the consensus rules.
Various tests have been updated to check for these exceptions, as they
can no longer instantiate these transactions to pass to the consensus
rules. The tests use an unsafe constructor so they can still check the
consensus rules.
This matches the existing transaction builder structs:
- SpendDescriptionInfo
- OutputDescriptionInfo
- TransparentInputInfo
It also removes the dependency of the transaction format on the proving
system.
This also includes the following:
commit b12adf605640abba4cef6ddab1a2797b12cbf454
Author: Kris Nuttycombe <kris.nuttycombe@gmail.com>
Date: Mon Aug 24 16:01:18 2020 -0600
Add assertions to ensure that dependencies between active upgrades are respected.
Co-authored-by: Daira Hopwood <daira@jacaranda.org>
crypto_sign_verify_detached is still used within the consensus rules
until Canopy activation. ed25519-zebra generates signatures that are
valid under both pre- and post-Canopy rules (for our honest usage),
so we can use it to generate transaction signatures now. Then once
Canopy activates, we can remove the remaining usages of crypto_sign.
Refactor ProofVerifier
`ProofVerifier` was previously used to conditionally verify pre-Sapling Sprout
proofs (based on `ProofVerifier::Strict` or `ProofVerifier::Disabled` being
used), but hybrid Sprout proofs bypassed it (so were being verified multiple
times during block verification), and once `libsnark` was removed in
zcash/zcash#4060 `ProofVerifier::check` was doing nothing.
This PR refactors `ProofVerifier`, moving it out of the `libzcash` compilation
unit (so that it can depend on `primitives/transaction.h`), and moving Sprout
verification from `JSDescription::Verify` to `ProofVerifier::VerifySprout`.
Verification-skipping for Sprout proofs is re-introduced.
Additionally, the `ZCJoinSplit` global is removed from the codebase, and
`ZCJoinSplit::prove` is converted into a static function. We load the hybrid
Sprout parameters dynamically at proving time within the Rust code, and no
longer require a C++ global for any proving parameters.
As a side-effect, `libzcashconsensus.la` building with `--with-libs` is fixed,
as `primitives/transaction.cpp` no longer depends on `librustzcash.h`.
ZIP212 implementation
Closes#4557.
(description by @ebfull, taken from #4575)
* The `SaplingNote` structure has a new enum called `zip212Enabled`. This
member is private and reflects whether the note was or is being created
using the derivation method of ZIP 212 (i.e., `BeforeZip212` or `AfterZip212`).
* The `SaplingNotePlaintext` structure has a new unsigned char member
`leadbyte`. This member is private and contains the leading byte of the
plaintext (e.g. `0x01`, `0x02`).
* The serialization of `SaplingNotePlaintext` sets `zip212Enabled` to
`BeforeZip212` iff the serialized note plaintext version is not `0x01`.
* The `r`/`rcm` fields have been removed and replaced with a private field
`rseed`. `SaplingNote` and `SaplingNotePlaintext` now have a helper method
`rcm()` which returns the `rcm` either by deriving it with `rseed`
(if `zip212Enabled` is `AfterZip212`) or returning `rseed` by interpreting
`rseed` as `rcm`.
* All the methods of obtaining a `SaplingNote` account for these changes:
- The `SaplingNote` constructor that is used by e.g. the transaction builder,
and internally samples random `rcm`, now takes a `zip212Enabled` argument
to decide whether to sample `rcm` the "old" way or the "new" way.
- The bare constructor for `SaplingNote` is removed.
- The other constructor which takes the raw contents of the note is only used
in tests or in `Note.cpp`, but now also takes a `zip212Enabled` argument.
- The other way of obtaining a note, by calling `SaplingNotePlaintext::note()`,
has been adjusted.
* The `SaplingNotePlaintext` class now has an `generate_or_derive_esk()` method
that either samples a random `esk` or derives it using the local `rseed`
depending on the value of `leadbyte`.
* The encryption routine is modified to consult `generate_or_derive_esk()` and
provide it to the note encryption object.
* The note encryption objects now take an optional `esk` as input and otherwise
sample a random `esk` internally. This API functionality is preserved to allow
for testing.
* The `SaplingNotePlaintext` decryption routines are modified:
- The out and enc decryption routines now check that `epk` is consistent with
the derived `esk`.
- The out decryption routine for plaintexts also checks that `esk` is
consistent with what is derived by the note.
* The miner and transaction builder consult the activation of Canopy when
creating `SaplingNote`s.
* The consensus rules are modified so that shielded outputs (miner rewards)
must have `v2` note plaintexts after Canopy has activated.
We don't support making pre-Sapling JoinSplit proofs, and we load the
parameters for post-Sapling JoinSplit proofs at proving time, so there
is no need for a global ZCJoinSplit to be passed through the APIs.