* Impl the elementary structure of the `z_gettreestate` RPC
* Fix merging bugs
* Fix a merge bug
* Fix a merge bug
* Move a derive attribute
Co-authored-by: teor <teor@riseup.net>
* Clarify the support of negative heights
* Add Orchard note commitment trees to the response
* Add the time to the response
* Finalize the `z_gettreestate` RPC
* Add a note that verified blocks have coinbase height
* Refactor `from_str` for `HashOrHeight`
* Fix a mistake in the docs
Co-authored-by: teor <teor@riseup.net>
* Clarify request types
Co-authored-by: teor <teor@riseup.net>
* Simplify `hash_or_height` conversion to height
Co-authored-by: teor <teor@riseup.net>
* Add a TODO about optimization
Co-authored-by: teor <teor@riseup.net>
* Add a doc comment
* Make sure Sapling & Orchard trees don't get mixed up
* Serialize Sapling commitment trees
* Refactor some comments
* Serialize Orchard commitment trees
* Serialize block heights
* Simplify the serialization of commitment trees
* Remove the block time from the RPC response
* Simplify the serialization of block heights
* Put Sapling & Orchard requests together
* Remove a redundant TODO
* Add block times to the RPC response
* Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate`
Co-authored-by: teor <teor@riseup.net>
* Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree`
* Document the fields of `GetTreestate`
* Skip the serialization of empty trees
This ensures compatibility with `zcashd` in the `z_gettreestate` RPC.
* Document the `impl` of `merkle_tree::Hashable` for nodes
* Make the structure of the JSON response consistent with `zcashd`
* Derive `Eq` for nodes
Co-authored-by: teor <teor@riseup.net>
* Convert Sapling commitment trees to a format compatible with zcashd
* Refactor the conversion of Sapling commitment trees
* Refactor some comments
* Refactor comments
* Add a description of the conversion
Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
* Fix comment indenting
* Document the conversion between the dense and sparse formats
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
* Derive Hash for transparent address index types
* Expose some types used by transparent address indexes
* Add an empty transparent transfers type for transparent address indexes
* Update TransparentTransfers with created UTXOs
* Add spent transparent outputs to ContextuallyValidBlock
* Update TransparentTransfers with spent transparent outputs
* Ignore missing spent outputs, so that tests pass
* Remove empty TransparentTransfers after a spend revert
* Update TransparentTransfers with creating and spending transaction IDs
* Ignore duplicate created UTXOs, so that tests pass
* Add some TODO comments
* Remove accidental doctest formatting
* Add address transfers index accessor methods
* Use TransactionLocation in the non-finalized state
* Apply more address index assertions to production code
* Refactor deeply nested code and apply more assertions
* Return UTXOs in chain order
* Return transaction hashes in chain order
* Stop indexing each transparent output multiple times
* Run some more asserts during tests
* Tidy TODO comments
* Fix an incorrect assert condition
* Use OrderedUtxos so that spent UTXOs can be stored in chain order
* Update tests to use OrderedUtxos
* Update the index API for the getaddressutxos query
* Remove redundant arguments in tests
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* feature(rpc): start adding a `getblock` method
* fix(rpc): replace oneshot
* fix(rpc): replace a panic with error
* fix(rpc): fix test
* feature(rpc): add hex to response
* refactor(rpc): use generic instead of alias
* docs(rpc): improve docs for getblock method
* test(rpc): add a test for getblock method
* deps(rpc): remove non needed tower features
Co-authored-by: teor <teor@riseup.net>
* docs(rpc): add a note to getblock doc
* refactor(rpc): replace alias
* fix(rpc): use `zcash_serialize_to_vec()` instead of logging format
* tests(rpc): add network argument to `populated_state()`
* refactor(rpc): use an error for state service readiness
* fix(rpc): add parameter
* fix(rpc): clippy
* nit(rpc): remove new line from imports
* fix(rpc): remove commented code
* fix(rpc): simplify error
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* Use a `SerializedBlock` type to help serializing blocks (#3725)
* Create a `SerializedBlock` helper type
Create a type that can be used as a byte slice, but is guaranteed to
represent a valid block.
* Use `into_iter` instead of `iter`
There's no need to borrow the elements, they can be moved out directly.
This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`,
so a `SerializedBlock` can't be built directly from an `&Arc<Block>`.
* Use `SerializedBlock` in `GetBlock`
Make the type stricter to avoid storing possibly invalid values. The
bytes are still serialized as a hexadecimal string, through the usage of
`hex`.
The `serde::Deserialize` can't be derived because `hex` requires the
type to also implement `FromHex`.
* feature(rpc): add suggestions from code review
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* tests(rpc): make sure mempool has no requests in get_block test
* fix(rpc): change height argument type in getblock method
* fix(rpc): rustfmt
* fix(rpc): replace panic
* fix(rpc): change getblock response
* fix(rpc): fix lightwalletd test
* tests(rpc): add a getblock error test
* fix(rpc): try another regex
* feature(rpc): add `getbestblockhash` RPC method
* feature(rpc): Add a `pub struct SerializedBlockHash` type
* tests(rpc): add a unit test for `getbestblockhash` method
* tests(rpc): make sure no requests are sent to mempool in getbestblockhash test
* tests(rpc): refactor check
Co-authored-by: teor <teor@riseup.net>
* fix(rpc): fixes after rebase
* refactor(rpc): refactor `GetBestBlockHash`
* fix(rpc): unused variables
Co-authored-by: teor <teor@riseup.net>
* docs(rpc): update
* fix(rpc): add panic
* fix(rpc): fix panic
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* feature(rpc): start adding a `getblock` method
* fix(rpc): replace oneshot
* fix(rpc): replace a panic with error
* fix(rpc): fix test
* feature(rpc): add hex to response
* refactor(rpc): use generic instead of alias
* docs(rpc): improve docs for getblock method
* test(rpc): add a test for getblock method
* deps(rpc): remove non needed tower features
Co-authored-by: teor <teor@riseup.net>
* docs(rpc): add a note to getblock doc
* refactor(rpc): replace alias
* fix(rpc): use `zcash_serialize_to_vec()` instead of logging format
* tests(rpc): add network argument to `populated_state()`
* refactor(rpc): use an error for state service readiness
* fix(rpc): add parameter
* fix(rpc): clippy
* nit(rpc): remove new line from imports
* fix(rpc): remove commented code
* fix(rpc): simplify error
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* Use a `SerializedBlock` type to help serializing blocks (#3725)
* Create a `SerializedBlock` helper type
Create a type that can be used as a byte slice, but is guaranteed to
represent a valid block.
* Use `into_iter` instead of `iter`
There's no need to borrow the elements, they can be moved out directly.
This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`,
so a `SerializedBlock` can't be built directly from an `&Arc<Block>`.
* Use `SerializedBlock` in `GetBlock`
Make the type stricter to avoid storing possibly invalid values. The
bytes are still serialized as a hexadecimal string, through the usage of
`hex`.
The `serde::Deserialize` can't be derived because `hex` requires the
type to also implement `FromHex`.
* feature(rpc): add suggestions from code review
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* tests(rpc): make sure mempool has no requests in get_block test
* fix(rpc): change height argument type in getblock method
* fix(rpc): rustfmt
* fix(rpc): replace panic
* fix(rpc): change getblock response
* fix(rpc): fix lightwalletd test
* tests(rpc): add a getblock error test
* fix(rpc): try another regex
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* refactor(test/block): rename large single transaction function
```sh
fastmod single_transaction_block single_transaction_block_many_inputs
```
* rustfmt
* test(block): add a test block with many transparent outputs
* doc(db): explain why we can't just get the UTXOs right before they are deleted
* refactor(db): split out a block data write method
* refactor(block): add a height argument to new_outputs
* test(db): add block and transaction round-trip tests
Including large blocks and transactions.
* test(db): fix large block serialization instability in the tests
* doc(block): add TODOs for generating correct blocks
* Make transparent output functions which take a height test-only
* make sure generated blocks are actually over/under-sized
* replace println!() with an error!() log
* change `anchorSapling` type
* implement PartialEq manually for clippy
* use `unique_by` in place of `sorted`
* replace panic with new error
* improve some serialize/deserialize calls for sapling anchors
* fix arbitrary for sapling::tree::Root
* remove dedup()
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Support large block heights
* Document consensus rules referring to expiry heights
* Refactor the docs
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Fix the formatting of an error message
* refactor: Simplify coinbase expiry code so the consensus rule is clear (#3408)
* Fix some outdated TODO comments
* refactor(coinbase expiry): Simplify the code so consensus rule is clear
* Fix the formatting of an error message
* Remove a redundant comment
Co-authored-by: Marek <mail@marek.onl>
Co-authored-by: Marek <mail@marek.onl>
* Check the max expiry height at parse time
* Test that 2^31 - 1 is the last valid height
* Add tests for nExpiryHeight
* Add tests for expiry heights of V4 transactions
* Add tests for V5 transactions
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* lint: enable more clippy checks for bug-prone code
* fix(lint): stop denying lints, to avoid being excluded from Crater
Also categorise lints.
* lint: add some lints to the TODO list
* refactor(arithmetic): partial fixes for some integer arithmetic lints
* Document some weird lint behaviour
* add testnet test blocks around nu5
* validate coinbase expiration height
* change const name and doc
Co-authored-by: teor <teor@riseup.net>
* change commit location
Co-authored-by: teor <teor@riseup.net>
* use pre Nu5 rules when there is no activation height
* add sapling final root to nu5 test vectors
* fix tests
Co-authored-by: teor <teor@riseup.net>
* Cleanup a function that calls zcash_script
* Remove zebra_test::prelude macros that conflict with the Rust prelude
* Add sigops count support to zebra-script
* Check MAX_BLOCK_SIGOPS in the block verifier
* Test MAX_BLOCK_SIGOPS on generated and historic blocks
* Add SAFETY comments for all unsafe zebra-script code
* Explain where the consensus rule comes from
* Remove unused pretty_assertions dependency
* Allow large test block generation functions with the proptest-impl feature
* Replace `as` with `try_into` for integer conversions in unsafe code
* Expand SAFETY comments
* Fix an incorrect assertion when the block locator is at the tip
This might have been triggered by receiving block hash gossips
from the new Zebra code.
* Add missing tests for zebra-state requests and responses
Specifically:
* `BlockLocator` (populated state only)
* `FindBlockHashes`
* `FindBlockHeaders`
* Test `FindBlock*` before and after the current block
* Add a specific test for bug #2789
* Refactor collect_best_chain_hashes to avoid manual index calculations
* Reword a comment
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
* Add validation of ZIP-221 and ZIP-244 commitments
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Add auth commitment check in the finalized state
* Reset the verifier when comitting to state fails
* Add explanation comment
* Add test with fake activation heights
* Add generate_valid_commitments flag
* Enable fake activation heights using env var instead of feature
* Also update initial_tip_hash; refactor into progress_from_tip()
* Improve comments
* Add fake activation heights test to CI
* Fix bug that caused commitment trees to not match when generating partial arbitrary chains
* Add ChainHistoryBlockTxAuthCommitmentHash::from_commitments to organize and deduplicate code
* Remove stale comment, improve readability
* Allow overriding with PROPTEST_CASES
* partial_chain_strategy(): don't update note commitment trees when not needed; add comment
Co-authored-by: teor <teor@riseup.net>
* Generate chains with valid chain value pool balances
* Move MAX_PARTIAL_CHAIN_BLOCKS to zebra-chain
* Fix generated value overflow based on the maximum number of values
And split it into its own method.
* Split fix_remaining_value into smaller methods
* Remove unused methods
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
* Refactor HistoryTree into NonEmptyHistoryTree and HistoryTree
* HistoryTree: use Deref instead of AsRef; remove unneeded PartialEq
* ZIP-221: Validate chain history commitments in the non-finalized state (#2301)
* sketch of implementation
* refined implementation; still incomplete
* update librustzcash, change zcash_history to work with it
* simplified code per review; renamed MMR to HistoryTree
* expand HistoryTree implementation
* handle and propagate errors
* simplify check.rs tracing
* add suggested TODO
* add HistoryTree::prune
* fix bug in pruning
* fix compilation of tests; still need to make them pass
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* improvements from code review
* improve check.rs comments and variable names
* fix HistoryTree which should use BTreeMap and not HashMap; fix non_finalized_state prop tests
* fix finalized_state proptest
* fix non_finalized_state tests by setting the correct commitments
* renamed mmr.rs to history_tree.rs
* Add HistoryTree struct
* expand non_finalized_state protest
* fix typo
* Add HistoryTree struct
* Update zebra-chain/src/primitives/zcash_history.rs
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>
* fix formatting
* Apply suggestions from code review
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>
* history_tree.rs: fixes from code review
* fixes to work with updated HistoryTree
* Improvements from code review
* Add Debug implementations to allow comparing Chains with proptest_assert_eq
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Improvements from code review
* Restore blocks returned by PreparedChain since other tests broken; adjust tests with history trees
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>
* Make Amount arithmetic more generic
To modify generated amounts, we need some extra operations on `Amount`.
We also need to extend existing operations to both `NonNegative` and
`NegativeAllowed` amounts.
* Add a constrain method for ValueBalance
* Derive Eq for ValueBalance
* impl Neg for ValueBalance
* Make some Amount arithmetic expectations explicit
* Explain why we use i128 for multiplication
And expand the overflow error details.
* Expand Amount::sum error details
* Make amount::Error field order consistent
* Rename an amount::Error variant to Constraint, so it's clearer
* Add specific pool variants to ValueBalanceError
* Update coinbase remaining value consensus rule comment
This consensus rule was updated recently to include coinbase transactions,
but Zebra doesn't check block subsidy or miner fees yet.
* Add test methods for modifying transparent values and shielded value balances
* Temporarily set values and value balances to zero in proptests
In both generated chains and proptests that construct their own transactions.
Using zero values reduces value calculation and value check test coverage.
A future change will use non-zero values, and fix them so the check passes.
* Add extra fields to remaining transaction value errors
* Swap the transparent value balance sign to match shielded value balances
This makes the signs of all the chain value pools consistent.
* Use a NonNegative constraint for transparent values
This fix:
* makes the type signature match the consensus rules
* avoids having to write code to handle negative values
* Allocate total generated transaction input value to outputs
If there isn't enough input value for an output, set it to zero.
Temporarily reduce all generated values to avoid overflow.
(We'll remove this workaround when we calculate chain value balances.)
* Consistently use ValueBalanceError for ValueBalances
* Make the value balance signs match the spec
And rename and document methods so their signs are clearer.
* Convert amount::Errors to specific pool ValueBalanceErrors
* Move some error changes to the next PR
* Add extra info to remaining transaction value errors (#2585)
* Distinguish between overflow and negative remaining transaction value errors
And make some error types cloneable.
* Add methods for updating chain value pools (#2586)
* Move amount::test to amount::tests:vectors
* Make ValueBalance traits more consistent with Amount
- implement Add and Sub variants with Result and Assign
- derive Hash
* Clarify some comments and expects
* Create ValueBalance update methods for blocks and transactions
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
* Add 1 to 3 transactions to generated blocks, rather than always 2
This change improves test coverage.
As a side-effect, it reduces the average number of generated
transactions, which should improve performance.
* Add 1 to max_size generated transparent inputs, rather than always max_size
Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>
* Validate transparent coinbase output maturity and shielding
- Add a CoinbaseSpendRestriction enum and Transaction method
- Validate transparent coinbase spends in non-finalized chains
* Don't use genesis created UTXOs for spends in generated block chains
* Refactor out a new_transaction_ordered_outputs function
* Add Transaction::outputs_mut for tests
* Generate valid transparent spends in arbitrary block chains
* When generating blocks, fixup the block contents, then the block hash
* Test that generated chains contain at least one transparent spend
* Make generated chains long enough for reliable tests
* Add transparent and shielded input and output methods to Transaction
* Split chain generation into 3 functions
* Test that unshielded and immature transparent coinbase spends fail
* Comment punctuation
* Clarify a comment
* Clarify probability calculation
* Test that shielded mature coinbase output spends succeed
* Reject transparent output double-spends
Check that transparent spends use unspent outputs from:
* earlier transaction in the same block,
* earlier blocks in the parent non-finalized chain, or
* the finalized state.
* Fixup UTXOs in proptests
* Add a comment
* Clarify a consensus rule implementation
* Fix an incorrect comment
* Fix an incorrect error message
* Clarify a comment
* Document `unspent_utxos`
* Simplify the UTXO check
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* Further simplify and fix the UTXO check
- split each error case into a separate check
- combine `contains` and `insert`
- add a missing check against the non-finalized unspent UTXOs
- rename arguments and edit error strings for clarity
* Share test methods between check test modules
* Make some chain fields available to tests
* Make error field names consistent with transparent::Input
* WIP: Add tests for UTXO double-spends
- accept output and spend in the same block
- accept output and spend in a later block
- reject output and double-spend all in the same block
- reject output then double-spend in a later block
- reject output, spend, then double-spend all in different blocks
* Use Extend rather than multiple pushes
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* Use Extend for more pushes
* Limit the number of proptest cases, to speed up tests
* Test rejection of UTXOs that were never in the chain
* Test rejection of spends of later transactions in the same block
Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* Skip invalid legacy chain check test cases
Add proptest seeds for the failing test.
And improve some unclear documentation.
* Fix the legacy chain test blocks order
Also fix unclear documentation that might have led to this bug.
* move network_upgrade check into zebra-chain
* fix the errors
* rename function
* typo fix
* rename the check function
* make changes from last code review
* 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 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.
* 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
* 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
* 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
* 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.
* 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.