zebra/zebra-state/src/error.rs

265 lines
8.9 KiB
Rust
Raw Normal View History

use std::sync::Arc;
use chrono::{DateTime, Utc};
use thiserror::Error;
Reject UTXO double spends (#2511) * 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>
2021-07-22 16:40:15 -07:00
use zebra_chain::{
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
amount::{self, NegativeAllowed, NonNegative},
block,
history_tree::HistoryTreeError,
orchard, sapling, sprout, transaction, transparent,
value_balance::{ValueBalance, ValueBalanceError},
work::difficulty::CompactDifficulty,
Reject UTXO double spends (#2511) * 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>
2021-07-22 16:40:15 -07:00
};
use crate::constants::MIN_TRANSPARENT_COINBASE_MATURITY;
/// A wrapper for type erased errors that is itself clonable and implements the
/// Error trait
#[derive(Debug, Error, Clone)]
#[error(transparent)]
pub struct CloneError {
source: Arc<dyn std::error::Error + Send + Sync + 'static>,
}
impl From<CommitBlockError> for CloneError {
fn from(source: CommitBlockError) -> Self {
let source = Arc::new(source);
Self { source }
}
}
impl From<BoxError> for CloneError {
fn from(source: BoxError) -> Self {
let source = Arc::from(source);
Self { source }
}
}
/// A boxed [`std::error::Error`].
pub type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
/// An error describing the reason a block could not be committed to the state.
Add ZIP-221 history tree to non-finalized state (#2583) * 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>
2021-08-11 06:42:40 -07:00
#[derive(Debug, Error, PartialEq, Eq)]
#[error("block is not contextually valid")]
pub struct CommitBlockError(#[from] ValidateContextError);
/// An error describing why a block failed contextual validation.
Add ZIP-221 history tree to non-finalized state (#2583) * 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>
2021-08-11 06:42:40 -07:00
#[derive(Debug, Error, PartialEq, Eq)]
#[non_exhaustive]
#[allow(missing_docs)]
pub enum ValidateContextError {
#[error("block height {candidate_height:?} is lower than the current finalized height {finalized_tip_height:?}")]
#[non_exhaustive]
OrphanedBlock {
candidate_height: block::Height,
finalized_tip_height: block::Height,
},
#[error("block height {candidate_height:?} is not one greater than its parent block's height {parent_height:?}")]
#[non_exhaustive]
NonSequentialBlock {
candidate_height: block::Height,
parent_height: block::Height,
},
#[error("block time {candidate_time:?} is less than or equal to the median-time-past for the block {median_time_past:?}")]
#[non_exhaustive]
TimeTooEarly {
candidate_time: DateTime<Utc>,
median_time_past: DateTime<Utc>,
},
#[error("block time {candidate_time:?} is greater than the median-time-past for the block plus 90 minutes {block_time_max:?}")]
#[non_exhaustive]
TimeTooLate {
candidate_time: DateTime<Utc>,
block_time_max: DateTime<Utc>,
},
#[error("block difficulty threshold {difficulty_threshold:?} is not equal to the expected difficulty for the block {expected_difficulty:?}")]
#[non_exhaustive]
InvalidDifficultyThreshold {
difficulty_threshold: CompactDifficulty,
expected_difficulty: CompactDifficulty,
},
Reject UTXO double spends (#2511) * 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>
2021-07-22 16:40:15 -07:00
#[error("transparent double-spend: {outpoint:?} is spent twice in {location:?}")]
#[non_exhaustive]
DuplicateTransparentSpend {
outpoint: transparent::OutPoint,
location: &'static str,
},
#[error("missing transparent output: possible double-spend of {outpoint:?} in {location:?}")]
#[non_exhaustive]
MissingTransparentOutput {
outpoint: transparent::OutPoint,
location: &'static str,
},
#[error("out-of-order transparent spend: {outpoint:?} is created by a later transaction in the same block")]
#[non_exhaustive]
EarlyTransparentSpend { outpoint: transparent::OutPoint },
#[error(
"unshielded transparent coinbase spend: {outpoint:?} \
must be spent in a transaction which only has shielded outputs"
)]
#[non_exhaustive]
UnshieldedTransparentCoinbaseSpend { outpoint: transparent::OutPoint },
#[error(
"immature transparent coinbase spend: \
attempt to spend {outpoint:?} at {spend_height:?}, \
but spends are invalid before {min_spend_height:?}, \
which is {MIN_TRANSPARENT_COINBASE_MATURITY:?} blocks \
after it was created at {created_height:?}"
)]
#[non_exhaustive]
ImmatureTransparentCoinbaseSpend {
outpoint: transparent::OutPoint,
spend_height: block::Height,
min_spend_height: block::Height,
created_height: block::Height,
},
#[error("sprout double-spend: duplicate nullifier: {nullifier:?}, in finalized state: {in_finalized_state:?}")]
#[non_exhaustive]
DuplicateSproutNullifier {
nullifier: sprout::Nullifier,
in_finalized_state: bool,
},
Reject duplicate Sapling and Orchard nullifiers (#2497) * Add sapling and orchard duplicate nullifier errors * Reject duplicate finalized sapling and orchard nullifiers Reject duplicate sapling and orchard nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is already in the finalized state. * Reject duplicate non-finalized sapling and orchard nullifiers Reject duplicate sapling and orchard nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is in: * the same shielded data, * the same transaction, * the same block, or * an earlier block in the non-finalized chain. * Refactor sprout nullifier tests to remove common code * Add sapling nullifier tests Test that the state rejects duplicate sapling nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is in: * the same shielded data, * the same transaction, * the same block, * an earlier block in the non-finalized chain, or * the finalized state. * Add orchard nullifier tests Test that the state rejects duplicate orchard nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is in: * the same shielded data, * the same transaction, * the same block, * an earlier block in the non-finalized chain, or * the finalized state. * Check for specific nullifiers in the state in tests * Replace slices with vectors in arguments * Remove redundant code and variables * Simplify sapling TransferData tests Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Remove an extra : * Remove redundant vec! Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2021-07-19 17:39:05 -07:00
#[error("sapling double-spend: duplicate nullifier: {nullifier:?}, in finalized state: {in_finalized_state:?}")]
#[non_exhaustive]
DuplicateSaplingNullifier {
nullifier: sapling::Nullifier,
in_finalized_state: bool,
},
#[error("orchard double-spend: duplicate nullifier: {nullifier:?}, in finalized state: {in_finalized_state:?}")]
#[non_exhaustive]
DuplicateOrchardNullifier {
nullifier: orchard::Nullifier,
in_finalized_state: bool,
},
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
#[error(
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
"the remaining value in the transparent transaction value pool MUST be nonnegative:\n\
{amount_error:?},\n\
{height:?}, index in block: {tx_index_in_block:?}, {transaction_hash:?}"
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
)]
#[non_exhaustive]
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
NegativeRemainingTransactionValue {
amount_error: amount::Error,
height: block::Height,
tx_index_in_block: usize,
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
transaction_hash: transaction::Hash,
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
},
#[error(
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
"error calculating the remaining value in the transaction value pool:\n\
{amount_error:?},\n\
{height:?}, index in block: {tx_index_in_block:?}, {transaction_hash:?}"
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
)]
#[non_exhaustive]
CalculateRemainingTransactionValue {
amount_error: amount::Error,
height: block::Height,
tx_index_in_block: usize,
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
transaction_hash: transaction::Hash,
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
},
#[error(
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
"error calculating value balances for the remaining value in the transaction value pool:\n\
{value_balance_error:?},\n\
{height:?}, index in block: {tx_index_in_block:?}, {transaction_hash:?}"
Check remaining transaction value & make value balance signs match the spec (#2566) * 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>
2021-08-09 10:22:26 -07:00
)]
#[non_exhaustive]
CalculateTransactionValueBalances {
value_balance_error: ValueBalanceError,
height: block::Height,
tx_index_in_block: usize,
Add value pool/balances to non-finalized state (#2656) * add value balances to non finalized state * fix 2 tests * fix remaining constrain issues in tests * extend value pool test to non finalized * WIP: fix tests after adding value pools to non-finalized state (#2647) * Update Chain::eq_internal_state with Chain.value_balance Also increase the number of cases in its tests, because they didn't detect this bug. * Calculate the chain value pool change before `Chain::push` Code - store the chain value pool change in `ContextuallyValidBlock` - convert `PreparedBlock` to `ContextuallyValidBlock` using `with_block_and_spent_utxos` (rather than `from` or `into`) - replace `block_utxos` with `new_outputs` in `PreparedBlock` - replace `block_utxos` with `chain_value_pool_change` in `ContextuallyValidBlock` Tests - create test methods for `PreparedBlock` and `ContextuallyValidBlock` - use `test_with_zero_chain_pool_change` or `test_with_zero_spent_utxos` to make tests pass * fix conflicts * build `set_current_value_pool()` only for tests * remove redundant cfgs * change cfg of set_current_value_pool() * Clarify some chain field documentation * Fix bugs in the non-finalized chain value pool calculations 1. Only revert the chain value pool balances when the tip is popped. Don't modify them when the root is finalized. 2. Only update or revert the chain value pool balances once per block. (Previously, the block changes were multiplied by the number of *transactions*.) And make corresponding changes to method names and documentation. * Add extra proptests to try to identify value balance failures * Simplify some transaction generation code * Add extra debugging info to value balance errors * Actually update non-finalized chain value pools in `UpdateWith` Previously, we were dropping the updated value pools in the `Ok` result. So the initial (finalized) chain value pool balances were never modified. * Rename and document value balance add methods The names and documentation of these methods were confusing. * Create genesis-based proptests that check chain value pools * Increase coverage for some test vectors * Test each chain value balance calculation for blocks 0-10 * Make continuous blockchain test errors easier to debug * Test the exact transparent pool values for the first few blocks Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2021-08-25 06:57:07 -07:00
transaction_hash: transaction::Hash,
},
#[error(
"error calculating the block chain value pool change:\n\
{value_balance_error:?},\n\
{height:?}, {block_hash:?},\n\
transactions: {transaction_count:?}, spent UTXOs: {spent_utxo_count:?}"
)]
#[non_exhaustive]
CalculateBlockChainValueChange {
value_balance_error: ValueBalanceError,
height: block::Height,
block_hash: block::Hash,
transaction_count: usize,
spent_utxo_count: usize,
},
#[error(
"error adding value balances to the chain value pool:\n\
{value_balance_error:?},\n\
{chain_value_pools:?},\n\
{block_value_pool_change:?},\n\
{height:?}"
)]
#[non_exhaustive]
AddValuePool {
value_balance_error: ValueBalanceError,
chain_value_pools: ValueBalance<NonNegative>,
block_value_pool_change: ValueBalance<NegativeAllowed>,
height: Option<block::Height>,
},
Track anchors and note commitment trees in zebra-state (#2458) * Tidy chain Cargo.toml * Organize imports * Add method to get note commitments from all Actions in Orchard shielded data * Add method to get note commitments from all JoinSplits in Sprout JoinSplitData * Add Request and Response variants for awaiting anchors * Add anchors and note commitment trees to finalized state db * Add (From|Into)Disk impls for tree::Roots and stubs for NoteCommitmentTrees * Track anchors and note commitment trees in Chain Append note commitments to their trees when doing update_chain_state_with, then use the resulting Sapling and Orchard roots to pass to history_tree, and add new roots to the anchor sets. * Handle errors when appending to note commitment trees * Add comments explaining why note commitment are not removed from the tree in revert_chain_state_with * Implementing note commitments in finalized state * Finish serialization of Orchard tree; remove old tree when updating finalize state * Add serialization and finalized state updates for Sprout and Sapling trees * Partially handle trees in non-finalized state. Use Option for trees in Chain * Rebuild trees when forking; change finalized state tree getters to not require height * Pass empty trees to tests; use empty trees by default in Chain * Also rebuild anchor sets when forking * Use empty tree as default in finalized state tree getters (for now) * Use HashMultiSet for anchors in order to make pop_root() work correctly * Reduce DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES and MAX_PARTIAL_CHAIN_BLOCKS * Reduce DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES and MAX_PARTIAL_CHAIN_BLOCKS even more * Apply suggestions from code review * Add comments about order of note commitments and related methods/fields * Don't use Option for trees * Set DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES=1 and restore MAX_PARTIAL_CHAIN_BLOCKS * Remove unneeded anchor set rebuilding in fork() * Improve proptest formatting * Add missing comparisons to eq_internal_state * Renamed sprout::tree::NoteCommitmentTree::hash() to root() * Improve comments * Add asserts, add issues to TODOs * Remove impl Default for Chain since it was only used by tests * Improve documentation and assertions; add tree serialization tests * Remove Sprout code, which will be moved to another branch * Add todo! in Sprout tree append() * Remove stub request, response *Anchor* handling for now * Add test for validating Sapling note commitment tree using test blocks * Increase database version (new columns added for note commitment trees and anchors) * Update test to make sure the order of sapling_note_commitments() is being tested * Improve comments and structure of the test * Improve variable names again * Rustfmt Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> Co-authored-by: Conrado P. L. Gouvea <conradoplg@gmail.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org> Co-authored-by: teor <teor@riseup.net>
2021-07-29 06:37:18 -07:00
#[error("error in Sprout note commitment tree")]
SproutNoteCommitmentTreeError(#[from] zebra_chain::sprout::tree::NoteCommitmentTreeError),
Track anchors and note commitment trees in zebra-state (#2458) * Tidy chain Cargo.toml * Organize imports * Add method to get note commitments from all Actions in Orchard shielded data * Add method to get note commitments from all JoinSplits in Sprout JoinSplitData * Add Request and Response variants for awaiting anchors * Add anchors and note commitment trees to finalized state db * Add (From|Into)Disk impls for tree::Roots and stubs for NoteCommitmentTrees * Track anchors and note commitment trees in Chain Append note commitments to their trees when doing update_chain_state_with, then use the resulting Sapling and Orchard roots to pass to history_tree, and add new roots to the anchor sets. * Handle errors when appending to note commitment trees * Add comments explaining why note commitment are not removed from the tree in revert_chain_state_with * Implementing note commitments in finalized state * Finish serialization of Orchard tree; remove old tree when updating finalize state * Add serialization and finalized state updates for Sprout and Sapling trees * Partially handle trees in non-finalized state. Use Option for trees in Chain * Rebuild trees when forking; change finalized state tree getters to not require height * Pass empty trees to tests; use empty trees by default in Chain * Also rebuild anchor sets when forking * Use empty tree as default in finalized state tree getters (for now) * Use HashMultiSet for anchors in order to make pop_root() work correctly * Reduce DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES and MAX_PARTIAL_CHAIN_BLOCKS * Reduce DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES and MAX_PARTIAL_CHAIN_BLOCKS even more * Apply suggestions from code review * Add comments about order of note commitments and related methods/fields * Don't use Option for trees * Set DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES=1 and restore MAX_PARTIAL_CHAIN_BLOCKS * Remove unneeded anchor set rebuilding in fork() * Improve proptest formatting * Add missing comparisons to eq_internal_state * Renamed sprout::tree::NoteCommitmentTree::hash() to root() * Improve comments * Add asserts, add issues to TODOs * Remove impl Default for Chain since it was only used by tests * Improve documentation and assertions; add tree serialization tests * Remove Sprout code, which will be moved to another branch * Add todo! in Sprout tree append() * Remove stub request, response *Anchor* handling for now * Add test for validating Sapling note commitment tree using test blocks * Increase database version (new columns added for note commitment trees and anchors) * Update test to make sure the order of sapling_note_commitments() is being tested * Improve comments and structure of the test * Improve variable names again * Rustfmt Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> Co-authored-by: Conrado P. L. Gouvea <conradoplg@gmail.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org> Co-authored-by: teor <teor@riseup.net>
2021-07-29 06:37:18 -07:00
#[error("error in Sapling note commitment tree")]
SaplingNoteCommitmentTreeError(#[from] zebra_chain::sapling::tree::NoteCommitmentTreeError),
#[error("error in Orchard note commitment tree")]
OrchardNoteCommitmentTreeError(#[from] zebra_chain::orchard::tree::NoteCommitmentTreeError),
Add ZIP-221 history tree to non-finalized state (#2583) * 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>
2021-08-11 06:42:40 -07:00
#[error("error building the history tree")]
HistoryTreeError(#[from] HistoryTreeError),
#[error("block contains an invalid commitment")]
InvalidBlockCommitment(#[from] block::CommitmentError),
}
/// Trait for creating the corresponding duplicate nullifier error from a nullifier.
pub(crate) trait DuplicateNullifierError {
/// Returns the corresponding duplicate nullifier error for `self`.
fn duplicate_nullifier_error(&self, in_finalized_state: bool) -> ValidateContextError;
}
impl DuplicateNullifierError for sprout::Nullifier {
fn duplicate_nullifier_error(&self, in_finalized_state: bool) -> ValidateContextError {
ValidateContextError::DuplicateSproutNullifier {
nullifier: *self,
in_finalized_state,
}
}
}
Reject duplicate Sapling and Orchard nullifiers (#2497) * Add sapling and orchard duplicate nullifier errors * Reject duplicate finalized sapling and orchard nullifiers Reject duplicate sapling and orchard nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is already in the finalized state. * Reject duplicate non-finalized sapling and orchard nullifiers Reject duplicate sapling and orchard nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is in: * the same shielded data, * the same transaction, * the same block, or * an earlier block in the non-finalized chain. * Refactor sprout nullifier tests to remove common code * Add sapling nullifier tests Test that the state rejects duplicate sapling nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is in: * the same shielded data, * the same transaction, * the same block, * an earlier block in the non-finalized chain, or * the finalized state. * Add orchard nullifier tests Test that the state rejects duplicate orchard nullifiers in a new block, when the block is added to a non-finalized chain, and the duplicate nullifier is in: * the same shielded data, * the same transaction, * the same block, * an earlier block in the non-finalized chain, or * the finalized state. * Check for specific nullifiers in the state in tests * Replace slices with vectors in arguments * Remove redundant code and variables * Simplify sapling TransferData tests Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Remove an extra : * Remove redundant vec! Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2021-07-19 17:39:05 -07:00
impl DuplicateNullifierError for sapling::Nullifier {
fn duplicate_nullifier_error(&self, in_finalized_state: bool) -> ValidateContextError {
ValidateContextError::DuplicateSaplingNullifier {
nullifier: *self,
in_finalized_state,
}
}
}
impl DuplicateNullifierError for orchard::Nullifier {
fn duplicate_nullifier_error(&self, in_finalized_state: bool) -> ValidateContextError {
ValidateContextError::DuplicateOrchardNullifier {
nullifier: *self,
in_finalized_state,
}
}
}