zebra/zebra-chain/src/transaction.rs

1286 lines
46 KiB
Rust
Raw Normal View History

2020-08-15 21:55:28 -07:00
//! Transactions and transaction-related structures.
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
use halo2::pasta::pallas;
use serde::{Deserialize, Serialize};
mod auth_digest;
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
mod hash;
mod joinsplit;
2020-08-14 23:37:25 -07:00
mod lock_time;
2020-08-15 18:50:18 -07:00
mod memo;
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
mod serialize;
mod sighash;
mod txid;
mod unmined;
#[cfg(any(test, feature = "proptest-impl"))]
pub mod arbitrary;
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
#[cfg(test)]
mod tests;
pub use auth_digest::AuthDigest;
pub use hash::{Hash, WtxId};
2020-08-17 02:06:38 -07:00
pub use joinsplit::JoinSplitData;
2020-08-14 23:37:25 -07:00
pub use lock_time::LockTime;
2020-08-15 18:50:18 -07:00
pub use memo::Memo;
pub use sapling::FieldNotPresent;
pub use sighash::{HashType, SigHash};
pub use unmined::{UnminedTx, UnminedTxId, VerifiedUnminedTx};
use crate::{
amount::{Amount, Error as AmountError, NegativeAllowed, NonNegative},
block, orchard,
parameters::NetworkUpgrade,
primitives::{Bctv14Proof, Groth16Proof},
sapling, sprout,
transparent::{
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
self, outputs_from_utxos,
CoinbaseSpendRestriction::{self, *},
},
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
value_balance::{ValueBalance, ValueBalanceError},
};
Refactor mempool spend conflict checks to increase performance (#2826) * Add `HashSet`s to help spend conflict detection Keep track of the spent transparent outpoints and the revealed nullifiers. Clippy complained that the `ActiveState` had variants with large size differences, but that was expected, so I disabled that lint on that `enum`. * Clear the `HashSet`s when clearing the mempool Clear them so that they remain consistent with the set of verified transactions. * Use `HashSet`s to check for spend conflicts Store new outputs into its respective `HashSet`, and abort if a duplicate output is found. * Remove inserted outputs when aborting Restore the `HashSet` to its previous state. * Remove tracked outputs when removing a transaction Keep the mempool storage in a consistent state when a transaction is removed. * Remove tracked outputs when evicting from mempool Ensure eviction also keeps the tracked outputs consistent with the verified transactions. * Refactor to create a `VerifiedSet` helper type Move the code to handle the output caches into the new type. Also move the eviction code to make things a little simpler. * Refactor to have a single `remove` method Centralize the code that handles the removal of a transaction to avoid mistakes. * Move mempool size limiting back to `Storage` Because the evicted transactions must be added to the rejected list. * Remove leftover `dbg!` statement Leftover from some temporary testing code. Co-authored-by: teor <teor@riseup.net> * Remove unnecessary `TODO` It is more speculation than planning, so it doesn't add much value. Co-authored-by: teor <teor@riseup.net> * Fix typo in documentation The verb should match the subject "transactions" which is plural. Co-authored-by: teor <teor@riseup.net> * Add a comment to warn about correctness There's a subtle but important detail in the implementation that should be made more visible to avoid mistakes in the future. Co-authored-by: teor <teor@riseup.net> * Remove outdated comment Left-over from the attempt to move the eviction into the `VerifiedSet`. * Improve comment explaining lint removal Rewrite the comment explaining why the Clippy lint was ignored. * Check for spend conflicts in `VerifiedSet` Refactor to avoid API misuse. * Test rejected transaction rollback Using two transactions, perform the same test adding a conflict to both of them to check if the second inserted transaction is properly rejected. Then remove any conflicts from the second transaction and add it again. That should work, because if it doesn't it means that when the second transaction was rejected it left things it shouldn't in the cache. * Test removal of multiple transactions When removing multiple transactions from the mempool storage, all of the ones requested should be removed and any other transaction should be still be there afterwards. * Increase mempool size to 4, so that spend conflict tests work If the mempool size is smaller than 4, these tests don't fail on a trivial removal bug. Because we need a minimum number of transactions in the mempool to trigger the bug. Also commit a proptest seed that fails on a trivial removal bug. (This seed fails if we remove indexes in order, because every index past the first removes the wrong transaction.) * Summarise transaction data in proptest error output * Summarise spend conflict field data in proptest error output * Summarise multiple removal field data in proptest error output And replace the very large proptest debug output with the new summary. Co-authored-by: teor <teor@riseup.net>
2021-10-10 16:54:46 -07:00
use std::{collections::HashMap, fmt, iter};
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// A Zcash transaction.
2019-09-25 18:25:46 -07:00
///
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// A transaction is an encoded data structure that facilitates the transfer of
/// value between two public key addresses on the Zcash ecosystem. Everything is
/// designed to ensure that transactions can created, propagated on the network,
/// validated, and finally added to the global ledger of transactions (the
/// blockchain).
2019-09-25 18:25:46 -07:00
///
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// Zcash has a number of different transaction formats. They are represented
/// internally by different enum variants. Because we checkpoint on Canopy
/// activation, we do not validate any pre-Sapling transaction types.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
// XXX consider boxing the Optional fields of V4 and V5 txs
2020-02-04 22:53:24 -08:00
#[allow(clippy::large_enum_variant)]
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
pub enum Transaction {
/// A fully transparent transaction (`version = 1`).
V1 {
/// The transparent inputs to the transaction.
inputs: Vec<transparent::Input>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The transparent outputs from the transaction.
outputs: Vec<transparent::Output>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The earliest time or block height that this transaction can be added to the
/// chain.
lock_time: LockTime,
},
/// A Sprout transaction (`version = 2`).
V2 {
/// The transparent inputs to the transaction.
inputs: Vec<transparent::Input>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The transparent outputs from the transaction.
outputs: Vec<transparent::Output>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The earliest time or block height that this transaction can be added to the
/// chain.
lock_time: LockTime,
/// The JoinSplit data for this transaction, if any.
joinsplit_data: Option<JoinSplitData<Bctv14Proof>>,
},
/// An Overwinter transaction (`version = 3`).
V3 {
/// The transparent inputs to the transaction.
inputs: Vec<transparent::Input>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The transparent outputs from the transaction.
outputs: Vec<transparent::Output>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The earliest time or block height that this transaction can be added to the
/// chain.
lock_time: LockTime,
/// The latest block height that this transaction can be added to the chain.
expiry_height: block::Height,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The JoinSplit data for this transaction, if any.
joinsplit_data: Option<JoinSplitData<Bctv14Proof>>,
},
/// A Sapling transaction (`version = 4`).
V4 {
/// The transparent inputs to the transaction.
inputs: Vec<transparent::Input>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The transparent outputs from the transaction.
outputs: Vec<transparent::Output>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The earliest time or block height that this transaction can be added to the
/// chain.
lock_time: LockTime,
/// The latest block height that this transaction can be added to the chain.
expiry_height: block::Height,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
/// The JoinSplit data for this transaction, if any.
joinsplit_data: Option<JoinSplitData<Groth16Proof>>,
/// The sapling shielded data for this transaction, if any.
sapling_shielded_data: Option<sapling::ShieldedData<sapling::PerSpendAnchor>>,
Update Transaction definition. (#105) * Added a few more top-level fields for the Transaction struct * Add a placeholder Script type. This could alternately use bytes::Bytes to save some allocations but I don't think this is important to get perfectly now. In the future, we will want to have all of the script handling code in the zebra-script crate, but we will need to have a container type for an encoded script in zebra-chain, because otherwise zebra-chain would depend on zebra-script and not the other way around. * Rename Transaction{Input,Output} -> Transparent{Input,Output}. These are only *transparent* inputs and outputs, so by putting Transparent in the name (instead of Transaction) it's more clear that a transaction's inputs or outputs can also be shielded. * Add a LockTime enum. * First attempt at a Transaction enum. This attempts to map the versioning and field presence rules into an ADT, so that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling transaction) are unrepresentable. * Update zebra-chain/src/transaction.rs Co-Authored-By: Daira Hopwood <daira@jacaranda.org> * Add fixme note on type refinement. * Rename Transaction variants according to version. * Split transaction.rs into submodules. * Start filling in spend, output descriptions. * Progress on JoinSplit data structures. This has a lot of duplication and should really use generics to abstract over Sprout-on-BCTV14 or Sprout-on-Groth16. * Add data types for Bctv14 and Groth16 proofs. This also adds a trait to abstract over them. * Make JoinSplit descriptions generic over the proof system. * Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 12:56:58 -08:00
},
/// A `version = 5` transaction, which supports `Sapling` and `Orchard`.
V5 {
/// The Network Upgrade for this transaction.
///
/// Derived from the ConsensusBranchId field.
network_upgrade: NetworkUpgrade,
/// The earliest time or block height that this transaction can be added to the
/// chain.
lock_time: LockTime,
/// The latest block height that this transaction can be added to the chain.
expiry_height: block::Height,
/// The transparent inputs to the transaction.
inputs: Vec<transparent::Input>,
/// The transparent outputs from the transaction.
outputs: Vec<transparent::Output>,
/// The sapling shielded data for this transaction, if any.
sapling_shielded_data: Option<sapling::ShieldedData<sapling::SharedAnchor>>,
/// The orchard data for this transaction, if any.
orchard_shielded_data: Option<orchard::ShieldedData>,
},
}
Refactor mempool spend conflict checks to increase performance (#2826) * Add `HashSet`s to help spend conflict detection Keep track of the spent transparent outpoints and the revealed nullifiers. Clippy complained that the `ActiveState` had variants with large size differences, but that was expected, so I disabled that lint on that `enum`. * Clear the `HashSet`s when clearing the mempool Clear them so that they remain consistent with the set of verified transactions. * Use `HashSet`s to check for spend conflicts Store new outputs into its respective `HashSet`, and abort if a duplicate output is found. * Remove inserted outputs when aborting Restore the `HashSet` to its previous state. * Remove tracked outputs when removing a transaction Keep the mempool storage in a consistent state when a transaction is removed. * Remove tracked outputs when evicting from mempool Ensure eviction also keeps the tracked outputs consistent with the verified transactions. * Refactor to create a `VerifiedSet` helper type Move the code to handle the output caches into the new type. Also move the eviction code to make things a little simpler. * Refactor to have a single `remove` method Centralize the code that handles the removal of a transaction to avoid mistakes. * Move mempool size limiting back to `Storage` Because the evicted transactions must be added to the rejected list. * Remove leftover `dbg!` statement Leftover from some temporary testing code. Co-authored-by: teor <teor@riseup.net> * Remove unnecessary `TODO` It is more speculation than planning, so it doesn't add much value. Co-authored-by: teor <teor@riseup.net> * Fix typo in documentation The verb should match the subject "transactions" which is plural. Co-authored-by: teor <teor@riseup.net> * Add a comment to warn about correctness There's a subtle but important detail in the implementation that should be made more visible to avoid mistakes in the future. Co-authored-by: teor <teor@riseup.net> * Remove outdated comment Left-over from the attempt to move the eviction into the `VerifiedSet`. * Improve comment explaining lint removal Rewrite the comment explaining why the Clippy lint was ignored. * Check for spend conflicts in `VerifiedSet` Refactor to avoid API misuse. * Test rejected transaction rollback Using two transactions, perform the same test adding a conflict to both of them to check if the second inserted transaction is properly rejected. Then remove any conflicts from the second transaction and add it again. That should work, because if it doesn't it means that when the second transaction was rejected it left things it shouldn't in the cache. * Test removal of multiple transactions When removing multiple transactions from the mempool storage, all of the ones requested should be removed and any other transaction should be still be there afterwards. * Increase mempool size to 4, so that spend conflict tests work If the mempool size is smaller than 4, these tests don't fail on a trivial removal bug. Because we need a minimum number of transactions in the mempool to trigger the bug. Also commit a proptest seed that fails on a trivial removal bug. (This seed fails if we remove indexes in order, because every index past the first removes the wrong transaction.) * Summarise transaction data in proptest error output * Summarise spend conflict field data in proptest error output * Summarise multiple removal field data in proptest error output And replace the very large proptest debug output with the new summary. Co-authored-by: teor <teor@riseup.net>
2021-10-10 16:54:46 -07:00
impl fmt::Display for Transaction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut fmter = f.debug_struct("Transaction");
fmter.field("version", &self.version());
if let Some(network_upgrade) = self.network_upgrade() {
fmter.field("network_upgrade", &network_upgrade);
}
fmter.field("transparent_inputs", &self.inputs().len());
fmter.field("transparent_outputs", &self.outputs().len());
fmter.field("sprout_joinsplits", &self.joinsplit_count());
fmter.field("sapling_spends", &self.sapling_spends_per_anchor().count());
fmter.field("sapling_outputs", &self.sapling_outputs().count());
fmter.field("orchard_actions", &self.orchard_actions().count());
fmter.field("unmined_id", &self.unmined_id());
fmter.finish()
}
}
impl Transaction {
// identifiers and hashes
/// Compute the hash (mined transaction ID) of this transaction.
///
/// The hash uniquely identifies mined v5 transactions,
/// and all v1-v4 transactions, whether mined or unmined.
pub fn hash(&self) -> Hash {
Hash::from(self)
}
/// Compute the unmined transaction ID of this transaction.
///
/// This ID uniquely identifies unmined transactions,
/// regardless of version.
pub fn unmined_id(&self) -> UnminedTxId {
UnminedTxId::from(self)
}
/// Calculate the sighash for the current transaction
///
/// # Details
///
/// The `input` argument indicates the transparent Input for which we are
/// producing a sighash. It is comprised of the index identifying the
/// transparent::Input within the transaction and the transparent::Output
/// representing the UTXO being spent by that input.
///
/// # Panics
///
/// - if passed in any NetworkUpgrade from before NetworkUpgrade::Overwinter
/// - if called on a v1 or v2 transaction
/// - if the input index points to a transparent::Input::CoinBase
/// - if the input index is out of bounds for self.inputs()
pub fn sighash(
&self,
network_upgrade: NetworkUpgrade,
hash_type: sighash::HashType,
input: Option<(u32, transparent::Output)>,
) -> SigHash {
sighash::SigHasher::new(self, hash_type, network_upgrade, input).sighash()
}
/// Compute the authorizing data commitment of this transaction as specified
/// in [ZIP-244].
///
/// Returns None for pre-v5 transactions.
///
/// [ZIP-244]: https://zips.z.cash/zip-0244.
pub fn auth_digest(&self) -> Option<AuthDigest> {
match self {
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 { .. } => None,
Transaction::V5 { .. } => Some(AuthDigest::from(self)),
}
}
// other properties
/// Does this transaction have transparent or shielded inputs?
///
/// "[Sapling onward] If effectiveVersion < 5, then at least one of tx_in_count,
/// nSpendsSapling, and nJoinSplit MUST be nonzero.
///
/// [NU5 onward] If effectiveVersion ≥ 5 then this condition MUST hold:
/// tx_in_count > 0 or nSpendsSapling > 0 or (nActionsOrchard > 0 and enableSpendsOrchard = 1)."
///
/// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
pub fn has_transparent_or_shielded_inputs(&self) -> bool {
!self.inputs().is_empty() || self.has_shielded_inputs()
}
/// Does this transaction have shielded inputs?
///
/// See [`has_transparent_or_shielded_inputs`] for details.
pub fn has_shielded_inputs(&self) -> bool {
self.joinsplit_count() > 0
|| self.sapling_spends_per_anchor().count() > 0
|| (self.orchard_actions().count() > 0
&& self
.orchard_flags()
.unwrap_or_else(orchard::Flags::empty)
.contains(orchard::Flags::ENABLE_SPENDS))
}
/// Does this transaction have transparent or shielded outputs?
///
/// "[Sapling onward] If effectiveVersion < 5, then at least one of tx_out_count,
/// nOutputsSapling, and nJoinSplit MUST be nonzero.
///
/// [NU5 onward] If effectiveVersion ≥ 5 then this condition MUST hold:
/// tx_out_count > 0 or nOutputsSapling > 0 or (nActionsOrchard > 0 and enableOutputsOrchard = 1)."
///
/// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
pub fn has_transparent_or_shielded_outputs(&self) -> bool {
!self.outputs().is_empty() || self.has_shielded_outputs()
}
/// Does this transaction have shielded outputs?
///
/// See [`has_transparent_or_shielded_outputs`] for details.
pub fn has_shielded_outputs(&self) -> bool {
self.joinsplit_count() > 0
|| self.sapling_outputs().count() > 0
|| (self.orchard_actions().count() > 0
&& self
.orchard_flags()
.unwrap_or_else(orchard::Flags::empty)
.contains(orchard::Flags::ENABLE_OUTPUTS))
}
2021-11-08 13:45:54 -08:00
/// Does this transaction has at least one flag when we have at least one orchard action?
///
/// [NU5 onward] If effectiveVersion >= 5 and nActionsOrchard > 0, then at least one
/// of enableSpendsOrchard and enableOutputsOrchard MUST be 1.
///
/// https://zips.z.cash/protocol/protocol.pdf#txnconsensus
pub fn has_enough_orchard_flags(&self) -> bool {
if self.version() < 5 || self.orchard_actions().count() == 0 {
return true;
}
self.orchard_flags()
.unwrap_or_else(orchard::Flags::empty)
.intersects(orchard::Flags::ENABLE_SPENDS | orchard::Flags::ENABLE_OUTPUTS)
}
/// Returns the [`CoinbaseSpendRestriction`] for this transaction,
/// assuming it is mined at `spend_height`.
pub fn coinbase_spend_restriction(
&self,
spend_height: block::Height,
) -> CoinbaseSpendRestriction {
if self.outputs().is_empty() {
// we know this transaction must have shielded outputs,
// because of other consensus rules
OnlyShieldedOutputs { spend_height }
} else {
SomeTransparentOutputs
}
}
// header
Reject V5 transactions before NU5 activation (#2285) * 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>
2021-06-14 17:15:59 -07:00
/// Return if the `fOverwintered` flag of this transaction is set.
pub fn is_overwintered(&self) -> bool {
match self {
Transaction::V1 { .. } | Transaction::V2 { .. } => false,
Transaction::V3 { .. } | Transaction::V4 { .. } | Transaction::V5 { .. } => true,
}
}
/// Return the version of this transaction.
pub fn version(&self) -> u32 {
match self {
Transaction::V1 { .. } => 1,
Transaction::V2 { .. } => 2,
Transaction::V3 { .. } => 3,
Transaction::V4 { .. } => 4,
Transaction::V5 { .. } => 5,
}
}
/// Get this transaction's lock time.
Validate transaction lock times (#3060) * Create a `LockTime::unlocked` helper constructor Returns a `LockTime` that is unlocked at the genesis block. * Return `Option<LockTime>` from `lock_time` method Prepare to return `None` for when a transaction has its lock time disabled. * Return `None` instead of zero `LockTime` Because a zero lock time means that the transaction was unlocked at the genesis block, so it was never actually locked. * Rephrase zero lock time check comment Clarify that the check is not redundant, and is necessary for the genesis transaction. Co-authored-by: teor <teor@riseup.net> * Add a `transparent::Input::sequence` getter method Retrieve a transparent input's sequence number. * Check if lock time is enabled by a sequence number Validate the consensus rule that the lock time is only enabled if at least one transparent input has a value different from `u32::MAX` as its sequence number. * Add more Zcash specific details to comment Explain the Zcash specific lock time behaviors. Co-authored-by: teor <teor@riseup.net> * Add `time` field to `Request::Block` variant The block time to use to check if the transaction was unlocked and allowed to be included in the block. * Add `Request::block_time` getter Returns the block time for the block that owns the transaction being validated or the current time plus a tolerance for mempool transactions. * Validate transaction lock times If they are enabled by a transaction's transparent input sequence numbers, make sure that they are in the past. * Add comments with consensus rule parts Make it easier to map what part of the consensus rule each match arm is responsible for. Co-authored-by: teor <teor@riseup.net>
2021-11-22 21:53:53 -08:00
pub fn lock_time(&self) -> Option<LockTime> {
let lock_time = match self {
Transaction::V1 { lock_time, .. }
| Transaction::V2 { lock_time, .. }
| Transaction::V3 { lock_time, .. }
| Transaction::V4 { lock_time, .. }
| Transaction::V5 { lock_time, .. } => *lock_time,
};
// `zcashd` checks that the block height is greater than the lock height.
// This check allows the genesis block transaction, which would otherwise be invalid.
// (Or have to use a lock time.)
//
// It matches the `zcashd` check here:
// https://github.com/zcash/zcash/blob/1a7c2a3b04bcad6549be6d571bfdff8af9a2c814/src/main.cpp#L720
if lock_time == LockTime::unlocked() {
return None;
}
// Consensus rule:
//
// > The transaction must be finalized: either its locktime must be in the past (or less
// > than or equal to the current block height), or all of its sequence numbers must be
// > 0xffffffff.
//
// In `zcashd`, this rule applies to both coinbase and prevout input sequence numbers.
//
// Unlike Bitcoin, Zcash allows transactions with no transparent inputs. These transactions
// only have shielded inputs. Surprisingly, the `zcashd` implementation ignores the lock
// time in these transactions. `zcashd` only checks the lock time when it finds a
// transparent input sequence number that is not `u32::MAX`.
//
// https://developer.bitcoin.org/devguide/transactions.html#non-standard-transactions
let has_sequence_number_enabling_lock_time = self
.inputs()
.iter()
.map(transparent::Input::sequence)
.any(|sequence_number| sequence_number != u32::MAX);
if has_sequence_number_enabling_lock_time {
Some(lock_time)
} else {
None
}
}
/// Get this transaction's expiry height, if any.
pub fn expiry_height(&self) -> Option<block::Height> {
match self {
Transaction::V1 { .. } | Transaction::V2 { .. } => None,
Transaction::V3 { expiry_height, .. }
| Transaction::V4 { expiry_height, .. }
| Transaction::V5 { expiry_height, .. } => match expiry_height {
// Consensus rule:
// > No limit: To set no limit on transactions (so that they do not expire), nExpiryHeight should be set to 0.
// https://zips.z.cash/zip-0203#specification
block::Height(0) => None,
block::Height(expiry_height) => Some(block::Height(*expiry_height)),
},
}
}
/// Modify the expiry height of this transaction.
///
/// # Panics
///
/// - if called on a v1 or v2 transaction
#[cfg(any(test, feature = "proptest-impl"))]
pub fn expiry_height_mut(&mut self) -> &mut block::Height {
match self {
Transaction::V1 { .. } | Transaction::V2 { .. } => {
panic!("v1 and v2 transactions are not supported")
}
Transaction::V3 {
ref mut expiry_height,
..
}
| Transaction::V4 {
ref mut expiry_height,
..
}
| Transaction::V5 {
ref mut expiry_height,
..
} => expiry_height,
}
}
/// Get this transaction's network upgrade field, if any.
/// This field is serialized as `nConsensusBranchId` ([7.1]).
///
/// [7.1]: https://zips.z.cash/protocol/nu5.pdf#txnencodingandconsensus
pub fn network_upgrade(&self) -> Option<NetworkUpgrade> {
match self {
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 { .. } => None,
Transaction::V5 {
network_upgrade, ..
} => Some(*network_upgrade),
}
}
// transparent
/// Access the transparent inputs of this transaction, regardless of version.
pub fn inputs(&self) -> &[transparent::Input] {
match self {
Transaction::V1 { ref inputs, .. } => inputs,
Transaction::V2 { ref inputs, .. } => inputs,
Transaction::V3 { ref inputs, .. } => inputs,
Transaction::V4 { ref inputs, .. } => inputs,
Transaction::V5 { ref inputs, .. } => inputs,
}
}
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
/// Modify the transparent inputs of this transaction, regardless of version.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn inputs_mut(&mut self) -> &mut Vec<transparent::Input> {
match self {
Transaction::V1 { ref mut inputs, .. } => inputs,
Transaction::V2 { ref mut inputs, .. } => inputs,
Transaction::V3 { ref mut inputs, .. } => inputs,
Transaction::V4 { ref mut inputs, .. } => inputs,
Transaction::V5 { ref mut inputs, .. } => inputs,
}
}
Reject conflicting mempool transactions (#2765) * Add `Transaction::spent_outpoints` getter method Returns an iterator over the UTXO `OutPoint`s spent by the transaction. * Add `mempool::Error::Conflict` variant An error representing that a transaction was rejected because it conflicts with another transaction that's already in the mempool. * Reject conflicting mempool transactions Reject including a transaction in the mempool if it spends outputs already spent by, or reveals nullifiers already revealed by another transaction in the mempool. * Fix typo in documentation Remove the `r` that was incorrectly added. Co-authored-by: teor <teor@riseup.net> * Specify that the conflict is a spend conflict Make the situation clearer, because there are other types of conflict. Co-authored-by: teor <teor@riseup.net> * Clarify that the outpoints are from inputs Because otherwise it could lead to confusion because it could also mean the outputs of the transaction represented as `OutPoint` references. Co-authored-by: teor <teor@riseup.net> * Create `storage::tests::vectors` module Refactor to follow the convention used for other tests. * Add an `AtLeastOne::first_mut` method A getter to allow changing the first element. * Add an `AtLeastOne::push` method Allow appending elements to the collection. * Derive `Arbitrary` for `FieldNotPresent` This is just to make the code that generates arbitrary anchors a bit simpler. * Test if conflicting transactions are rejected Generate two transactions (either V4 or V5) and insert a conflicting spend, which can be either a transparent UTXO, or a nullifier for one of the shielded pools. Check that any attempt to insert both transactions causes one to be accepted and the other to be rejected. * Delete a TODO comment that we decided not to do Co-authored-by: teor <teor@riseup.net>
2021-09-27 18:03:08 -07:00
/// Access the [`transparent::OutPoint`]s spent by this transaction's [`transparent::Input`]s.
pub fn spent_outpoints(&self) -> impl Iterator<Item = transparent::OutPoint> + '_ {
self.inputs()
.iter()
.filter_map(transparent::Input::outpoint)
}
/// Access the transparent outputs of this transaction, regardless of version.
pub fn outputs(&self) -> &[transparent::Output] {
match self {
Transaction::V1 { ref outputs, .. } => outputs,
Transaction::V2 { ref outputs, .. } => outputs,
Transaction::V3 { ref outputs, .. } => outputs,
Transaction::V4 { ref outputs, .. } => outputs,
Transaction::V5 { ref outputs, .. } => outputs,
}
}
/// Modify the transparent outputs of this transaction, regardless of version.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn outputs_mut(&mut self) -> &mut Vec<transparent::Output> {
match self {
Transaction::V1 {
ref mut outputs, ..
} => outputs,
Transaction::V2 {
ref mut outputs, ..
} => outputs,
Transaction::V3 {
ref mut outputs, ..
} => outputs,
Transaction::V4 {
ref mut outputs, ..
} => outputs,
Transaction::V5 {
ref mut outputs, ..
} => outputs,
}
}
/// Returns `true` if this transaction has valid inputs for a coinbase
/// transaction, that is, has a single input and it is a coinbase input.
pub fn has_valid_coinbase_transaction_inputs(&self) -> bool {
self.inputs().len() == 1
&& matches!(
self.inputs().get(0),
Some(transparent::Input::Coinbase { .. })
)
}
/// Returns `true` if transaction contains any coinbase inputs.
pub fn has_any_coinbase_inputs(&self) -> bool {
self.inputs()
.iter()
.any(|input| matches!(input, transparent::Input::Coinbase { .. }))
}
/// Returns `true` if transaction contains any `PrevOut` inputs.
///
/// `PrevOut` inputs are also known as `transparent` inputs in the spec.
pub fn contains_prevout_input(&self) -> bool {
self.inputs()
.iter()
.any(|input| matches!(input, transparent::Input::PrevOut { .. }))
}
// sprout
/// Returns the number of `JoinSplit`s in this transaction, regardless of version.
pub fn joinsplit_count(&self) -> usize {
match self {
// JoinSplits with Bctv14 Proofs
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => joinsplit_data.joinsplits().count(),
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => joinsplit_data.joinsplits().count(),
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 {
joinsplit_data: None,
..
}
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => 0,
}
}
2020-10-23 15:29:52 -07:00
/// Access the sprout::Nullifiers in this transaction, regardless of version.
pub fn sprout_nullifiers(&self) -> Box<dyn Iterator<Item = &sprout::Nullifier> + '_> {
// This function returns a boxed iterator because the different
// transaction variants end up having different iterator types
// (we could extract bctv and groth as separate iterators, then chain
// them together, but that would be much harder to read and maintain)
2020-10-23 15:29:52 -07:00
match self {
// JoinSplits with Bctv14 Proofs
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(joinsplit_data.nullifiers()),
2020-10-23 15:29:52 -07:00
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(joinsplit_data.nullifiers()),
2020-10-23 15:29:52 -07:00
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 {
joinsplit_data: None,
..
}
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => Box::new(std::iter::empty()),
2020-10-23 15:29:52 -07:00
}
}
// sapling
/// Iterate over the sapling [`Spend`](sapling::Spend)s for this transaction,
/// returning `Spend<PerSpendAnchor>` regardless of the underlying
/// transaction version.
///
/// Shared anchors in V5 transactions are copied into each sapling spend.
/// This allows the same code to validate spends from V4 and V5 transactions.
///
/// # Correctness
///
/// Do not use this function for serialization.
pub fn sapling_spends_per_anchor(
&self,
) -> Box<dyn Iterator<Item = sapling::Spend<sapling::PerSpendAnchor>> + '_> {
match self {
Transaction::V4 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.spends_per_anchor()),
Transaction::V5 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.spends_per_anchor()),
// No Spends
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
}
| Transaction::V5 {
sapling_shielded_data: None,
..
} => Box::new(std::iter::empty()),
}
}
/// Iterate over the sapling [`Output`](sapling::Output)s for this
/// transaction
pub fn sapling_outputs(&self) -> Box<dyn Iterator<Item = &sapling::Output> + '_> {
match self {
Transaction::V4 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.outputs()),
Transaction::V5 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.outputs()),
// No Outputs
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
}
| Transaction::V5 {
sapling_shielded_data: None,
..
} => Box::new(std::iter::empty()),
}
}
2020-10-23 15:29:52 -07:00
/// Access the sapling::Nullifiers in this transaction, regardless of version.
pub fn sapling_nullifiers(&self) -> Box<dyn Iterator<Item = &sapling::Nullifier> + '_> {
// This function returns a boxed iterator because the different
// transaction variants end up having different iterator types
match self {
// Spends with Groth Proofs
2020-10-23 15:29:52 -07:00
Transaction::V4 {
sapling_shielded_data: Some(sapling_shielded_data),
2020-10-23 15:29:52 -07:00
..
} => Box::new(sapling_shielded_data.nullifiers()),
Transaction::V5 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.nullifiers()),
// No Spends
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
}
| Transaction::V5 {
sapling_shielded_data: None,
..
} => Box::new(std::iter::empty()),
2020-10-23 15:29:52 -07:00
}
}
Sprout note commitment trees (#3051) * Implement incremental note commitment Merkle tree for Sprout * Add tests for Sprout note commitment tree * Remove the `Arbitrary` attribute * Reverse the vector of empty roots * Add more tests * Refactor rustdoc Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> * Refactor rustdoc Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> * rustdoc * Rustdoc * rustdoc links * Oops, need the trait in scope to use it * Avoid accessing the wrapped hash directly Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> * rustfmt * Add typing * Avoid accessing the wrapped hash directly * Implement incremental note commitment Merkle tree for Sprout * Add tests for Sprout note commitment tree * Remove the `Arbitrary` attribute * Reverse the vector of empty roots * Add more tests * Refactor rustdoc Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> * Refactor rustdoc Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> * rustdoc * Rustdoc * rustdoc links * Oops, need the trait in scope to use it * Avoid accessing the wrapped hash directly Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> * rustfmt * Add typing * Avoid accessing the wrapped hash directly * Add Overwinter final roots (test vectors) * Test sprout note commitments trees on Overwinter blocks * Add new test vectors * Finish the tests for the note commitment trees * Make the wrapped hash in `Root` private Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
2021-11-18 15:05:52 -08:00
/// Returns the Sprout note commitments in this transaction.
pub fn sprout_note_commitments(
&self,
) -> Box<dyn Iterator<Item = &sprout::commitment::NoteCommitment> + '_> {
match self {
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(joinsplit_data.note_commitments()),
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 { .. }
| Transaction::V4 { .. }
| Transaction::V5 { .. } => Box::new(std::iter::empty()),
}
}
/// Returns the Sapling note commitments in this transaction, regardless of version.
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
pub fn sapling_note_commitments(&self) -> Box<dyn Iterator<Item = &jubjub::Fq> + '_> {
// This function returns a boxed iterator because the different
// transaction variants end up having different iterator types
match self {
// Spends with Groth16 Proofs
Transaction::V4 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.note_commitments()),
Transaction::V5 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Box::new(sapling_shielded_data.note_commitments()),
// No Spends
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
}
| Transaction::V5 {
sapling_shielded_data: None,
..
} => Box::new(std::iter::empty()),
}
}
/// Return if the transaction has any Sapling shielded data.
pub fn has_sapling_shielded_data(&self) -> bool {
match self {
Transaction::V1 { .. } | Transaction::V2 { .. } | Transaction::V3 { .. } => false,
Transaction::V4 {
sapling_shielded_data,
..
} => sapling_shielded_data.is_some(),
Transaction::V5 {
sapling_shielded_data,
..
} => sapling_shielded_data.is_some(),
}
}
// orchard
/// Access the [`orchard::ShieldedData`] in this transaction,
/// regardless of version.
pub fn orchard_shielded_data(&self) -> Option<&orchard::ShieldedData> {
match self {
// Maybe Orchard shielded data
Transaction::V5 {
orchard_shielded_data,
..
} => orchard_shielded_data.as_ref(),
// No Orchard shielded data
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 { .. } => None,
}
}
/// Modify the [`orchard::ShieldedData`] in this transaction,
/// regardless of version.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn orchard_shielded_data_mut(&mut self) -> Option<&mut orchard::ShieldedData> {
match self {
Transaction::V5 {
orchard_shielded_data: Some(orchard_shielded_data),
..
} => Some(orchard_shielded_data),
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 { .. }
| Transaction::V5 {
orchard_shielded_data: None,
..
} => None,
}
}
/// Iterate over the [`orchard::Action`]s in this transaction, if there are any,
/// regardless of version.
pub fn orchard_actions(&self) -> impl Iterator<Item = &orchard::Action> {
self.orchard_shielded_data()
.into_iter()
.map(orchard::ShieldedData::actions)
.flatten()
}
/// Access the [`orchard::Nullifier`]s in this transaction, if there are any,
/// regardless of version.
pub fn orchard_nullifiers(&self) -> impl Iterator<Item = &orchard::Nullifier> {
self.orchard_shielded_data()
.into_iter()
.map(orchard::ShieldedData::nullifiers)
.flatten()
}
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
/// Access the note commitments in this transaction, if there are any,
/// regardless of version.
pub fn orchard_note_commitments(&self) -> impl Iterator<Item = &pallas::Base> {
self.orchard_shielded_data()
.into_iter()
.map(orchard::ShieldedData::note_commitments)
.flatten()
}
/// Access the [`orchard::Flags`] in this transaction, if there is any,
/// regardless of version.
pub fn orchard_flags(&self) -> Option<orchard::shielded_data::Flags> {
self.orchard_shielded_data()
.map(|orchard_shielded_data| orchard_shielded_data.flags)
}
/// Return if the transaction has any Orchard shielded data,
/// regardless of version.
pub fn has_orchard_shielded_data(&self) -> bool {
self.orchard_shielded_data().is_some()
}
// value balances
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
/// Return the transparent value balance,
/// using the outputs spent by this transaction.
///
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
/// See `transparent_value_balance` for details.
fn transparent_value_balance_from_outputs(
&self,
outputs: &HashMap<transparent::OutPoint, transparent::Output>,
) -> Result<ValueBalance<NegativeAllowed>, ValueBalanceError> {
let input_value = self
.inputs()
.iter()
.map(|i| i.value_from_outputs(outputs))
.sum::<Result<Amount<NonNegative>, AmountError>>()
.map_err(ValueBalanceError::Transparent)?
.constrain()
.expect("conversion from NonNegative to NegativeAllowed is always valid");
let output_value = self
.outputs()
.iter()
.map(|o| o.value())
.sum::<Result<Amount<NonNegative>, AmountError>>()
.map_err(ValueBalanceError::Transparent)?
.constrain()
.expect("conversion from NonNegative to NegativeAllowed is always valid");
(input_value - output_value)
.map(ValueBalance::from_transparent_amount)
.map_err(ValueBalanceError::Transparent)
}
/// Return the transparent value balance,
/// the change in the value of the transaction value pool.
///
/// The sum of the UTXOs spent by transparent inputs in `tx_in` fields,
/// minus the sum of the newly created outputs in `tx_out` fields.
///
/// Positive values are added to this transaction's value pool,
/// and removed from the transparent chain value pool.
/// Negative values are removed from the transparent chain value pool,
/// and added to this transaction.
///
/// https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions
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
///
/// `utxos` must contain the utxos of every input in the transaction,
/// including UTXOs created by earlier transactions in this block.
#[allow(dead_code)]
fn transparent_value_balance(
&self,
utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
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
) -> Result<ValueBalance<NegativeAllowed>, ValueBalanceError> {
self.transparent_value_balance_from_outputs(&outputs_from_utxos(utxos.clone()))
}
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
/// Modify the transparent output values of this transaction, regardless of version.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn output_values_mut(&mut self) -> impl Iterator<Item = &mut Amount<NonNegative>> {
self.outputs_mut()
.iter_mut()
.map(|output| &mut output.value)
}
/// Returns the `vpub_old` fields from `JoinSplit`s in this transaction,
/// regardless of version.
///
/// These values are added to the sprout chain value pool,
/// and removed from the value pool of this transaction.
pub fn output_values_to_sprout(&self) -> Box<dyn Iterator<Item = &Amount<NonNegative>> + '_> {
match self {
// JoinSplits with Bctv14 Proofs
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits()
.map(|joinsplit| &joinsplit.vpub_old),
),
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits()
.map(|joinsplit| &joinsplit.vpub_old),
),
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 {
joinsplit_data: None,
..
}
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => Box::new(std::iter::empty()),
}
}
/// Modify the `vpub_old` fields from `JoinSplit`s in this transaction,
/// regardless of version.
///
/// See `output_values_to_sprout` for details.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn output_values_to_sprout_mut(
&mut self,
) -> Box<dyn Iterator<Item = &mut Amount<NonNegative>> + '_> {
match self {
// JoinSplits with Bctv14 Proofs
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits_mut()
.map(|joinsplit| &mut joinsplit.vpub_old),
),
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits_mut()
.map(|joinsplit| &mut joinsplit.vpub_old),
),
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 {
joinsplit_data: None,
..
}
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => Box::new(std::iter::empty()),
}
}
/// Returns the `vpub_new` fields from `JoinSplit`s in this transaction,
/// regardless of version.
///
/// These values are removed from the value pool of this transaction.
/// and added to the sprout chain value pool.
pub fn input_values_from_sprout(&self) -> Box<dyn Iterator<Item = &Amount<NonNegative>> + '_> {
match self {
// JoinSplits with Bctv14 Proofs
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits()
.map(|joinsplit| &joinsplit.vpub_new),
),
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits()
.map(|joinsplit| &joinsplit.vpub_new),
),
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 {
joinsplit_data: None,
..
}
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => Box::new(std::iter::empty()),
}
}
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
/// Modify the `vpub_new` fields from `JoinSplit`s in this transaction,
/// regardless of version.
///
/// See `input_values_from_sprout` for details.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn input_values_from_sprout_mut(
&mut self,
) -> Box<dyn Iterator<Item = &mut Amount<NonNegative>> + '_> {
match self {
// JoinSplits with Bctv14 Proofs
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits_mut()
.map(|joinsplit| &mut joinsplit.vpub_new),
),
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits_mut()
.map(|joinsplit| &mut joinsplit.vpub_new),
),
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
| Transaction::V3 {
joinsplit_data: None,
..
}
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => Box::new(std::iter::empty()),
}
}
/// Return a list of sprout value balances,
/// the changes in the transaction value pool due to each sprout [`JoinSplit`].
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
///
/// Each value balance is the sprout `vpub_new` field, minus the `vpub_old` field.
///
/// See `sprout_value_balance` for details.
fn sprout_joinsplit_value_balances(
&self,
) -> impl Iterator<Item = ValueBalance<NegativeAllowed>> + '_ {
let joinsplit_value_balances = match self {
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
Transaction::V2 {
joinsplit_data: Some(joinsplit_data),
..
}
| Transaction::V3 {
joinsplit_data: Some(joinsplit_data),
..
} => joinsplit_data.joinsplit_value_balances(),
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
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => joinsplit_data.joinsplit_value_balances(),
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
Transaction::V1 { .. }
| Transaction::V2 {
joinsplit_data: None,
..
}
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
| Transaction::V3 {
joinsplit_data: None,
..
}
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
| Transaction::V4 {
joinsplit_data: None,
..
}
| Transaction::V5 { .. } => Box::new(iter::empty()),
};
joinsplit_value_balances.map(ValueBalance::from_sprout_amount)
}
/// Return the sprout value balance,
/// the change in the transaction value pool due to sprout [`JoinSplit`]s.
///
/// The sum of all sprout `vpub_new` fields, minus the sum of all `vpub_old` fields.
///
/// Positive values are added to this transaction's value pool,
/// and removed from the sprout chain value pool.
/// Negative values are removed from this transaction,
/// and added to the sprout pool.
///
/// https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions
fn sprout_value_balance(&self) -> Result<ValueBalance<NegativeAllowed>, ValueBalanceError> {
self.sprout_joinsplit_value_balances().sum()
}
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
/// Return the sapling value balance,
/// the change in the transaction value pool due to sapling `Spend`s and `Output`s.
///
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
/// Returns the `valueBalanceSapling` field in this transaction.
///
/// Positive values are added to this transaction's value pool,
/// and removed from the sapling chain value pool.
/// Negative values are removed from this transaction,
/// and added to sapling pool.
///
/// https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions
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
fn sapling_value_balance(&self) -> ValueBalance<NegativeAllowed> {
let sapling_value_balance = match self {
Transaction::V4 {
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
sapling_shielded_data: Some(sapling_shielded_data),
..
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
} => sapling_shielded_data.value_balance,
Transaction::V5 {
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
sapling_shielded_data: Some(sapling_shielded_data),
..
} => sapling_shielded_data.value_balance,
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
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
}
| Transaction::V5 {
sapling_shielded_data: None,
..
} => Amount::zero(),
};
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
ValueBalance::from_sapling_amount(sapling_value_balance)
}
/// Modify the `value_balance` field from the `sapling::ShieldedData` in this transaction,
/// regardless of version.
///
/// See `sapling_value_balance` for details.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn sapling_value_balance_mut(&mut self) -> Option<&mut Amount<NegativeAllowed>> {
match self {
Transaction::V4 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Some(&mut sapling_shielded_data.value_balance),
Transaction::V5 {
sapling_shielded_data: Some(sapling_shielded_data),
..
} => Some(&mut sapling_shielded_data.value_balance),
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
}
| Transaction::V5 {
sapling_shielded_data: None,
..
} => None,
}
}
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
/// Return the orchard value balance,
/// the change in the transaction value pool due to orchard [`Action`]s.
///
/// Returns the `valueBalanceOrchard` field in this transaction.
///
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
/// Positive values are added to this transaction's value pool,
/// and removed from the orchard chain value pool.
/// Negative values are removed from this transaction,
/// and added to orchard pool.
///
/// https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions
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
fn orchard_value_balance(&self) -> ValueBalance<NegativeAllowed> {
let orchard_value_balance = self
.orchard_shielded_data()
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
.map(|shielded_data| shielded_data.value_balance)
.unwrap_or_else(Amount::zero);
ValueBalance::from_orchard_amount(orchard_value_balance)
}
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
/// Modify the `value_balance` field from the `orchard::ShieldedData` in this transaction,
/// regardless of version.
///
/// See `orchard_value_balance` for details.
#[cfg(any(test, feature = "proptest-impl"))]
pub fn orchard_value_balance_mut(&mut self) -> Option<&mut Amount<NegativeAllowed>> {
self.orchard_shielded_data_mut()
.map(|shielded_data| &mut shielded_data.value_balance)
}
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
/// Get the value balances for this transaction,
/// using the transparent outputs spent in this transaction.
///
/// See `value_balance` for details.
pub(crate) fn value_balance_from_outputs(
&self,
outputs: &HashMap<transparent::OutPoint, transparent::Output>,
) -> Result<ValueBalance<NegativeAllowed>, ValueBalanceError> {
self.transparent_value_balance_from_outputs(outputs)?
+ self.sprout_value_balance()?
+ self.sapling_value_balance()
+ self.orchard_value_balance()
}
/// Get the value balances for this transaction.
/// These are the changes in the transaction value pool,
/// split up into transparent, sprout, sapling, and orchard values.
///
/// Calculated as the sum of the inputs and outputs from each pool,
/// or the sum of the value balances from each pool.
///
/// Positive values are added to this transaction's value pool,
/// and removed from the corresponding chain value pool.
/// Negative values are removed from this transaction,
/// and added to the corresponding pool.
///
/// https://zebra.zfnd.org/dev/rfcs/0012-value-pools.html#definitions
///
/// `utxos` must contain the utxos of every input in the transaction,
/// including UTXOs created by earlier transactions in this block.
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
///
/// Note: the chain value pool has the opposite sign to the transaction
/// value pool.
pub fn value_balance(
&self,
utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
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
) -> Result<ValueBalance<NegativeAllowed>, ValueBalanceError> {
self.value_balance_from_outputs(&outputs_from_utxos(utxos.clone()))
}
}