* Rename some methods and constants for clarity
Using the following commands:
```
fastmod '\bis_ready_for_attempt\b' is_ready_for_connection_attempt
# One instance required a tweak, because of the ASCII diagram.
fastmod '\bwas_recently_live\b' has_connection_recently_responded
fastmod '\bwas_recently_attempted\b' was_connection_recently_attempted
fastmod '\bwas_recently_failed\b' has_connection_recently_failed
fastmod '\bLIVE_PEER_DURATION\b' MIN_PEER_RECONNECTION_DELAY
```
* Use `Instant::elapsed` for conciseness
Instead of `Instant::now().saturating_duration_since`. They're both
equivalent, and `elapsed` only panics if the `Instant` is somehow
synthetically generated.
* Allow `Duration32` to be created in other crates
Export the `Duration32` from the `zebra_chain::serialization` module.
* Add some new `Duration32` constructors
Create some helper `const` constructors to make it easy to create
constant durations. Add methods to create a `Duration32` from seconds,
minutes and hours.
* Avoid gossiping unreachable peers
When sanitizing the list of peers to gossip, remove those that we
haven't seen in more than three hours.
* Test if unreachable addresses aren't gossiped
Create a property test with random addreses inserted into an
`AddressBook`, and verify that the sanitized list of addresses does not
contain any addresses considered unreachable.
* Test if new alternate address isn't gossipable
Create a new alternate peer, because that type of `MetaAddr` does not
have `last_response` or `untrusted_last_seen` times. Verify that the
peer is not considered gossipable.
* Test if local listener is gossipable
The `MetaAddr` representing the local peer's listening address should
always be considered gossipable.
* Test if gossiped peer recently seen is gossipable
Create a `MetaAddr` representing a gossiped peer that was reported to be
seen recently. Check that the peer is considered gossipable.
* Test peer reportedly last seen in the future
Create a `MetaAddr` representing a peer gossiped and reported to have
been last seen in a time that's in the future. Check that the peer is
considered gossipable, to check that the fallback calculation is working
as intended.
* Test gossiped peer reportedly seen long ago
Create a `MetaAddr` representing a gossiped peer that was reported to
last have been seen a long time ago. Check that the peer is not
considered gossipable.
* Test if just responded peer is gossipable
Create a `MetaAddr` representing a peer that has just responded and
check that it is considered gossipable.
* Test if recently responded peer is gossipable
Create a `MetaAddr` representing a peer that last responded within the
duration a peer is considered reachable. Verify that the peer is
considered gossipable.
* Test peer that responded long ago isn't gossipable
Create a `MetaAddr` representing a peer that last responded outside the
duration a peer is considered reachable. Verify that the peer is not
considered gossipable.
* add legacy chain check and tests
* improve has_network_upgrade check
* add docs to legacy_chain_check()
* change arbitrary module structure
* change the panic message
* move legacy chain acceptance into existing tests
* use a reduced_branch_id_strategy()
* add docs to strategy function
* add argument to check for legacy chain into sync_until()
* Stop trying to verify coinbase inputs using the script verifier
And create tests to catch similar bugs earier.
* Use Testnet in NU5 tests that temporarily should_panic
We've marked these tests as should_panic until there is a NU5 activation
height. But Testnet will have an activation height first, so we should
prefer it in the tests. (Or use both networks.)
* Orchard note commitment tree and hash test vectors?
* Add failing sinsemilla test vector test
* Support incomplete Pallas addition, all the way down
* Fix sinsemilla sub function S(j), add note commitment tree empty root tests
* Clippy nightly lints
* allow(clippy::derive_hash_xor_eq) for orchard::tree
* Update zebra-chain/src/orchard/sinsemilla.rs
Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
* Update multiple crates to ensure bitvec 0.22.3 is being used and avoid package conflicts
* Add documentation to zebra-chain::sapling to indicate that ZIP-216 rules are enforced by jubjub
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
* Always send our local listener with the latest time
Previously, whenever there was an inbound request for peers, we would
clone the address book and update it with the local listener.
This had two impacts:
- the listener could conflict with an existing entry,
rather than unconditionally replacing it, and
- the listener was briefly included in the address book metrics.
As a side-effect, this change also makes sanitization slightly faster,
because it avoids some useless peer filtering and sorting.
* Skip listeners that are not valid for outbound connections
* Filter sanitized addresses Zebra based on address state
This fix correctly prevents Zebra gossiping client addresses to peers,
but still keeps the client in the address book to avoid reconnections.
* Add a full set of DateTime32 and Duration32 calculation methods
* Refactor sanitize to use the new DateTime32/Duration32 methods
* Security: Use canonical SocketAddrs to avoid duplicate connections
If we allow multiple variants for each peer address, we can make multiple
connections to that peer.
Also make sure sanitized MetaAddrs are valid for outbound connections.
* Test that address books contain the local listener address
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* move network_upgrade check into zebra-chain
* fix the errors
* rename function
* typo fix
* rename the check function
* make changes from last code review
* Security: Limit reconnection rate to individual peers
Reconnection Rate
Limit the reconnection rate to each individual peer by applying the
liveness cutoff to the attempt, responded, and failure time fields.
If any field is recent, the peer is skipped.
The new liveness cutoff skips any peers that have recently been attempted
or failed. (Previously, the liveness check was only applied if the peer
was in the `Responded` state, which could lead to repeated retries of
`Failed` peers, particularly in small address books.)
Reconnection Order
Zebra prefers more useful peer states, then the earliest attempted,
failed, and responded times, then the most recent gossiped last seen
times.
Before this change, Zebra took the most recent time in all the peer time
fields, and used that time for liveness and ordering. This led to
confusion between trusted and untrusted data, and success and failure
times.
Unlike the previous order, the new order:
- tries all peers in each state, before re-trying any peer in that state,
and
- only checks the the gossiped untrusted last seen time
if all other times are equal.
* Preserve the later time if changes arrive out of order
* Update CandidateSet::next documentation
* Update CandidateSet state diagram
* Fix variant names in comments
* Explain why timestamps can be left out of MetaAddrChanges
* Add a simple test for the individual peer retry limit
* Only generate valid Arbitrary PeerServices values
* Add an individual peer retry limit AddressBook and CandidateSet test
* Stop deleting recently live addresses from the address book
If we delete recently live addresses from the address book, we can get a
new entry for them, and reconnect too rapidly.
* Rename functions to match similar tokio API
* Fix docs for service sorting
* Clarify a comment
* Cleanup a variable and comments
* Remove blank lines in the CandidateSet state diagram
* Add a multi-peer proptest that checks outbound attempt fairness
* Fix a comment typo
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* Simplify time maths in MetaAddr
* Create a Duration32 type to simplify calculations and comparisons
* Rename variables for clarity
* Split a string constant into multiple lines
* Make constants match rustdoc order
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* stop panicking on invalid orchard nullifiers
* add context to error
* use `from_bytes_wide` for nullifiers in arbitrary
* orchard::Nullifier vec to array conversion is a bit clearer and simpler
Co-authored-by: teor <teor@riseup.net>
* 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.
* add consensus_branch_id field to transaction v5
* clippy
* rustfmt
* replace consensus_branch_id with network_upgrade
* remove unintended test files
* change method name
* some clanups
* add network_upgrade as a constant in tests
* use std in created function
* add comment to manual arbitrary impl
* create custom strategy to deal with NetworkUpgrade
* Add a missing TODO comment
Co-authored-by: teor <teor@riseup.net>
* validate sapling v5 tx
* Make itertools dependency optional
We only need itertools when the `proptest-impl` feature is enabled.
* Check if V4 and V5 coinbase transactions contain PrevOut transparent inputs
This is a bugfix on V4 transaction validation. The PrevOut consensus
rule was not explicitly stated in the Zcash spec until April 2021.
(But it was implied by Bitcoin, and partially implemented by Zebra.)
Also do the shielded sapling input check for V5 transactions.
* Add spec and orchard TODOs to has_inputs_and_outputs
Also make the variable names match the spec.
* Sort transaction functions to match v5 data order
* Simplify transaction input and output checks
Move counts or iterators into `Transaction` methods, so we can remove
duplicate code, and make the consensus rule logic clearer.
* Update sapling_balances_match for Transaction v5
- Quote from the spec
- Explain why the function is redunant for v5
- Rename the function so it's clear that it is sapling-specific
Co-authored-by: teor <teor@riseup.net>
* Disable clippy warnings about comparing a newly created struct
In Sapling, we compare canonical JubJub 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.
* Clippy: use assert rather than assert_eq on a bool
* Use the git version + new commit count + hash for the app version
This helps diagnose bugs in versions of Zebra built from git branches,
rather than git version tags.
* Fill in assert
* Also log semver string
* Fix syntax
* Handle vergen using the cargo package version or raw git tag
* s/Semver/SemVer/
Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
* Redesign Sapling data model for V5 shared anchor and spends
The shared anchor is only present if there are any spends.
As part of this change, delete the manual PartialEq impl and its tests,
because we can derive PartialEq now.
* Stop creating a temporary Vec for the spend and output iterators
* Rename TransferData variants
Interactive rename using the following commands:
```sh
fastmod Spends SpendsAndMaybeOutputs
fastmod NoSpends JustOutputs
```
* Refactor out common sprout nullifier code
* Implement the AtLeastOne constrained vector type
This vector wrapper ensures that it always contains at least one element.
* Simplify Sapling TransferData using AtLeastOne
Also update the RFC to use AtLeastOne for Orchard.
* build(deps): bump vergen from 3.2.0 to 5.1.1
* fix hardcoded version for Tracing struct
* add additional metadata
* remove extra allocations for metadata
* Remove zebrad code version from release checklist
The zebrad code automatically uses the crate version now.
* Sort panic metadata into rough categories
Co-authored-by: teor <teor@riseup.net>
* serialize/deserialize spaling shielded data in v5 transaction
* fix serialize/deserialize fields order according to spec
* remove extra clone calls
* more serialize fixes
* clippy: fix empty array
* tidy comments
* Add v4 and v5 transaction tests
Also make sure that serialized bytes match if structs match.
* Test fake v5 blocks made out of pre-NU5 block test vectors
* Add outputs-only tests for v5 shared anchor serialization
* Refactor sapling::ShieldedData V5 serialization into its own impl
* Fix spec name typos
* Simplify sapling shielded data parsing
* Delete redundant V5 transaction wrappers in tests
And split out sapling ShieldedData serialization.
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
* Speedup proptests for Chain struct in zebra-state
* Add teor2345 requested changes
* Fix type for DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES
* More costs for PROPTEST_CASES
* Add functions for serializing and deserializing split arrays
In Transaction::V5, Zcash splits some types into multiple arrays, with a
single prefix count before the first array.
Add utility functions for serializing and deserializing the subsequent
arrays, with a paramater for the original array's length.
* Use zcash_deserialize_bytes_external_count in zebra-network
* Move some preallocate proptests to their own file
And fix the test module structure so it is consistent with the rest of
zebra-chain.
* Add a convenience alias zcash_serialize_external_count
* Explain why u64::MAX items will never be reached
* add sapling shielded data to transaction V5
* implement nullifiers
* test v5 in shielded_data_roundtrip
* Explicitly design serialization for Transaction V5
Implement serialization for V4 and V5 spends and outputs, to make sure
that the design works.
* Test serialization for v5 spends and outputs
Also add a few missing v4 tests.
* Delete a disabled proptest
* Make v5 transactions a top-level heading
And add a missing serialized type.
* Fix a comment typo
* v5 transaction RFC: split array serialization
Based on #2017
* RFC: explicitly describe serialized field order
And link to the spec
* RFC: add the shared anchor serialization rule test
Co-authored-by: teor <teor@riseup.net>
* Move the preallocate tests into their own files
And move the MetaAddr proptest into its own file.
Also do some minor formatting and cleanups.
Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
* Rename RootHash to Commitment based on ZIP-244
Interactive replace using:
```sh
fastmod RootHash Commitment
fastmod root_hash commitment
fastmod root_bytes commitment_bytes
git mv zebra-chain/src/block/root_hash.rs zebra-chain/src/block/commitment.rs
```
All replacements were accepted.
* rustfmt
* Comment and format cleanups after interactive replace
* Distinguish Sapling tree roots from other tree roots
* Add the NU5 BlockCommitmentsHash variant to block::Commitment
This change parses the hash, but does not perform validation.
* Validate reserved values in Block::commitment
- change Block::commitment to return a Result rather than an Option
- enforce the all-zeroes reserved value consensus rules
- change `PreSaplingReserved([u8; 32])` to `PreSaplingReserved`
- change `ChainHistoryActivationReserved([u8; 32])` to `ChainHistoryActivationReserved`
- update the function comments to describe when each variant is verified
* Fix comment whitespace
* Implement SafePreallocate. Resolves#1880
* Add proptests for SafePreallocate
* Apply suggestions from code review
Comments which did not include replacement code will be addressed in a follow-up commit.
Co-authored-by: teor <teor@riseup.net>
* Rename [Safe-> Trusted]Allocate. Add doc and tests
Add tests to show that the largest allowed vec under TrustedPreallocate
is small enough to fit in a Zcash block/message (depending on type).
Add doc comments to all TrustedPreallocate test cases.
Tighten bounds on max_trusted_alloc for some types.
Note - this commit does NOT include TrustedPreallocate
impls for JoinSplitData, String, and Script.
These impls will be added in a follow up commit
* Implement SafePreallocate. Resolves#1880
* Add proptests for SafePreallocate
* Apply suggestions from code review
Comments which did not include replacement code will be addressed in a follow-up commit.
Co-authored-by: teor <teor@riseup.net>
* Rename [Safe-> Trusted]Allocate. Add doc and tests
Add tests to show that the largest allowed vec under TrustedPreallocate
is small enough to fit in a Zcash block/message (depending on type).
Add doc comments to all TrustedPreallocate test cases.
Tighten bounds on max_trusted_alloc for some types.
Note - this commit does NOT include TrustedPreallocate
impls for JoinSplitData, String, and Script.
These impls will be added in a follow up commit
* Impl TrustedPreallocate for Joinsplit
* Impl ZcashDeserialize for Vec<u8>
* Arbitrary, TrustedPreallocate, Serialize, and tests for Spend<SharedAnchor>
Co-authored-by: teor <teor@riseup.net>
* start refactoring transaction v4 for transaction v5
- move ShieldedData to sapling
- add AnchorVariant
- rename shielded_data to sapling_shielded data in V4
- move value_balance into ShieldedData
- update prop tests for new structure
* add AnchorVariant to Spend
- make anchor types available from sapling crate
- update serialize
* change shielded_balances_match() arguments
* change variable name anchor to shared_anchor in ShieldedData
* fix empty value balance serialization
* use AnchorV in shielded spends
* Rename anchor to per_spend_anchor
* Use nullifiers function directly in non-finalized state
* Use self.value_balance instead of passing it as an argument
* Add missing fields to ShieldedData PartialEq
* Derive Copy for tag types
* Add doc comments for ShieldedData refactor
* Implement a per-spend anchor compatibility iterator
Co-authored-by: teor <teor@riseup.net>
Zebra already uses `Read::take` to enforce message, body, and block
maximum sizes.
So using `Read::take` on untrusted sizes can result in short reads,
without a corresponding `UnexpectedEof` error. (The old code was
correct, but copying it elsewhere would have been risky.)
Zebra believes the untrusted `JoinSplit` list size field when
deserializing `JoinSplit`s, and preallocates a `Vec` based on that size.
This is trivial a memory exhaustion attack.
Instead, use the current auto-growing implementation, which is limited
by the size of the message data.
* add transaction V5 stub
* add v5_strategy
* deduplicate version group ids
* Update comment for V5 transactions
* Add V5 transactions to non_finalized_state
Currently these are all `unimplemented!(...)`
* Fix struct matches
* Apply trivial panic message changes
* add zcash_deserialize for V5
* make all tx versions explicit in sprout and sapling nullifier functions
* match exhaustively in sprout and sapling nullifier functions
* fix matches in zebra-consensus
* fix NU5 strategy
* We're still deciding if v5 transactions support Sprout
Co-authored-by: teor <teor@riseup.net>
* Add NU5 variant to NetworkUpgrade
* Add consensus branch ID for NU5
* Add network protocol versions for NU5
* Add NU5 to the protocol::version_consistent test
* Make unimplemented panic messages more specific
* Block target spacing doesn't change in NU5
* add comments for future updates for NU5
Co-authored-by: teor <teor@riseup.net>
The clippy unknown lints attribute was deprecated in
nightly in rust-lang/rust#80524. The old lint name now produces a
warning.
Since we're using `allow(unknown_lints)` to suppress warnings, we need to
add the canonical name, so we can continue to build without warnings on
nightly.
But we also need to keep the old name, so we can continue to build
without warnings on stable.
And therefore, we also need to disable the "removed lints" warning,
otherwise we'll get warnings about the old name on nightly.
We'll need to keep this transitional clippy config until rustc 1.51 is
stable.
We modeled a Bitcoin `headers` message as being a list of block headers.
However, the actual data structure is slightly different: it's a list of (block
header, transaction count) pairs. This caused zcashd to reject our headers
messages.
To fix this, introduce a new `CountedHeader` struct with a `block::Header` and
transaction count `usize`, then thread it through the inbound service and the
state.
I tested this locally by running Zebra with these changes and inspecting a
trace-level log of the span of a peer connection that requested a nontrivial
headers packet from us, and verified that it did not reject our message.
The `CoinbaseData` parses the block height separately from the rest of the
free-form coinbase data. However, it had two bugs:
1. It did not require that the height was canonically encoded;
2. Its canonical encoding was incorrect relative to the BIP34-inherited encoding.
This meant that we computed some transaction hashes incorrectly, because when
we re-serialized the coinbase transaction, we would canonically serialize the
coinbase transaction (using the incorrect definition of canonical, bug 2). And
we didn't notice that the wrong definition of canonical encoding was being used
because we accepted what we thought were non-canonically encoded heights.
The relevant rules are here: 877212414a/src/script/script.h (L307-L346)
This commit changes the encoding to reject non-canonically encoded heights, and
to match the correct encoding rules. We check that at least one
non-canonically encoded height is correctly rejected using a new test vector.
The database format increments because we saved a bunch of wrongly encoded blocks.
This discrepancy was originally noticed by @teor2345, who pointed out that a
previous version of the block 202 test vector (now preserved as "bad block
202") did not match the block from zcashd.
* implement inbound `FindBlocks`
* Handle inbound peer FindHeaders requests
* handle request before having any chain tip
* Split `find_chain_hashes` into smaller functions
Add a `max_len` argument to support `FindHeaders` requests.
Rewrite the hash collection code to use heights, so we can handle the
`stop` hash and "no intersection" cases correctly.
* Split state height functions into "any chain" and "best chain"
* Rename the best chain block method to `best_block`
* Move fmt utilities to zebra_chain::fmt
* Summarise Debug for some Message variants
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Jane Lusby <jlusby42@gmail.com>
The derived Debug impl just shows u8s as numbers, which isn't what we
want. There are basically two reasonable options here:
1. Hex-encoded bytes
2. Escaped ASCII
I picked (2) because a lot of coinbase data has ascii text in it.
`zcashd` converts the PoWLimit into a compact representation before
using it to perform difficulty filter checks.
The Zcash specification converts to compact for the default difficulty
filter, but not for testnet minimum difficulty blocks. (ZIP 205 and
ZIP 208 don't specify this conversion either.) See #1277.
* Implement Expanded to Compact Difficulty
* Implement Arbitrary for CompactDifficulty
Remove the derive, and generate values from random block
hashes.
* Implement Arbitrary for ExpandedDifficulty and Work
* Use Arbitrary for CompactDifficulty in Arbitrary for Block
* Test difficulty on all block test vectors
And cleanup some duplicate test code
* Round-trip tests for compact test cases
* Round-trip tests for compact difficulty in block test vectors
* Make Add for Work return PartialCumulativeWork
Remove AddAssign for Work
Rewrite a proptest using Sub for PartialCumulativeWork
Use Arbitrary for Work
* Add roundtrip work sum tests
* Add roundtrip comparison difficulty tests
* Add failing proptest cases due to test bugs
* Use Some(_) rather than _.into()
* Reduce visibility of difficulty type inner values
* Split work and other difficulty proptests
This change makes sure that rejected work values don't disable property
tests on other types.
* Reverse displayed endianness of transaction and block hashes
* fix zebra-checkpoints utility for new hash order
* Stop using "zebrad revhex" in zebrad-hash-lookup
* Rebuild checkpoint lists in new hash order
This change also adds additional checkpoints to the end of each list.
* Replace TransactionHash with transaction::Hash
This change should have been made in #905, but we missed Debug impls
and some docs.
Co-authored-by: Ramana Venkata <vramana@users.noreply.github.com>
Co-authored-by: teor <teor@riseup.net>
Reduce the default number of cases run by the equihash proptests,
so they run in under 10 seconds on my machine.
Set the PROPTEST_CASES env var to override the default.
* add general and founders reward subsidy modules
* validate founders reward
* Use funding streams after Canopy on testnet
ZIP-1014 only applies to mainnet, where Canopy is at the first halving.
On testnet, Canopy is before the first halving, and the dev fund rules
apply from Canopy. (See ZIP-214.)
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Jane Lusby <jlusby42@gmail.com>
* pass all test vectors through current subsidy validation
* Add testnet and halving subsidy tests
* add subsidy validation error tests
* rename block validation methods
* add network to block verifier
* add amount operators
* Implement Ord, Eq, and Hash for Amount
* Implement Add<Height> for Height
And make the existing Height operators do range checks.
* Apply operator suggestions
Co-authored-by: Jane Lusby <jlusby42@gmail.com>
* implement most of the chain functions
* implement fork
* fix outpoint handling in Chain struct
* update expect for work
* split utxo into two sets
* update the Chain definition
* remove allow attribute in zebra-state/lib.rs
* merge ChainSet type into MemoryState
* Add error messages to asserts
* export proptest impls for use in downstream crates
* add testjob for disabled feature in zebra-chain
* try to fix github actions syntax
* add module doc comment
* update RFC for utxos
* add missing header
* working proptest for Chain
* propagate back results over channel
* Start updating RFC to match changes
* implement queued block pruning
* and now it syncs wooo!
* remove empty modules
* setup config for proptests
* re-enable missing_docs lint
* update RFC to match changes in impl
* add documentation
* use more explicit variable names
* Begin work on RFC5 implementation
* I think this is necessary
* holy shit supertrait implemented via subtrait
* implement most of the chain functions
* change to slightly better name
* implement fork
* fix outpoint handling in Chain struct
* update expect for work
* resolve review comment
* split utxo into two sets
* update the Chain definition
* just a little more
* update comment
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* apply changes from code review
* remove allow attribute in zebra-state/lib.rs
* Update zebra-state/src/memory_state.rs
Co-authored-by: teor <teor@riseup.net>
* merge ChainSet type into MemoryState
* rename state impl types
* Add error messages to asserts
* checkpoint so I can split off arbitrary changes into a PR
* export proptest impls for use in downstream crates
* add testjob for disabled feature in zebra-chain
* run rustfmt
* try to fix github actions syntax
* differentiate name
* prove that github action tests zebra-chain build without features
* revert change from last commit now that test is running
* remove accidentally introduced newline
* checkpoint
* add module doc comment
* update RFC for utxos
* add missing header
* working proptest for Chain
* apply change from chain impl PR
* setup config for proptests
* Update zebra-chain/src/block/arbitrary.rs
Co-authored-by: teor <teor@riseup.net>
* run rustfmt
Co-authored-by: teor <teor@riseup.net>
To avoid confusion with TESTNET_BLOCKS.
Automated search and replace, made using this script:
sed -i 's/TEST_BLOCKS/BLOCKS/' \
$(grep -r TEST_BLOCKS zebra* | cut -d: -f1 | sort -u)
* Move block test vectors into separate files
* Refactor block test vectors into their own module
* Remove some duplicate test vector data
* Add mainnet block test vectors for each network upgrade
* Add testnet block test vectors for each network upgrade
* Update the TEST_BLOCKS list
* Add basic tests using TEST_BLOCKS
* Ignore shell.nix
* Begin work on RFC5 implementation
* I think this is necessary
* holy shit supertrait implemented via subtrait
* implement most of the chain functions
* change to slightly better name
* implement fork
* fix outpoint handling in Chain struct
* update expect for work
* resolve review comment
* split utxo into two sets
* update the Chain definition
* just a little more
* update comment
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* apply changes from code review
* remove allow attribute in zebra-state/lib.rs
* Update zebra-state/src/memory_state.rs
Co-authored-by: teor <teor@riseup.net>
* merge ChainSet type into MemoryState
* rename state impl types
* Add error messages to asserts
* add module doc comment
* update RFC for utxos
* add missing header
Co-authored-by: teor <teor@riseup.net>
* export proptest impls for use in downstream crates
* add testjob for disabled feature in zebra-chain
* run rustfmt
* try to fix github actions syntax
* differentiate name
* prove that github action tests zebra-chain build without features
* revert change from last commit now that test is running
* remove accidentally introduced newline
* Update .github/workflows/ci.yml
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>