Create per-protocol fees modules.

This commit is contained in:
Kris Nuttycombe 2022-11-03 15:07:14 -06:00
parent c92d81b15d
commit 9c894ebf3e
12 changed files with 151 additions and 89 deletions

View File

@ -3,8 +3,8 @@ use zcash_primitives::{
transaction::{
components::{
amount::{Amount, BalanceError},
sapling::builder::{SaplingInput, SaplingOutput},
transparent::{builder::TransparentInput, TxOut},
sapling::fees as sapling,
transparent::fees as transparent,
},
fees::{FeeRule, FixedFeeRule},
},
@ -79,10 +79,10 @@ pub trait ChangeStrategy {
&self,
params: &P,
target_height: BlockHeight,
transparent_inputs: &[impl TransparentInput],
transparent_outputs: &[TxOut],
sapling_inputs: &[impl SaplingInput],
sapling_outputs: &[impl SaplingOutput],
transparent_inputs: &[impl transparent::InputView],
transparent_outputs: &[impl transparent::OutputView],
sapling_inputs: &[impl sapling::InputView],
sapling_outputs: &[impl sapling::OutputView],
) -> Result<TransactionBalance, ChangeError<Self::Error>>;
}
@ -112,10 +112,10 @@ impl ChangeStrategy for BasicFixedFeeChangeStrategy {
&self,
_params: &P,
_target_height: BlockHeight,
transparent_inputs: &[impl TransparentInput],
transparent_outputs: &[TxOut],
sapling_inputs: &[impl SaplingInput],
sapling_outputs: &[impl SaplingOutput],
transparent_inputs: &[impl transparent::InputView],
transparent_outputs: &[impl transparent::OutputView],
sapling_inputs: &[impl sapling::InputView],
sapling_outputs: &[impl sapling::OutputView],
) -> Result<TransactionBalance, ChangeError<Self::Error>> {
let overflow = || ChangeError::StrategyError(BalanceError::Overflow);
let underflow = || ChangeError::StrategyError(BalanceError::Underflow);
@ -127,7 +127,7 @@ impl ChangeStrategy for BasicFixedFeeChangeStrategy {
.ok_or_else(overflow)?;
let t_out = transparent_outputs
.iter()
.map(|t_out| t_out.value)
.map(|t_out| t_out.value())
.sum::<Option<_>>()
.ok_or_else(overflow)?;
let sapling_in = sapling_inputs

View File

@ -23,21 +23,21 @@ use crate::{
amount::Amount,
sapling::{
self,
builder::{SaplingBuilder, SaplingInput, SaplingMetadata, SaplingOutput},
},
transparent::{
self,
builder::{TransparentBuilder, TransparentInput},
builder::{SaplingBuilder, SaplingMetadata},
},
transparent::{self, builder::TransparentBuilder},
},
fees::FeeRule,
sighash::{signature_hash, SignableInput},
txid::TxIdDigester,
Transaction, TransactionData, TxOut, TxVersion, Unauthorized,
Transaction, TransactionData, TxVersion, Unauthorized,
},
zip32::ExtendedSpendingKey,
};
#[cfg(feature = "transparent-inputs")]
use crate::transaction::components::transparent::TxOut;
#[cfg(feature = "zfuture")]
use crate::{
extensions::transparent::{ExtensionTxBuilder, ToPayload},
@ -159,25 +159,25 @@ impl<'a, P, R> Builder<'a, P, R> {
/// Returns the set of transparent inputs currently committed to be consumed
/// by the transaction.
pub fn transparent_inputs(&self) -> &[impl TransparentInput] {
pub fn transparent_inputs(&self) -> &[impl transparent::fees::InputView] {
self.transparent_builder.inputs()
}
/// Returns the set of transparent outputs currently set to be produced by
/// the transaction.
pub fn transparent_outputs(&self) -> &[TxOut] {
pub fn transparent_outputs(&self) -> &[impl transparent::fees::OutputView] {
self.transparent_builder.outputs()
}
/// Returns the set of Sapling inputs currently committed to be consumed
/// by the transaction.
pub fn sapling_inputs(&self) -> &[impl SaplingInput] {
pub fn sapling_inputs(&self) -> &[impl sapling::fees::InputView] {
self.sapling_builder.inputs()
}
/// Returns the set of Sapling outputs currently set to be produced by
/// the transaction.
pub fn sapling_outputs(&self) -> &[impl SaplingOutput] {
pub fn sapling_outputs(&self) -> &[impl sapling::fees::OutputView] {
self.sapling_builder.outputs()
}
}

View File

@ -24,6 +24,7 @@ use super::{amount::Amount, GROTH_PROOF_SIZE};
pub type GrothProofBytes = [u8; GROTH_PROOF_SIZE];
pub mod builder;
pub mod fees;
pub trait Authorization: Debug {
type Proof: Clone + Debug;

View File

@ -25,7 +25,7 @@ use crate::{
components::{
amount::Amount,
sapling::{
Authorization, Authorized, Bundle, GrothProofBytes, OutputDescription,
fees, Authorization, Authorized, Bundle, GrothProofBytes, OutputDescription,
SpendDescription,
},
},
@ -60,20 +60,6 @@ impl fmt::Display for Error {
}
}
/// A trait that provides a minimized view of a Sapling input suitable for use in
/// fee and change calculation.
pub trait SaplingInput {
/// The value of the input being spent.
fn value(&self) -> Amount;
}
/// A trait that provides a minimized view of a Sapling output suitable for use in
/// fee and change calculation.
pub trait SaplingOutput {
/// The value of the output being produced.
fn value(&self) -> Amount;
}
#[derive(Debug, Clone)]
pub struct SpendDescriptionInfo {
extsk: ExtendedSpendingKey,
@ -83,7 +69,7 @@ pub struct SpendDescriptionInfo {
merkle_path: MerklePath<Node>,
}
impl SaplingInput for SpendDescriptionInfo {
impl fees::InputView for SpendDescriptionInfo {
fn value(&self) -> Amount {
// An existing note to be spent must have a valid
// amount value.
@ -174,7 +160,7 @@ impl SaplingOutputInfo {
}
}
impl SaplingOutput for SaplingOutputInfo {
impl fees::OutputView for SaplingOutputInfo {
fn value(&self) -> Amount {
Amount::from_u64(self.note.value).expect("Note values should be checked at construction.")
}
@ -257,12 +243,12 @@ impl<P> SaplingBuilder<P> {
/// Returns the list of Sapling inputs that will be consumed by the transaction being
/// constructed.
pub fn inputs(&self) -> &[impl SaplingInput] {
pub fn inputs(&self) -> &[impl fees::InputView] {
&self.spends
}
/// Returns the Sapling outputs that will be produced by the transaction being constructed
pub fn outputs(&self) -> &[impl SaplingOutput] {
pub fn outputs(&self) -> &[impl fees::OutputView] {
&self.outputs
}

View File

@ -0,0 +1,18 @@
//! Types related to computation of fees and change related to the Sapling components
//! of a transaction.
use crate::transaction::components::amount::Amount;
/// A trait that provides a minimized view of a Sapling input suitable for use in
/// fee and change calculation.
pub trait InputView {
/// The value of the input being spent.
fn value(&self) -> Amount;
}
/// A trait that provides a minimized view of a Sapling output suitable for use in
/// fee and change calculation.
pub trait OutputView {
/// The value of the output being produced.
fn value(&self) -> Amount;
}

View File

@ -10,6 +10,7 @@ use crate::legacy::{Script, TransparentAddress};
use super::amount::{Amount, BalanceError};
pub mod builder;
pub mod fees;
pub trait Authorization: Debug {
type ScriptSig: Debug + Clone + PartialEq;

View File

@ -7,7 +7,7 @@ use crate::{
transaction::{
components::{
amount::Amount,
transparent::{self, Authorization, Authorized, Bundle, TxIn, TxOut},
transparent::{self, fees, Authorization, Authorized, Bundle, TxIn, TxOut},
},
sighash::TransparentAuthorizingContext,
OutPoint,
@ -40,22 +40,13 @@ impl fmt::Display for Error {
}
}
/// This trait provides a minimized view of a transparent input suitable for use in
/// fee computation.
pub trait TransparentInput {
/// The outpoint to which the input refers.
fn outpoint(&self) -> &OutPoint;
/// The previous output being spent.
fn coin(&self) -> &TxOut;
}
/// An uninhabited type that allows the type of [`TransparentBuilder::inputs`]
/// to resolve when the transparent-inputs feature is not turned on.
#[cfg(not(feature = "transparent-inputs"))]
enum InvalidTransparentInput {}
#[cfg(not(feature = "transparent-inputs"))]
impl TransparentInput for InvalidTransparentInput {
impl fees::InputView for InvalidTransparentInput {
fn outpoint(&self) -> &OutPoint {
panic!("transparent-inputs feature flag is not enabled.");
}
@ -74,7 +65,7 @@ struct TransparentInputInfo {
}
#[cfg(feature = "transparent-inputs")]
impl TransparentInput for TransparentInputInfo {
impl fees::InputView for TransparentInputInfo {
fn outpoint(&self) -> &OutPoint {
&self.utxo
}
@ -118,7 +109,7 @@ impl TransparentBuilder {
/// Returns the list of transparent inputs that will be consumed by the transaction being
/// constructed.
pub fn inputs(&self) -> &[impl TransparentInput] {
pub fn inputs(&self) -> &[impl fees::InputView] {
#[cfg(feature = "transparent-inputs")]
return &self.inputs;
@ -130,7 +121,7 @@ impl TransparentBuilder {
}
/// Returns the transparent outputs that will be produced by the transaction being constructed.
pub fn outputs(&self) -> &[TxOut] {
pub fn outputs(&self) -> &[impl fees::OutputView] {
&self.vout
}

View File

@ -0,0 +1,36 @@
//! Types related to computation of fees and change related to the transparent components
//! of a transaction.
use super::TxOut;
use crate::{
legacy::Script,
transaction::{components::amount::Amount, OutPoint},
};
/// This trait provides a minimized view of a transparent input suitable for use in
/// fee and change computation.
pub trait InputView {
/// The outpoint to which the input refers.
fn outpoint(&self) -> &OutPoint;
/// The previous output being spent.
fn coin(&self) -> &TxOut;
}
/// This trait provides a minimized view of a transparent output suitable for use in
/// fee and change computation.
pub trait OutputView {
/// Returns the value of the output being created.
fn value(&self) -> Amount;
/// Returns the script corresponding to the newly created output.
fn script_pubkey(&self) -> &Script;
}
impl OutputView for TxOut {
fn value(&self) -> Amount {
self.value
}
fn script_pubkey(&self) -> &Script {
&self.script_pubkey
}
}

View File

@ -12,6 +12,7 @@ use super::amount::Amount;
use crate::{extensions::transparent as tze, transaction::TxId};
pub mod builder;
pub mod fees;
fn to_io_error(_: std::num::TryFromIntError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidData, "value out of range")

View File

@ -9,7 +9,7 @@ use crate::{
self as tx,
components::{
amount::Amount,
tze::{Authorization, Authorized, Bundle, OutPoint, TzeIn, TzeOut},
tze::{fees, Authorization, Authorized, Bundle, OutPoint, TzeIn, TzeOut},
},
},
};
@ -35,20 +35,13 @@ pub struct TzeSigner<'a, BuildCtx> {
builder: Box<dyn FnOnce(&BuildCtx) -> Result<(u32, Vec<u8>), Error> + 'a>,
}
/// This trait provides a minimized view of a TZE input suitable for use in
/// fee computation.
pub trait TzeInput {
fn outpoint(&self) -> &OutPoint;
fn coin(&self) -> &TzeOut;
}
#[derive(Clone)]
struct TzeBuildInput {
tzein: TzeIn<()>,
coin: TzeOut,
}
impl TzeInput for TzeBuildInput {
impl fees::InputView for TzeBuildInput {
fn outpoint(&self) -> &OutPoint {
&self.tzein.prevout
}
@ -79,11 +72,11 @@ impl<'a, BuildCtx> TzeBuilder<'a, BuildCtx> {
}
}
pub fn inputs(&self) -> &[impl TzeInput] {
pub fn inputs(&self) -> &[impl fees::InputView] {
&self.vin
}
pub fn outputs(&self) -> &[TzeOut] {
pub fn outputs(&self) -> &[impl fees::OutputView] {
&self.vout
}

View File

@ -0,0 +1,37 @@
//! Abstractions and types related to fee calculations for TZE components of a transaction.
use crate::{
extensions::transparent::{self as tze},
transaction::components::{
amount::Amount,
tze::{OutPoint, TzeOut},
},
};
/// This trait provides a minimized view of a TZE input suitable for use in
/// fee computation.
pub trait InputView {
/// The outpoint to which the input refers.
fn outpoint(&self) -> &OutPoint;
/// The previous output being consumed.
fn coin(&self) -> &TzeOut;
}
/// This trait provides a minimized view of a TZE output suitable for use in
/// fee computation.
pub trait OutputView {
/// The value of the newly created output
fn value(&self) -> Amount;
/// The precondition that must be satisfied in order to spend this output.
fn precondition(&self) -> &tze::Precondition;
}
impl OutputView for TzeOut {
fn value(&self) -> Amount {
self.value
}
fn precondition(&self) -> &tze::Precondition {
&self.precondition
}
}

View File

@ -3,14 +3,12 @@
use crate::{
consensus::{self, BlockHeight},
transaction::components::{
amount::Amount,
sapling::builder::{SaplingInput, SaplingOutput},
transparent::{builder::TransparentInput, TxOut},
amount::Amount, sapling::fees as sapling, transparent::fees as transparent,
},
};
#[cfg(feature = "zfuture")]
use crate::transaction::components::tze::{builder::TzeInput, TzeOut};
use crate::transaction::components::tze::fees as tze;
/// A trait that represents the ability to compute the fees that must be paid
/// by a transaction having a specified set of inputs and outputs.
@ -26,10 +24,10 @@ pub trait FeeRule {
&self,
params: &P,
target_height: BlockHeight,
transparent_inputs: &[impl TransparentInput],
transparent_outputs: &[TxOut],
sapling_inputs: &[impl SaplingInput],
sapling_outputs: &[impl SaplingOutput],
transparent_inputs: &[impl transparent::InputView],
transparent_outputs: &[impl transparent::OutputView],
sapling_inputs: &[impl sapling::InputView],
sapling_outputs: &[impl sapling::OutputView],
) -> Result<Amount, Self::Error>;
}
@ -47,12 +45,12 @@ pub trait FutureFeeRule: FeeRule {
&self,
params: &P,
target_height: BlockHeight,
transparent_inputs: &[impl TransparentInput],
transparent_outputs: &[TxOut],
sapling_inputs: &[impl SaplingInput],
sapling_outputs: &[impl SaplingOutput],
tze_inputs: &[impl TzeInput],
tze_outputs: &[TzeOut],
transparent_inputs: &[impl transparent::InputView],
transparent_outputs: &[impl transparent::OutputView],
sapling_inputs: &[impl sapling::InputView],
sapling_outputs: &[impl sapling::OutputView],
tze_inputs: &[impl tze::InputView],
tze_outputs: &[impl tze::OutputView],
) -> Result<Amount, Self::Error>;
}
@ -76,10 +74,10 @@ impl FeeRule for FixedFeeRule {
&self,
_params: &P,
_target_height: BlockHeight,
_transparent_inputs: &[impl TransparentInput],
_transparent_outputs: &[TxOut],
_sapling_inputs: &[impl SaplingInput],
_sapling_outputs: &[impl SaplingOutput],
_transparent_inputs: &[impl transparent::InputView],
_transparent_outputs: &[impl transparent::OutputView],
_sapling_inputs: &[impl sapling::InputView],
_sapling_outputs: &[impl sapling::OutputView],
) -> Result<Amount, Self::Error> {
Ok(self.fixed_fee)
}
@ -91,12 +89,12 @@ impl FutureFeeRule for FixedFeeRule {
&self,
_params: &P,
_target_height: BlockHeight,
_transparent_inputs: &[impl TransparentInput],
_transparent_outputs: &[TxOut],
_sapling_inputs: &[impl SaplingInput],
_sapling_outputs: &[impl SaplingOutput],
_tze_inputs: &[impl TzeInput],
_tze_outputs: &[TzeOut],
_transparent_inputs: &[impl transparent::InputView],
_transparent_outputs: &[impl transparent::OutputView],
_sapling_inputs: &[impl sapling::InputView],
_sapling_outputs: &[impl sapling::OutputView],
_tze_inputs: &[impl tze::InputView],
_tze_outputs: &[impl tze::OutputView],
) -> Result<Amount, Self::Error> {
Ok(self.fixed_fee)
}