* Add a `Transaction::version` getter
Returns the version of the transaction as a `u32`.
* Add `Transaction::is_overwintered` helper method
Returns if the `fOverwintered` flag should be set for the transaction's
version.
* Use new helpers to serialize transaction version
Reduce the repeated code and make it less error-prone with future
changes.
* Add getter methods to `transaction::Request` type
Refactor to move the type deconstruction code into the `Request` type.
The main objective is to make it easier to split the call handler into
methods that receive the request directly.
* Refactor to create `verify_v4_transaction` helper
Split the code specific to V4 transactions into a separate helper
method.
* Create `verify_v5_transaction` helper method
Prepare a separate method to have the validation code.
* Add `UnsupportedByNetworkUpgrade` error variant
An error for when a transaction's version isn't supported by the network
upgrade of the block it's included or for the current network upgrade if
the transaction is for the mempool.
* Verify a V5 transaction's network upgrade
For now, only NU5 supports V5 transactions.
* Test that V5 transaction is rejected on Canopy
Create a fake V5 transaction and try to verify it using a block height
from Canopy's activation. The verifier should reject the transaction
with an error saying that the network upgrade does not support that
transaction version.
* Test if V5 tx. is accepted after NU5 activation
Create a fake V5 transaction and pretend it is placed in a block that
has a height after the NU5 activation. The test should succeed, but
since the NU5 activation height has not been specified yet (neither for
the testnet nor the mainnet), for now this test is marked as
`should_panic`.
* Add `TODO` comment to the code
Add more detail to what's left to do, and link to the appropriate PRs.
* Use `u32` to store transaction version
Use a type consistent with how the version is specified.
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: teor <teor@riseup.net>
* add zcash_history.rs with librustzcash Tree wrapper
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Apply changes from code review
* Update zebra-chain/src/primitives/zcash_history.rs
Co-authored-by: teor <teor@riseup.net>
* Apply changes from code review
* Add Entry struct; return Result where needed; add test
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* zcash_history: improve naming style with `inner`
* zcash_history: check if block has the correct network upgrade when adding to tree
* zcash_history: test improvements
* zcash_history: split Tree::new into new_from_block and new_from_cache
* zcash_history: move tests to their own file
* remove unneeded empty line in Cargo.toml
Co-authored-by: teor <teor@riseup.net>
* Add a `at_least_one!` macro for testing
Similar to the `vec!` macro, but doesn't allow creating an empty list.
* Test if `has_inputs_and_outputs` considers actions
Create a dummy transaction with no inputs and no outputs, and add a
dummy Orchard action to it. The `check::has_inputs_and_outputs`
should succeed, because the consensus rule considers having Orchard
actions as having inputs and/or outputs.
* Refactor to create helper function
Move the code to create a fake Orchard shielded data instance to a
helper function in `zebra_chain::transaction::arbitrary`, so that other
tests can also use it.
* Test coinbase V5 transaction with enable spends
A V5 coinbase transaction that has Orchard shielded data MUST NOT have
the enable spends flag set.
* Test if coinbase without enable spends is valid
A coinbase transaction with Orchard shielded data and without the enable
spends flag set should be valid.
* Add a security comment about the `at_least_one!` macro
This macro must not be used outside tests, because it allows memory denial
of service.
Co-authored-by: teor <teor@riseup.net>
* Add sapling final root test vectors
Also tidy some formatting and imports
* Doc: final sapling roots can be duplicated
* Reverse the byte order of final sapling root test vectors
This makes the test vectors match the byte order in the block header,
rather than the zcashd RPC responses.
* Ignore pre-sapling block header commitments
Previously, Zebra expected this reserved field to be all zeroes,
but some mainnet and testnet blocks had other values.
* Test structural and semantic validation of the block commitment field
History roots are excluded from these tests, because they require
contextual validation.
* Implement `PartialEq<i64>` for `Amount`
Allows to compare an `Amount` instance directly to an integer.
* Add `SerializationError::BadTransactionBalance`
Error variant representing deserialization of a transaction that doesn't
conform to the Sapling consensus rule where the balance MUST be zero if
there aren't any shielded spends and outputs.
* Validate consensus rule when deserializing
Return an error if the deserialized V4 transaction has a non-zero value
balance but doesn't have any Sapling shielded spends nor outputs.
* Add consensus rule link to field documentation
Describe how the consensus rule is validated structurally by
`ShieldedData`.
* Clarify that `value_balance` is zero
Make the description more concise and objective.
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
* Update field documentation
Include information about how the consensus rule is guaranteed during
serialization.
Co-authored-by: teor <teor@riseup.net>
* Remove `check::sapling_balances_match` function
The check is redundant because the respective consensus rule is
validated structurally by `ShieldedData`.
* Test deserialization of invalid V4 transaction
A transaction with no Sapling shielded spends and no outputs but with a
non-zero balance value should fail to deserialize.
* Change least-significant byte of the value balance
State how the byte index is calculated, and change the least
significant-byte to be non-zero.
Co-authored-by: teor <teor@riseup.net>
* Standardise lints across Zebra crates, and add missing docs
The only remaining module with missing docs is `zebra_test::command`
* Todo -> TODO
* Clarify what a transcript ErrorChecker does
Also change `Error` -> `BoxError`
* TransError -> ExpectedTranscriptError
* Output Descriptions -> Output descriptions
* Add a `Transaction::orchard_shielded_data` getter
Allows accessing the Orchard shielded data if it is present in the
transaction, regardless of the transaction version.
* Refactor `orchard_nullifiers` to use new getter
Allows making the method more concise.
* Add `CoinbaseHasEnableSpendsOrchard` error variant
Used when the validation rule is not met.
* Implement `enableSpendsOrchard` in coinbase check
The flag must not be set for the coinbase transaction.
* Refactor `Transaction::orchard_*` getters
Use the fact that `Option<T>` implements `Iterator<T>` to simplify the
code and remove the need for boxing the iterators.
Co-authored-by: teor <teor@riseup.net>
* Make sure the Canopy activation block is a finalized checkpoint block
This enables ZIP-221 chain history from Canopy activation onwards.
* Clarify that the mandatory checkpoint test includes Canopy activation
The test was correct, but the docs and assertion message did not include activation.
* Document that the mandatory checkpoint includes Canopy activation
Co-authored-by: teor <teor@riseup.net>
* Restore SummaryDebug on arbitrary chains
And also add it to some more proptest vectors.
* Reduce most arbitrary vectors from 10 to 4
This makes debugging easier
* Make SummaryDebug generic over collections and exact size iterators
* Document DisplayToDebug
* Fix documentation comment
Was missing a slash to become documentation.
* Add documentation link to type reference
Just to help navigation a bit.
* Implement `Transaction::orchard_actions()` getter
Returns an iterator to iterator over the actions in the Orchard shielded
data (if there is one, otherwise it returns an empty iterator).
* Add V5 support for `has_inputs_and_outputs`
Checks if the transaction has Orchard actions. If it does, it is
considered to have inputs and outputs.
* Refactor transaction test vectors
Make it easier to reuse the fake V5 transaction converter in other test
vectors.
* Move helper function to `zebra-chain` crate
Place it together with some other helper functions, including the one
that actually creates the fake V5 transaction.
* Test transaction with no inputs
`check::has_inputs_and_outputs` should return an error indicating that
the transaction has no inputs.
* Test transaction with no outputs
`check::has_inputs_and_outputs` should return an error indicating that
the transaction has no outputs.
* Note that transaction is fake in `expect` message
Should make the message easier to find, and also gives emphasis to the
fact that the transaction is a fake conversion to V5.
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: teor <teor@riseup.net>
* add nullifier methods to orchard
* store orchard nullifiers
* bump database version
* update `IntoDisk`
* support V5 in `UpdateWith`
* add a test for finalized state
* Use the latest network upgrade in state proptests
Now that we always generate an extra proper VerificationKey for each
Tweak::ChangePubkey case, this /should/ never fail: it also helps split out the
actual verification of the signature from the parsing and validation of the key
itself.
* Set the tip height and previous hash for arbitrary genesis blocks
And cleanup the ledger strategy interface.
* Generate partial chains with correct previous block hashes
* Provide the network value from the PreparedChain strategy
Instead of creating an invalid verification key for a particular signature by tweaking its bytes,
create another verification key and when the ChangePubkey tweak is applied, just swap out the correct
SignatureCase::pk_bytes for SignatureCase::invalid_pk_bytes and check that trying to verify the signature
using that wrong key fails, as expected.
Resolves#2170
* Clarify the finalized state assertion that checks the genesis block
* Make arbitrary block chains pass some genesis checks
Use the genesis previous block hash for
- the first arbitrary block in each chain, and
- individual arbitrary blocks.
This setting can be adjusted by individual proptests as needed.
* Fix scriptCode serialization and sighash test vectors
The scriptCode was being serialized without the compact size prefix, and the test vectors included the prefix in the script, which cancelled each other
* Add ConstantTimeEq's for Orchard FullViewingKey and DiversifierKey and affirmatively test
* Fix orchard::keys doc comments with links to make them automatic links
* Exercise ConstantTimeEq for FullViewingKey with a cheap clone
* Allow some clippy lints to pass for somewhat contrived tests
Co-authored-by: teor <teor@riseup.net>
* Impl subtle::ConstantTimeEq for orchard SpendingKey, use that in Eq/PartialEq
* Use constant time comparisons for secret key data where applicable
This also makes Clippy happier so that we aren't creating types just to compare.
* Fix clippy::cmp_owned for orchard::keys Eq/PartialEq
By impl'ing ConstantTimeEq for those types where leaks of the value
would compromise access or privacy.
* Make clippy::cmp_owned happy for some sapling::keys
* initialize the work on parsing orchard data in V5
* add the rest of orchard serialization
* fix serialization according to spec
* fix arbitrary for Signature<SpendAuth>
* move deserialization of AuthorizedAction to shielded_data module
* use `from_bits_truncate` to generate valid arbitrary flags
* change panic message
* fix serialization/deserialization when nActionsOrchard is empty
* fix Halo2Proof deserialization
* implement ZcashSerialize and ZcashDeserialize for flags
* implement ZcashSerialize and ZcashDeserialize for orchard::tree::Root
* use ZcashSerialize and ZcashDeserialize for binding_sig
* implement from_parts()
* implement Arbitrary for Signature<Binding>
* add trusted preallocate with tests
* fix Arbitrary for orchard Nullifier
* Use zcash_serialize_bytes instead of write_compactsize
Co-authored-by: teor <teor@riseup.net>
* Security: panic if an internally generated time is out of range
If Zebra has a bug where it generates blocks, transactions, or meta
addresses with bad times, panic. This avoids sending bad data onto the
network.
(Previously, Zebra would truncate some of these times, silently
corrupting the underlying data.)
Make it clear that deserialization of these objects is infalliable.
In Orchard, we compare canonical Pallas bytes with a supplied byte array.
Since we need to perform calculations to get it into canonical form, we
need to create a newly owned object.