use std::convert::Infallible;
use zcash_client_backend::proposal::Proposal;
use zcash_primitives::transaction::fees::zip317;
use zcash_protocol::value::{BalanceError, Zatoshis};
use crate::wallet::output::OutputRef;
pub(crate) type ProportionalFeeProposal = Proposal<zip317::FeeRule, OutputRef>;
pub(crate) type ProportionalFeeShieldProposal = Proposal<zip317::FeeRule, Infallible>;
#[derive(Debug, Clone)]
pub(crate) enum ZingoProposal {
Transfer(ProportionalFeeProposal),
Shield(ProportionalFeeShieldProposal),
}
pub(crate) fn total_payment_amount(
proposal: &ProportionalFeeProposal,
) -> Result<Zatoshis, BalanceError> {
proposal
.steps()
.iter()
.map(|step| step.transaction_request())
.try_fold(Zatoshis::ZERO, |acc, request| {
(acc + request.total()?).ok_or(BalanceError::Overflow)
})
}
pub(crate) fn total_fee(proposal: &ProportionalFeeProposal) -> Result<Zatoshis, BalanceError> {
proposal
.steps()
.iter()
.map(|step| step.balance().fee_required())
.try_fold(Zatoshis::ZERO, |acc, fee| {
(acc + fee).ok_or(BalanceError::Overflow)
})
}
#[cfg(test)]
mod tests {
use zcash_protocol::value::Zatoshis;
use crate::mocks;
#[test]
fn total_payment_amount() {
let proposal = mocks::proposal::ProposalBuilder::default().build();
assert_eq!(
super::total_payment_amount(&proposal).unwrap(),
Zatoshis::from_u64(100_000).unwrap()
);
}
#[test]
fn total_fee() {
let proposal = mocks::proposal::ProposalBuilder::default().build();
assert_eq!(
super::total_fee(&proposal).unwrap(),
Zatoshis::from_u64(20_000).unwrap()
);
}
}