Add value_balance() method to Block (#2546)
* add value_balance() method to Block * Fix a comment typo Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
parent
4f96a4bb40
commit
0325aa2517
|
@ -14,7 +14,7 @@ pub mod arbitrary;
|
||||||
#[cfg(any(test, feature = "bench"))]
|
#[cfg(any(test, feature = "bench"))]
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
use std::fmt;
|
use std::{collections::HashMap, fmt};
|
||||||
|
|
||||||
pub use commitment::{ChainHistoryMmrRootHash, Commitment, CommitmentError};
|
pub use commitment::{ChainHistoryMmrRootHash, Commitment, CommitmentError};
|
||||||
pub use hash::Hash;
|
pub use hash::Hash;
|
||||||
|
@ -28,6 +28,7 @@ pub use arbitrary::LedgerState;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
amount::NegativeAllowed,
|
||||||
fmt::DisplayToDebug,
|
fmt::DisplayToDebug,
|
||||||
orchard,
|
orchard,
|
||||||
parameters::{Network, NetworkUpgrade},
|
parameters::{Network, NetworkUpgrade},
|
||||||
|
@ -36,6 +37,7 @@ use crate::{
|
||||||
sprout,
|
sprout,
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
transparent,
|
transparent,
|
||||||
|
value_balance::{ValueBalance, ValueBalanceError},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A Zcash block, containing a header and a list of transactions.
|
/// A Zcash block, containing a header and a list of transactions.
|
||||||
|
@ -143,6 +145,22 @@ impl Block {
|
||||||
.map(|transaction| transaction.orchard_nullifiers())
|
.map(|transaction| transaction.orchard_nullifiers())
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get all the value balances from this block by summing all the value balances
|
||||||
|
/// in each transaction the block has.
|
||||||
|
///
|
||||||
|
/// `utxos` must contain the utxos of every input in the block,
|
||||||
|
/// including UTXOs created by a transaction in this block,
|
||||||
|
/// then spent by a later transaction that's also in this block.
|
||||||
|
pub fn value_balance(
|
||||||
|
&self,
|
||||||
|
utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
|
||||||
|
) -> Result<ValueBalance<NegativeAllowed>, ValueBalanceError> {
|
||||||
|
self.transactions
|
||||||
|
.iter()
|
||||||
|
.flat_map(|t| t.value_balance(utxos))
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Block> for Hash {
|
impl<'a> From<&'a Block> for Hash {
|
||||||
|
|
|
@ -184,3 +184,28 @@ where
|
||||||
self? - rhs
|
self? - rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<C> std::iter::Sum<ValueBalance<C>> for Result<ValueBalance<C>, ValueBalanceError>
|
||||||
|
where
|
||||||
|
C: Constraint + Copy,
|
||||||
|
{
|
||||||
|
fn sum<I: Iterator<Item = ValueBalance<C>>>(mut iter: I) -> Self {
|
||||||
|
iter.try_fold(ValueBalance::zero(), |acc, value_balance| {
|
||||||
|
Ok(ValueBalance {
|
||||||
|
transparent: (acc.transparent + value_balance.transparent)?,
|
||||||
|
sprout: (acc.sprout + value_balance.sprout)?,
|
||||||
|
sapling: (acc.sapling + value_balance.sapling)?,
|
||||||
|
orchard: (acc.orchard + value_balance.orchard)?,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'amt, C> std::iter::Sum<&'amt ValueBalance<C>> for Result<ValueBalance<C>, ValueBalanceError>
|
||||||
|
where
|
||||||
|
C: Constraint + std::marker::Copy + 'amt,
|
||||||
|
{
|
||||||
|
fn sum<I: Iterator<Item = &'amt ValueBalance<C>>>(iter: I) -> Self {
|
||||||
|
iter.copied().sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -60,4 +60,32 @@ proptest! {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sum(
|
||||||
|
value_balance1 in any::<ValueBalance<NegativeAllowed>>(),
|
||||||
|
value_balance2 in any::<ValueBalance<NegativeAllowed>>(),
|
||||||
|
) {
|
||||||
|
zebra_test::init();
|
||||||
|
|
||||||
|
let collection = vec![value_balance1, value_balance2];
|
||||||
|
|
||||||
|
let transparent = value_balance1.transparent + value_balance2.transparent;
|
||||||
|
let sprout = value_balance1.sprout + value_balance2.sprout;
|
||||||
|
let sapling = value_balance1.sapling + value_balance2.sapling;
|
||||||
|
let orchard = value_balance1.orchard + value_balance2.orchard;
|
||||||
|
|
||||||
|
match (transparent, sprout, sapling, orchard) {
|
||||||
|
(Ok(transparent), Ok(sprout), Ok(sapling), Ok(orchard)) => prop_assert_eq!(
|
||||||
|
collection.iter().sum::<Result<ValueBalance<NegativeAllowed>, ValueBalanceError>>(),
|
||||||
|
Ok(ValueBalance {
|
||||||
|
transparent,
|
||||||
|
sprout,
|
||||||
|
sapling,
|
||||||
|
orchard,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
_ => prop_assert!(matches!(collection.iter().sum(), Err(ValueBalanceError::AmountError(_))))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue