zebra/zebra-chain/src/transaction.rs

1154 lines
41 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};
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},
};
use std::{collections::HashMap, 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>,
},
}
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))
}
/// 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.
pub fn lock_time(&self) -> LockTime {
match self {
Transaction::V1 { lock_time, .. } => *lock_time,
Transaction::V2 { lock_time, .. } => *lock_time,
Transaction::V3 { lock_time, .. } => *lock_time,
Transaction::V4 { lock_time, .. } => *lock_time,
Transaction::V5 { lock_time, .. } => *lock_time,
}
}
/// Get this transaction's expiry height, if any.
pub fn expiry_height(&self) -> Option<block::Height> {
match self {
Transaction::V1 { .. } => None,
Transaction::V2 { .. } => None,
Transaction::V3 { expiry_height, .. } => Some(*expiry_height),
Transaction::V4 { expiry_height, .. } => Some(*expiry_height),
Transaction::V5 { expiry_height, .. } => Some(*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,
}
}
/// 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
}
}
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, regardless of version.
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()))
}
}