zcash_primitives: Remove and relocate `InputView` traits.
This commit is contained in:
parent
a9d6505148
commit
4eaa41affa
|
@ -28,7 +28,7 @@ and this library adheres to Rust's notion of
|
||||||
- `wallet::input_selection::ShieldingSelector` has been
|
- `wallet::input_selection::ShieldingSelector` has been
|
||||||
factored out from the `InputSelector` trait to separate out transparent
|
factored out from the `InputSelector` trait to separate out transparent
|
||||||
functionality and move it behind the `transparent-inputs` feature flag.
|
functionality and move it behind the `transparent-inputs` feature flag.
|
||||||
- `zcash_client_backend::fees::standard`
|
- `zcash_client_backend::fees::{standard, sapling}`
|
||||||
- `zcash_client_backend::wallet`:
|
- `zcash_client_backend::wallet`:
|
||||||
- `WalletNote`
|
- `WalletNote`
|
||||||
- `ReceivedNote`
|
- `ReceivedNote`
|
||||||
|
|
|
@ -10,7 +10,6 @@ use zcash_primitives::{
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::{
|
||||||
amount::{BalanceError, NonNegativeAmount},
|
amount::{BalanceError, NonNegativeAmount},
|
||||||
sapling::fees as sapling,
|
|
||||||
TxOut,
|
TxOut,
|
||||||
},
|
},
|
||||||
fees::FeeRule,
|
fees::FeeRule,
|
||||||
|
@ -21,7 +20,7 @@ use zcash_primitives::{
|
||||||
use crate::{
|
use crate::{
|
||||||
address::{RecipientAddress, UnifiedAddress},
|
address::{RecipientAddress, UnifiedAddress},
|
||||||
data_api::SaplingInputSource,
|
data_api::SaplingInputSource,
|
||||||
fees::{ChangeError, ChangeStrategy, DustOutputPolicy, TransactionBalance},
|
fees::{sapling, ChangeError, ChangeStrategy, DustOutputPolicy, TransactionBalance},
|
||||||
wallet::{ReceivedNote, WalletTransparentOutput},
|
wallet::{ReceivedNote, WalletTransparentOutput},
|
||||||
zip321::TransactionRequest,
|
zip321::TransactionRequest,
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,15 +6,14 @@ use zcash_primitives::{
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::{
|
||||||
amount::{BalanceError, NonNegativeAmount},
|
amount::{BalanceError, NonNegativeAmount},
|
||||||
sapling::fees as sapling,
|
|
||||||
transparent::fees as transparent,
|
|
||||||
OutPoint,
|
OutPoint,
|
||||||
},
|
},
|
||||||
fees::FeeRule,
|
fees::{transparent, FeeRule},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod fixed;
|
pub mod fixed;
|
||||||
|
pub mod sapling;
|
||||||
pub mod standard;
|
pub mod standard;
|
||||||
pub mod zip317;
|
pub mod zip317;
|
||||||
|
|
||||||
|
@ -260,12 +259,16 @@ pub trait ChangeStrategy {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use zcash_primitives::transaction::components::{
|
use zcash_primitives::transaction::{
|
||||||
|
components::{
|
||||||
amount::NonNegativeAmount,
|
amount::NonNegativeAmount,
|
||||||
sapling::fees as sapling,
|
transparent::{OutPoint, TxOut},
|
||||||
transparent::{fees as transparent, OutPoint, TxOut},
|
},
|
||||||
|
fees::transparent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::sapling;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct TestTransparentInput {
|
pub(crate) struct TestTransparentInput {
|
||||||
pub outpoint: OutPoint,
|
pub outpoint: OutPoint,
|
||||||
|
|
|
@ -4,17 +4,14 @@ use zcash_primitives::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::amount::{BalanceError, NonNegativeAmount},
|
||||||
amount::{BalanceError, NonNegativeAmount},
|
fees::{fixed::FeeRule as FixedFeeRule, transparent, FeeRule},
|
||||||
sapling::fees as sapling,
|
|
||||||
transparent::fees as transparent,
|
|
||||||
},
|
|
||||||
fees::{fixed::FeeRule as FixedFeeRule, FeeRule},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ChangeError, ChangeStrategy, ChangeValue, DustAction, DustOutputPolicy, TransactionBalance,
|
sapling, ChangeError, ChangeStrategy, ChangeValue, DustAction, DustOutputPolicy,
|
||||||
|
TransactionBalance,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A change strategy that and proposes change as a single output to the most current supported
|
/// A change strategy that and proposes change as a single output to the most current supported
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
//! Types related to computation of fees and change related to the Sapling components
|
||||||
|
//! of a transaction.
|
||||||
|
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use zcash_primitives::{
|
||||||
|
sapling::builder::{SaplingOutputInfo, SpendDescriptionInfo},
|
||||||
|
transaction::components::amount::NonNegativeAmount,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A trait that provides a minimized view of a Sapling input suitable for use in
|
||||||
|
/// fee and change calculation.
|
||||||
|
pub trait InputView<NoteRef> {
|
||||||
|
/// An identifier for the input being spent.
|
||||||
|
fn note_id(&self) -> &NoteRef;
|
||||||
|
/// The value of the input being spent.
|
||||||
|
fn value(&self) -> NonNegativeAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N> InputView<N> for Infallible {
|
||||||
|
fn note_id(&self) -> &N {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn value(&self) -> NonNegativeAmount {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// `SpendDescriptionInfo` does not contain a note identifier, so we can only implement
|
||||||
|
// `InputView<()>`
|
||||||
|
impl InputView<()> for SpendDescriptionInfo {
|
||||||
|
fn note_id(&self) -> &() {
|
||||||
|
&()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value(&self) -> NonNegativeAmount {
|
||||||
|
NonNegativeAmount::try_from(self.value())
|
||||||
|
.expect("An existing note to be spent must have a valid amount value.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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) -> NonNegativeAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputView for SaplingOutputInfo {
|
||||||
|
fn value(&self) -> NonNegativeAmount {
|
||||||
|
NonNegativeAmount::try_from(self.value())
|
||||||
|
.expect("Output values should be checked at construction.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputView for Infallible {
|
||||||
|
fn value(&self) -> NonNegativeAmount {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,18 +4,19 @@ use zcash_primitives::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::amount::NonNegativeAmount,
|
||||||
amount::NonNegativeAmount, sapling::fees as sapling, transparent::fees as transparent,
|
|
||||||
},
|
|
||||||
fees::{
|
fees::{
|
||||||
fixed::FeeRule as FixedFeeRule,
|
fixed::FeeRule as FixedFeeRule,
|
||||||
|
transparent,
|
||||||
zip317::{FeeError as Zip317FeeError, FeeRule as Zip317FeeRule},
|
zip317::{FeeError as Zip317FeeError, FeeRule as Zip317FeeRule},
|
||||||
StandardFeeRule,
|
StandardFeeRule,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{fixed, zip317, ChangeError, ChangeStrategy, DustOutputPolicy, TransactionBalance};
|
use super::{
|
||||||
|
fixed, sapling, zip317, ChangeError, ChangeStrategy, DustOutputPolicy, TransactionBalance,
|
||||||
|
};
|
||||||
|
|
||||||
/// A change strategy that proposes change as a single output to the most current supported
|
/// A change strategy that proposes change as a single output to the most current supported
|
||||||
/// shielded pool and delegates fee calculation to the provided fee rule.
|
/// shielded pool and delegates fee calculation to the provided fee rule.
|
||||||
|
|
|
@ -8,12 +8,9 @@ use zcash_primitives::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::amount::{BalanceError, NonNegativeAmount},
|
||||||
amount::{BalanceError, NonNegativeAmount},
|
|
||||||
sapling::fees as sapling,
|
|
||||||
transparent::fees as transparent,
|
|
||||||
},
|
|
||||||
fees::{
|
fees::{
|
||||||
|
transparent,
|
||||||
zip317::{FeeError as Zip317FeeError, FeeRule as Zip317FeeRule},
|
zip317::{FeeError as Zip317FeeError, FeeRule as Zip317FeeRule},
|
||||||
FeeRule,
|
FeeRule,
|
||||||
},
|
},
|
||||||
|
@ -21,7 +18,8 @@ use zcash_primitives::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ChangeError, ChangeStrategy, ChangeValue, DustAction, DustOutputPolicy, TransactionBalance,
|
sapling, ChangeError, ChangeStrategy, ChangeValue, DustAction, DustOutputPolicy,
|
||||||
|
TransactionBalance,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A change strategy that and proposes change as a single output to the most current supported
|
/// A change strategy that and proposes change as a single output to the most current supported
|
||||||
|
|
|
@ -10,15 +10,15 @@ use zcash_primitives::{
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::{
|
||||||
amount::NonNegativeAmount,
|
amount::NonNegativeAmount,
|
||||||
sapling::fees as sapling_fees,
|
transparent::{OutPoint, TxOut},
|
||||||
transparent::{self, OutPoint, TxOut},
|
|
||||||
},
|
},
|
||||||
|
fees::transparent as transparent_fees,
|
||||||
TxId,
|
TxId,
|
||||||
},
|
},
|
||||||
zip32::{AccountId, Scope},
|
zip32::{AccountId, Scope},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{address::UnifiedAddress, PoolType, ShieldedProtocol};
|
use crate::{address::UnifiedAddress, fees::sapling as sapling_fees, PoolType, ShieldedProtocol};
|
||||||
|
|
||||||
/// A unique identifier for a shielded transaction output
|
/// A unique identifier for a shielded transaction output
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
@ -122,7 +122,7 @@ impl WalletTransparentOutput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl transparent::fees::InputView for WalletTransparentOutput {
|
impl transparent_fees::InputView for WalletTransparentOutput {
|
||||||
fn outpoint(&self) -> &OutPoint {
|
fn outpoint(&self) -> &OutPoint {
|
||||||
&self.outpoint
|
&self.outpoint
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ and this library adheres to Rust's notion of
|
||||||
- `builder::{InProgressProofs, Unproven, Proven}`
|
- `builder::{InProgressProofs, Unproven, Proven}`
|
||||||
- `builder::{InProgressSignatures, Unsigned, PartiallyAuthorized}`
|
- `builder::{InProgressSignatures, Unsigned, PartiallyAuthorized}`
|
||||||
- `builder::{MaybeSigned, SigningParts}`
|
- `builder::{MaybeSigned, SigningParts}`
|
||||||
|
- `builder::{SpendDescriptionInfo::value}`
|
||||||
|
- `builder::{SaplingOutputInfo}`
|
||||||
- `bundle` module, containing the following types moved from
|
- `bundle` module, containing the following types moved from
|
||||||
`zcash_primitives::transaction::components::sapling`:
|
`zcash_primitives::transaction::components::sapling`:
|
||||||
- `Bundle`
|
- `Bundle`
|
||||||
|
@ -69,6 +71,8 @@ and this library adheres to Rust's notion of
|
||||||
- `temporary_zcashd_write_output_v4`
|
- `temporary_zcashd_write_output_v4`
|
||||||
- `temporary_zcashd_read_v4_components`
|
- `temporary_zcashd_read_v4_components`
|
||||||
- `temporary_zcashd_write_v4_components`
|
- `temporary_zcashd_write_v4_components`
|
||||||
|
- `components::transparent`:
|
||||||
|
- `builder::TransparentInputInfo`
|
||||||
- `fees::StandardFeeRule`
|
- `fees::StandardFeeRule`
|
||||||
- Constants in `fees::zip317`:
|
- Constants in `fees::zip317`:
|
||||||
- `MARGINAL_FEE`
|
- `MARGINAL_FEE`
|
||||||
|
@ -182,7 +186,14 @@ and this library adheres to Rust's notion of
|
||||||
argument as the diversifier may be obtained from the note.
|
argument as the diversifier may be obtained from the note.
|
||||||
- `components::transparent::TxOut.value` now has type `NonNegativeAmount`
|
- `components::transparent::TxOut.value` now has type `NonNegativeAmount`
|
||||||
instead of `Amount`.
|
instead of `Amount`.
|
||||||
|
- `components::transparent::fees` has been moved to
|
||||||
|
`zcash_primitives::transaction::fees::transparent`
|
||||||
|
- `components::transparent::builder::TransparentBuilder::{inputs, outputs}`
|
||||||
|
have changed to return `&[TransparentInputInfo]` and `&[TxOut]` respectively,
|
||||||
|
in order to avoid coupling to the fee traits.
|
||||||
- `Unauthorized::SaplingAuth` now has type `InProgress<Proven, Unsigned>`.
|
- `Unauthorized::SaplingAuth` now has type `InProgress<Proven, Unsigned>`.
|
||||||
|
- `fees::FeeRule::fee_required` now takes an additional `orchard_action_count`
|
||||||
|
argument.
|
||||||
- The following methods now take `NonNegativeAmount` instead of `Amount`:
|
- The following methods now take `NonNegativeAmount` instead of `Amount`:
|
||||||
- `builder::Builder::{add_sapling_output, add_transparent_output}`
|
- `builder::Builder::{add_sapling_output, add_transparent_output}`
|
||||||
- `components::transparent::builder::TransparentBuilder::add_output`
|
- `components::transparent::builder::TransparentBuilder::add_output`
|
||||||
|
@ -190,12 +201,9 @@ and this library adheres to Rust's notion of
|
||||||
- `fees::zip317::FeeRule::non_standard`
|
- `fees::zip317::FeeRule::non_standard`
|
||||||
- The following methods now return `NonNegativeAmount` instead of `Amount`:
|
- The following methods now return `NonNegativeAmount` instead of `Amount`:
|
||||||
- `components::amount::testing::arb_nonnegative_amount`
|
- `components::amount::testing::arb_nonnegative_amount`
|
||||||
- `components::sapling`:
|
- `fees::transparent`:
|
||||||
- `fees::InputView::value`
|
- `InputView::value`
|
||||||
- `fees::OutputView::value`
|
- `OutputView::value`
|
||||||
- `components::transparent`:
|
|
||||||
- `fees::InputView::value`
|
|
||||||
- `fees::OutputView::value`
|
|
||||||
- `fees::FeeRule::{fee_required, fee_required_zfuture}`
|
- `fees::FeeRule::{fee_required, fee_required_zfuture}`
|
||||||
- `fees::fixed::FeeRule::fixed_fee`
|
- `fees::fixed::FeeRule::fixed_fee`
|
||||||
- `fees::zip317::FeeRule::marginal_fee`
|
- `fees::zip317::FeeRule::marginal_fee`
|
||||||
|
@ -237,6 +245,8 @@ and this library adheres to Rust's notion of
|
||||||
- `SpendDescription::<Unauthorized>::apply_signature`
|
- `SpendDescription::<Unauthorized>::apply_signature`
|
||||||
- `Bundle::<Unauthorized>::apply_signatures` (use
|
- `Bundle::<Unauthorized>::apply_signatures` (use
|
||||||
`Bundle::<InProgress<Proven, Unsigned>>::apply_signatures` instead).
|
`Bundle::<InProgress<Proven, Unsigned>>::apply_signatures` instead).
|
||||||
|
- The `fees` module was removed. Its contents were unused in this crate,
|
||||||
|
are now instead made available by `zcash_client_backend::fees::sapling`.
|
||||||
- `impl From<zcash_primitive::components::transaction::Amount> for u64`
|
- `impl From<zcash_primitive::components::transaction::Amount> for u64`
|
||||||
- `zcash_primitives::zip32`:
|
- `zcash_primitives::zip32`:
|
||||||
- `sapling` module (moved from `zcash_primitives::sapling::zip32`).
|
- `sapling` module (moved from `zcash_primitives::sapling::zip32`).
|
||||||
|
|
|
@ -25,10 +25,7 @@ use crate::{
|
||||||
zip32::ExtendedSpendingKey,
|
zip32::ExtendedSpendingKey,
|
||||||
Diversifier, MerklePath, Node, Note, PaymentAddress, ProofGenerationKey, SaplingIvk,
|
Diversifier, MerklePath, Node, Note, PaymentAddress, ProofGenerationKey, SaplingIvk,
|
||||||
},
|
},
|
||||||
transaction::{
|
transaction::builder::Progress,
|
||||||
builder::Progress,
|
|
||||||
components::{amount::NonNegativeAmount, sapling::fees},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// If there are any shielded inputs, always have at least two shielded outputs, padding
|
/// If there are any shielded inputs, always have at least two shielded outputs, padding
|
||||||
|
@ -77,18 +74,6 @@ pub struct SpendDescriptionInfo {
|
||||||
rcv: ValueCommitTrapdoor,
|
rcv: ValueCommitTrapdoor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fees::InputView<()> for SpendDescriptionInfo {
|
|
||||||
fn note_id(&self) -> &() {
|
|
||||||
// The builder does not make use of note identifiers, so we can just return the unit value.
|
|
||||||
&()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn value(&self) -> NonNegativeAmount {
|
|
||||||
// An existing note to be spent must have a valid amount value.
|
|
||||||
NonNegativeAmount::from_u64(self.note.value().inner()).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpendDescriptionInfo {
|
impl SpendDescriptionInfo {
|
||||||
fn new_internal<R: RngCore>(
|
fn new_internal<R: RngCore>(
|
||||||
mut rng: &mut R,
|
mut rng: &mut R,
|
||||||
|
@ -105,6 +90,10 @@ impl SpendDescriptionInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> NoteValue {
|
||||||
|
self.note.value()
|
||||||
|
}
|
||||||
|
|
||||||
fn build<Pr: SpendProver>(
|
fn build<Pr: SpendProver>(
|
||||||
self,
|
self,
|
||||||
anchor: Option<bls12_381::Scalar>,
|
anchor: Option<bls12_381::Scalar>,
|
||||||
|
@ -154,7 +143,7 @@ impl SpendDescriptionInfo {
|
||||||
/// A struct containing the information required in order to construct a
|
/// A struct containing the information required in order to construct a
|
||||||
/// Sapling output to a transaction.
|
/// Sapling output to a transaction.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct SaplingOutputInfo {
|
pub struct SaplingOutputInfo {
|
||||||
/// `None` represents the `ovk = ⊥` case.
|
/// `None` represents the `ovk = ⊥` case.
|
||||||
ovk: Option<OutgoingViewingKey>,
|
ovk: Option<OutgoingViewingKey>,
|
||||||
note: Note,
|
note: Note,
|
||||||
|
@ -249,12 +238,13 @@ impl SaplingOutputInfo {
|
||||||
zkproof,
|
zkproof,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn recipient(&self) -> PaymentAddress {
|
||||||
|
self.note.recipient()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fees::OutputView for SaplingOutputInfo {
|
pub fn value(&self) -> NoteValue {
|
||||||
fn value(&self) -> NonNegativeAmount {
|
self.note.value()
|
||||||
NonNegativeAmount::from_u64(self.note.value().inner())
|
|
||||||
.expect("Note values should be checked at construction.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,12 +307,12 @@ impl SaplingBuilder {
|
||||||
|
|
||||||
/// Returns the list of Sapling inputs that will be consumed by the transaction being
|
/// Returns the list of Sapling inputs that will be consumed by the transaction being
|
||||||
/// constructed.
|
/// constructed.
|
||||||
pub fn inputs(&self) -> &[impl fees::InputView<()>] {
|
pub fn inputs(&self) -> &[SpendDescriptionInfo] {
|
||||||
&self.spends
|
&self.spends
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Sapling outputs that will be produced by the transaction being constructed
|
/// Returns the Sapling outputs that will be produced by the transaction being constructed
|
||||||
pub fn outputs(&self) -> &[impl fees::OutputView] {
|
pub fn outputs(&self) -> &[SaplingOutputInfo] {
|
||||||
&self.outputs
|
&self.outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,7 @@ use crate::{
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::{
|
||||||
amount::{Amount, BalanceError},
|
amount::{Amount, BalanceError},
|
||||||
sapling::fees as sapling_fees,
|
transparent::{self, builder::TransparentBuilder, TxOut},
|
||||||
transparent::{self, builder::TransparentBuilder},
|
|
||||||
},
|
},
|
||||||
fees::FeeRule,
|
fees::FeeRule,
|
||||||
sighash::{signature_hash, SignableInput},
|
sighash::{signature_hash, SignableInput},
|
||||||
|
@ -31,7 +30,10 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
use crate::transaction::components::transparent::TxOut;
|
use crate::transaction::components::transparent::builder::TransparentInputInfo;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "transparent-inputs"))]
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
#[cfg(feature = "zfuture")]
|
#[cfg(feature = "zfuture")]
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -184,25 +186,26 @@ impl<'a, P, R> Builder<'a, P, R> {
|
||||||
|
|
||||||
/// Returns the set of transparent inputs currently committed to be consumed
|
/// Returns the set of transparent inputs currently committed to be consumed
|
||||||
/// by the transaction.
|
/// by the transaction.
|
||||||
pub fn transparent_inputs(&self) -> &[impl transparent::fees::InputView] {
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
pub fn transparent_inputs(&self) -> &[TransparentInputInfo] {
|
||||||
self.transparent_builder.inputs()
|
self.transparent_builder.inputs()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of transparent outputs currently set to be produced by
|
/// Returns the set of transparent outputs currently set to be produced by
|
||||||
/// the transaction.
|
/// the transaction.
|
||||||
pub fn transparent_outputs(&self) -> &[impl transparent::fees::OutputView] {
|
pub fn transparent_outputs(&self) -> &[TxOut] {
|
||||||
self.transparent_builder.outputs()
|
self.transparent_builder.outputs()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of Sapling inputs currently committed to be consumed
|
/// Returns the set of Sapling inputs currently committed to be consumed
|
||||||
/// by the transaction.
|
/// by the transaction.
|
||||||
pub fn sapling_inputs(&self) -> &[impl sapling_fees::InputView<()>] {
|
pub fn sapling_inputs(&self) -> &[sapling::builder::SpendDescriptionInfo] {
|
||||||
self.sapling_builder.inputs()
|
self.sapling_builder.inputs()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of Sapling outputs currently set to be produced by
|
/// Returns the set of Sapling outputs currently set to be produced by
|
||||||
/// the transaction.
|
/// the transaction.
|
||||||
pub fn sapling_outputs(&self) -> &[impl sapling_fees::OutputView] {
|
pub fn sapling_outputs(&self) -> &[sapling::builder::SaplingOutputInfo] {
|
||||||
self.sapling_builder.outputs()
|
self.sapling_builder.outputs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,10 +417,16 @@ impl<'a, P: consensus::Parameters, R: RngCore + CryptoRng> Builder<'a, P, R> {
|
||||||
/// This fee is a function of the spends and outputs that have been added to the builder,
|
/// This fee is a function of the spends and outputs that have been added to the builder,
|
||||||
/// pursuant to the specified [`FeeRule`].
|
/// pursuant to the specified [`FeeRule`].
|
||||||
pub fn get_fee<FR: FeeRule>(&self, fee_rule: &FR) -> Result<NonNegativeAmount, FR::Error> {
|
pub fn get_fee<FR: FeeRule>(&self, fee_rule: &FR) -> Result<NonNegativeAmount, FR::Error> {
|
||||||
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
let transparent_inputs = self.transparent_builder.inputs();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "transparent-inputs"))]
|
||||||
|
let transparent_inputs: &[Infallible] = &[];
|
||||||
|
|
||||||
fee_rule.fee_required(
|
fee_rule.fee_required(
|
||||||
&self.params,
|
&self.params,
|
||||||
self.target_height,
|
self.target_height,
|
||||||
self.transparent_builder.inputs(),
|
transparent_inputs,
|
||||||
self.transparent_builder.outputs(),
|
self.transparent_builder.outputs(),
|
||||||
self.sapling_builder.inputs().len(),
|
self.sapling_builder.inputs().len(),
|
||||||
self.sapling_builder.bundle_output_count(),
|
self.sapling_builder.bundle_output_count(),
|
||||||
|
@ -460,14 +469,28 @@ impl<'a, P: consensus::Parameters, R: RngCore + CryptoRng> Builder<'a, P, R> {
|
||||||
output_prover: &OP,
|
output_prover: &OP,
|
||||||
fee_rule: &FR,
|
fee_rule: &FR,
|
||||||
) -> Result<(Transaction, SaplingMetadata), Error<FR::Error>> {
|
) -> Result<(Transaction, SaplingMetadata), Error<FR::Error>> {
|
||||||
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
let transparent_inputs = self.transparent_builder.inputs();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "transparent-inputs"))]
|
||||||
|
let transparent_inputs: &[Infallible] = &[];
|
||||||
|
|
||||||
let fee = fee_rule
|
let fee = fee_rule
|
||||||
.fee_required_zfuture(
|
.fee_required_zfuture(
|
||||||
&self.params,
|
&self.params,
|
||||||
self.target_height,
|
self.target_height,
|
||||||
self.transparent_builder.inputs(),
|
transparent_inputs,
|
||||||
self.transparent_builder.outputs(),
|
self.transparent_builder.outputs(),
|
||||||
self.sapling_builder.inputs().len(),
|
self.sapling_builder.inputs().len(),
|
||||||
self.sapling_builder.bundle_output_count(),
|
self.sapling_builder.bundle_output_count(),
|
||||||
|
std::cmp::max(
|
||||||
|
self.orchard_builder
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |builder| builder.outputs().len()),
|
||||||
|
self.orchard_builder
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |builder| builder.spends().len()),
|
||||||
|
),
|
||||||
self.tze_builder.inputs(),
|
self.tze_builder.inputs(),
|
||||||
self.tze_builder.outputs(),
|
self.tze_builder.outputs(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,8 +21,6 @@ use crate::{
|
||||||
|
|
||||||
use super::{Amount, GROTH_PROOF_SIZE};
|
use super::{Amount, GROTH_PROOF_SIZE};
|
||||||
|
|
||||||
pub mod fees;
|
|
||||||
|
|
||||||
/// Consensus rules (§4.4) & (§4.5):
|
/// Consensus rules (§4.4) & (§4.5):
|
||||||
/// - Canonical encoding is enforced here.
|
/// - Canonical encoding is enforced here.
|
||||||
/// - "Not small order" is enforced here.
|
/// - "Not small order" is enforced here.
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
//! Types related to computation of fees and change related to the Sapling components
|
|
||||||
//! of a transaction.
|
|
||||||
|
|
||||||
use crate::transaction::components::amount::NonNegativeAmount;
|
|
||||||
|
|
||||||
/// A trait that provides a minimized view of a Sapling input suitable for use in
|
|
||||||
/// fee and change calculation.
|
|
||||||
pub trait InputView<NoteRef> {
|
|
||||||
/// An identifier for the input being spent.
|
|
||||||
fn note_id(&self) -> &NoteRef;
|
|
||||||
/// The value of the input being spent.
|
|
||||||
fn value(&self) -> NonNegativeAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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) -> NonNegativeAmount;
|
|
||||||
}
|
|
|
@ -10,7 +10,6 @@ use crate::legacy::{Script, TransparentAddress};
|
||||||
use super::amount::{Amount, BalanceError, NonNegativeAmount};
|
use super::amount::{Amount, BalanceError, NonNegativeAmount};
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
pub mod fees;
|
|
||||||
|
|
||||||
pub trait Authorization: Debug {
|
pub trait Authorization: Debug {
|
||||||
type ScriptSig: Debug + Clone + PartialEq;
|
type ScriptSig: Debug + Clone + PartialEq;
|
||||||
|
|
|
@ -7,10 +7,9 @@ use crate::{
|
||||||
transaction::{
|
transaction::{
|
||||||
components::{
|
components::{
|
||||||
amount::{Amount, BalanceError, NonNegativeAmount},
|
amount::{Amount, BalanceError, NonNegativeAmount},
|
||||||
transparent::{self, fees, Authorization, Authorized, Bundle, TxIn, TxOut},
|
transparent::{self, Authorization, Authorized, Bundle, TxIn, TxOut},
|
||||||
},
|
},
|
||||||
sighash::TransparentAuthorizingContext,
|
sighash::TransparentAuthorizingContext,
|
||||||
OutPoint,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +17,7 @@ use crate::{
|
||||||
use {
|
use {
|
||||||
crate::transaction::{
|
crate::transaction::{
|
||||||
self as tx,
|
self as tx,
|
||||||
|
components::transparent::OutPoint,
|
||||||
sighash::{signature_hash, SignableInput, SIGHASH_ALL},
|
sighash::{signature_hash, SignableInput, SIGHASH_ALL},
|
||||||
TransactionData, TxDigests,
|
TransactionData, TxDigests,
|
||||||
},
|
},
|
||||||
|
@ -40,25 +40,9 @@ impl fmt::Display for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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"))]
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum InvalidTransparentInput {}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "transparent-inputs"))]
|
|
||||||
impl fees::InputView for InvalidTransparentInput {
|
|
||||||
fn outpoint(&self) -> &OutPoint {
|
|
||||||
panic!("transparent-inputs feature flag is not enabled.");
|
|
||||||
}
|
|
||||||
fn coin(&self) -> &TxOut {
|
|
||||||
panic!("transparent-inputs feature flag is not enabled.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct TransparentInputInfo {
|
pub struct TransparentInputInfo {
|
||||||
sk: secp256k1::SecretKey,
|
sk: secp256k1::SecretKey,
|
||||||
pubkey: [u8; secp256k1::constants::PUBLIC_KEY_SIZE],
|
pubkey: [u8; secp256k1::constants::PUBLIC_KEY_SIZE],
|
||||||
utxo: OutPoint,
|
utxo: OutPoint,
|
||||||
|
@ -66,12 +50,12 @@ struct TransparentInputInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
impl fees::InputView for TransparentInputInfo {
|
impl TransparentInputInfo {
|
||||||
fn outpoint(&self) -> &OutPoint {
|
pub fn outpoint(&self) -> &OutPoint {
|
||||||
&self.utxo
|
&self.utxo
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coin(&self) -> &TxOut {
|
pub fn coin(&self) -> &TxOut {
|
||||||
&self.coin
|
&self.coin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,19 +94,13 @@ impl TransparentBuilder {
|
||||||
|
|
||||||
/// Returns the list of transparent inputs that will be consumed by the transaction being
|
/// Returns the list of transparent inputs that will be consumed by the transaction being
|
||||||
/// constructed.
|
/// constructed.
|
||||||
pub fn inputs(&self) -> &[impl fees::InputView] {
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
return &self.inputs;
|
pub fn inputs(&self) -> &[TransparentInputInfo] {
|
||||||
|
&self.inputs
|
||||||
#[cfg(not(feature = "transparent-inputs"))]
|
|
||||||
{
|
|
||||||
let invalid: &[InvalidTransparentInput] = &[];
|
|
||||||
invalid
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the transparent outputs that will be produced by the transaction being constructed.
|
/// Returns the transparent outputs that will be produced by the transaction being constructed.
|
||||||
pub fn outputs(&self) -> &[impl fees::OutputView] {
|
pub fn outputs(&self) -> &[TxOut] {
|
||||||
&self.vout
|
&self.vout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ use super::amount::Amount;
|
||||||
use crate::{extensions::transparent as tze, transaction::TxId};
|
use crate::{extensions::transparent as tze, transaction::TxId};
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
pub mod fees;
|
|
||||||
|
|
||||||
fn to_io_error(_: std::num::TryFromIntError) -> io::Error {
|
fn to_io_error(_: std::num::TryFromIntError) -> io::Error {
|
||||||
io::Error::new(io::ErrorKind::InvalidData, "value out of range")
|
io::Error::new(io::ErrorKind::InvalidData, "value out of range")
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
self as tx,
|
self as tx,
|
||||||
components::{
|
components::{
|
||||||
amount::{Amount, BalanceError},
|
amount::{Amount, BalanceError},
|
||||||
tze::{fees, Authorization, Authorized, Bundle, OutPoint, TzeIn, TzeOut},
|
tze::{Authorization, Authorized, Bundle, OutPoint, TzeIn, TzeOut},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -36,16 +36,16 @@ pub struct TzeSigner<'a, BuildCtx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct TzeBuildInput {
|
pub struct TzeBuildInput {
|
||||||
tzein: TzeIn<()>,
|
tzein: TzeIn<()>,
|
||||||
coin: TzeOut,
|
coin: TzeOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fees::InputView for TzeBuildInput {
|
impl TzeBuildInput {
|
||||||
fn outpoint(&self) -> &OutPoint {
|
pub fn outpoint(&self) -> &OutPoint {
|
||||||
&self.tzein.prevout
|
&self.tzein.prevout
|
||||||
}
|
}
|
||||||
fn coin(&self) -> &TzeOut {
|
pub fn coin(&self) -> &TzeOut {
|
||||||
&self.coin
|
&self.coin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,11 +72,11 @@ impl<'a, BuildCtx> TzeBuilder<'a, BuildCtx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inputs(&self) -> &[impl fees::InputView] {
|
pub fn inputs(&self) -> &[TzeBuildInput] {
|
||||||
&self.vin
|
&self.vin
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outputs(&self) -> &[impl fees::OutputView] {
|
pub fn outputs(&self) -> &[TzeOut] {
|
||||||
&self.vout
|
&self.vout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,16 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
transaction::components::{amount::NonNegativeAmount, transparent::fees as transparent},
|
transaction::components::amount::NonNegativeAmount,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "zfuture")]
|
|
||||||
use crate::transaction::components::tze::fees as tze;
|
|
||||||
|
|
||||||
pub mod fixed;
|
pub mod fixed;
|
||||||
|
pub mod transparent;
|
||||||
pub mod zip317;
|
pub mod zip317;
|
||||||
|
|
||||||
|
#[cfg(feature = "zfuture")]
|
||||||
|
pub mod tze;
|
||||||
|
|
||||||
/// A trait that represents the ability to compute the fees that must be paid
|
/// 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.
|
/// by a transaction having a specified set of inputs and outputs.
|
||||||
pub trait FeeRule {
|
pub trait FeeRule {
|
||||||
|
@ -52,6 +53,7 @@ pub trait FutureFeeRule: FeeRule {
|
||||||
transparent_outputs: &[impl transparent::OutputView],
|
transparent_outputs: &[impl transparent::OutputView],
|
||||||
sapling_input_count: usize,
|
sapling_input_count: usize,
|
||||||
sapling_output_count: usize,
|
sapling_output_count: usize,
|
||||||
|
orchard_action_count: usize,
|
||||||
tze_inputs: &[impl tze::InputView],
|
tze_inputs: &[impl tze::InputView],
|
||||||
tze_outputs: &[impl tze::OutputView],
|
tze_outputs: &[impl tze::OutputView],
|
||||||
) -> Result<NonNegativeAmount, Self::Error>;
|
) -> Result<NonNegativeAmount, Self::Error>;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
transaction::components::{amount::NonNegativeAmount, transparent::fees as transparent},
|
transaction::components::amount::NonNegativeAmount,
|
||||||
transaction::fees::zip317,
|
transaction::fees::{transparent, zip317},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "zfuture")]
|
#[cfg(feature = "zfuture")]
|
||||||
use crate::transaction::components::tze::fees as tze;
|
use crate::transaction::fees::tze;
|
||||||
|
|
||||||
/// A fee rule that always returns a fixed fee, irrespective of the structure of
|
/// A fee rule that always returns a fixed fee, irrespective of the structure of
|
||||||
/// the transaction being constructed.
|
/// the transaction being constructed.
|
||||||
|
@ -72,6 +72,7 @@ impl super::FutureFeeRule for FeeRule {
|
||||||
_transparent_outputs: &[impl transparent::OutputView],
|
_transparent_outputs: &[impl transparent::OutputView],
|
||||||
_sapling_input_count: usize,
|
_sapling_input_count: usize,
|
||||||
_sapling_output_count: usize,
|
_sapling_output_count: usize,
|
||||||
|
_orchard_action_count: usize,
|
||||||
_tze_inputs: &[impl tze::InputView],
|
_tze_inputs: &[impl tze::InputView],
|
||||||
_tze_outputs: &[impl tze::OutputView],
|
_tze_outputs: &[impl tze::OutputView],
|
||||||
) -> Result<NonNegativeAmount, Self::Error> {
|
) -> Result<NonNegativeAmount, Self::Error> {
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
//! Types related to computation of fees and change related to the transparent components
|
//! Types related to computation of fees and change related to the transparent components
|
||||||
//! of a transaction.
|
//! of a transaction.
|
||||||
|
|
||||||
use super::TxOut;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
legacy::Script,
|
legacy::Script,
|
||||||
transaction::{components::amount::NonNegativeAmount, OutPoint},
|
transaction::components::{amount::NonNegativeAmount, transparent::TxOut, OutPoint},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
use crate::transaction::components::transparent::builder::TransparentInputInfo;
|
||||||
|
|
||||||
/// This trait provides a minimized view of a transparent input suitable for use in
|
/// This trait provides a minimized view of a transparent input suitable for use in
|
||||||
/// fee and change computation.
|
/// fee and change computation.
|
||||||
pub trait InputView: std::fmt::Debug {
|
pub trait InputView: std::fmt::Debug {
|
||||||
|
@ -16,6 +20,26 @@ pub trait InputView: std::fmt::Debug {
|
||||||
fn coin(&self) -> &TxOut;
|
fn coin(&self) -> &TxOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
impl InputView for TransparentInputInfo {
|
||||||
|
fn outpoint(&self) -> &OutPoint {
|
||||||
|
self.outpoint()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn coin(&self) -> &TxOut {
|
||||||
|
self.coin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputView for Infallible {
|
||||||
|
fn outpoint(&self) -> &OutPoint {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn coin(&self) -> &TxOut {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This trait provides a minimized view of a transparent output suitable for use in
|
/// This trait provides a minimized view of a transparent output suitable for use in
|
||||||
/// fee and change computation.
|
/// fee and change computation.
|
||||||
pub trait OutputView: std::fmt::Debug {
|
pub trait OutputView: std::fmt::Debug {
|
|
@ -1,10 +1,10 @@
|
||||||
//! Abstractions and types related to fee calculations for TZE components of a transaction.
|
//! Abstractions and types related to fee calculations for TZE components of a transaction.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
extensions::transparent::{self as tze},
|
extensions::transparent as tze,
|
||||||
transaction::components::{
|
transaction::components::{
|
||||||
amount::Amount,
|
amount::Amount,
|
||||||
tze::{OutPoint, TzeOut},
|
tze::{builder::TzeBuildInput, OutPoint, TzeOut},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +17,15 @@ pub trait InputView {
|
||||||
fn coin(&self) -> &TzeOut;
|
fn coin(&self) -> &TzeOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InputView for TzeBuildInput {
|
||||||
|
fn outpoint(&self) -> &OutPoint {
|
||||||
|
self.outpoint()
|
||||||
|
}
|
||||||
|
fn coin(&self) -> &TzeOut {
|
||||||
|
self.coin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This trait provides a minimized view of a TZE output suitable for use in
|
/// This trait provides a minimized view of a TZE output suitable for use in
|
||||||
/// fee computation.
|
/// fee computation.
|
||||||
pub trait OutputView {
|
pub trait OutputView {
|
|
@ -7,9 +7,12 @@ use core::cmp::max;
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
legacy::TransparentAddress,
|
legacy::TransparentAddress,
|
||||||
transaction::components::{
|
transaction::{
|
||||||
|
components::{
|
||||||
amount::{BalanceError, NonNegativeAmount},
|
amount::{BalanceError, NonNegativeAmount},
|
||||||
transparent::{fees as transparent, OutPoint},
|
transparent::OutPoint,
|
||||||
|
},
|
||||||
|
fees::transparent,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue