zebra/zebra-chain/src/transaction.rs

278 lines
10 KiB
Rust
Raw Normal View History

2020-08-15 21:55:28 -07:00
//! Transactions and transaction-related structures.
use serde::{Deserialize, Serialize};
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;
#[cfg(any(test, feature = "proptest-impl"))]
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 hash::Hash;
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;
2020-09-25 16:26:39 -07:00
pub use sighash::HashType;
use crate::{
block,
parameters::NetworkUpgrade,
primitives::{Bctv14Proof, Groth16Proof},
2020-10-23 15:29:52 -07:00
sapling, sprout, transparent,
};
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 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 rest of the transaction as bytes
rest: Vec<u8>,
},
}
impl Transaction {
/// Compute the hash of this transaction.
pub fn hash(&self) -> Hash {
Hash::from(self)
}
/// 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,
}
}
/// 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,
}
}
/// 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),
}
}
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
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()
.flat_map(|joinsplit| joinsplit.nullifiers.iter()),
),
// JoinSplits with Groth Proofs
Transaction::V4 {
joinsplit_data: Some(joinsplit_data),
..
} => Box::new(
joinsplit_data
.joinsplits()
.flat_map(|joinsplit| joinsplit.nullifiers.iter()),
),
// Maybe JoinSplits, maybe not, we're still deciding
Transaction::V5 { .. } => {
unimplemented!(
"v5 transaction format as specified in ZIP-225 after decision on 2021-03-12"
)
}
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,
..
} => 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 {
// JoinSplits with Groth Proofs
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 { .. } => {
unimplemented!("v5 transaction format as specified in ZIP-225")
}
2020-10-23 15:29:52 -07:00
// No JoinSplits
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
| Transaction::V4 {
sapling_shielded_data: None,
..
} => Box::new(std::iter::empty()),
2020-10-23 15:29:52 -07:00
}
}
/// Returns `true` if transaction contains any coinbase inputs.
pub fn contains_coinbase_input(&self) -> bool {
self.inputs()
.iter()
.any(|input| matches!(input, transparent::Input::Coinbase { .. }))
}
/// Returns `true` if this transaction is a coinbase transaction.
pub fn is_coinbase(&self) -> bool {
self.inputs().len() == 1
&& matches!(
self.inputs().get(0),
Some(transparent::Input::Coinbase { .. })
)
}
/// 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)>,
) -> blake2b_simd::Hash {
sighash::SigHasher::new(self, hash_type, network_upgrade, input).sighash()
}
}