-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Validate funding stream amounts in coinbase transaction (#3017)
* validate funding stream amounts in the coinbase * clippy * use `i64::from()` and remove `number()` method from `Amount` * move tests to their own file * refactor the funding stream check * use `Amount`s in funding streams calculation * remove unused import * add import to tests * expand test vectors * add notes to `funding_stream_values()`
- Loading branch information
1 parent
f7c1907
commit 62bfa15
Showing
8 changed files
with
267 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//! Funding Streams calculations. - [§7.7][7.7] | ||
//! | ||
//! [7.7]: https://zips.z.cash/protocol/protocol.pdf#subsidies | ||
use zebra_chain::{ | ||
amount::{Amount, Error, NonNegative}, | ||
block::Height, | ||
parameters::{Network, NetworkUpgrade::*}, | ||
}; | ||
|
||
use crate::{ | ||
block::subsidy::general::block_subsidy, | ||
parameters::subsidy::{ | ||
FundingStreamReceiver, FUNDING_STREAM_HEIGHT_RANGES, FUNDING_STREAM_RECEIVER_DENOMINATOR, | ||
FUNDING_STREAM_RECEIVER_NUMERATORS, | ||
}, | ||
}; | ||
|
||
#[cfg(test)] | ||
mod tests; | ||
|
||
/// Returns the `fs.Value(height)` for each stream receiver | ||
/// as described in [protocol specification §7.7][7.7] | ||
/// | ||
/// [7.7]: https://zips.z.cash/protocol/protocol.pdf#subsidies | ||
use std::collections::HashMap; | ||
pub fn funding_stream_values( | ||
height: Height, | ||
network: Network, | ||
) -> Result<HashMap<FundingStreamReceiver, Amount<NonNegative>>, Error> { | ||
let canopy_height = Canopy.activation_height(network).unwrap(); | ||
let mut results = HashMap::new(); | ||
|
||
if height >= canopy_height { | ||
let range = FUNDING_STREAM_HEIGHT_RANGES.get(&network).unwrap(); | ||
if range.contains(&height) { | ||
let block_subsidy = block_subsidy(height, network)?; | ||
for (&receiver, &numerator) in FUNDING_STREAM_RECEIVER_NUMERATORS.iter() { | ||
// - Spec equation: `fs.value = floor(block_subsidy(height)*(fs.numerator/fs.denominator))`: | ||
// https://zips.z.cash/protocol/protocol.pdf#subsidies | ||
// - In Rust, "integer division rounds towards zero": | ||
// https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators | ||
// This is the same as `floor()`, because these numbers are all positive. | ||
let amount_value = | ||
((block_subsidy * numerator)? / FUNDING_STREAM_RECEIVER_DENOMINATOR)?; | ||
|
||
results.insert(receiver, amount_value); | ||
} | ||
} | ||
} | ||
Ok(results) | ||
} |
56 changes: 56 additions & 0 deletions
56
zebra-consensus/src/block/subsidy/funding_streams/tests.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use super::*; | ||
use color_eyre::Report; | ||
use std::convert::TryFrom; | ||
|
||
#[test] | ||
// Check funding streams are correct in the entire period. | ||
fn test_funding_stream_values() -> Result<(), Report> { | ||
zebra_test::init(); | ||
let network = Network::Mainnet; | ||
|
||
// funding streams not active | ||
let canopy_height_minus1 = Canopy.activation_height(network).unwrap() - 1; | ||
assert!(funding_stream_values(canopy_height_minus1.unwrap(), network)?.is_empty()); | ||
|
||
// funding stream is active | ||
let canopy_height = Canopy.activation_height(network); | ||
let canopy_height_plus1 = Canopy.activation_height(network).unwrap() + 1; | ||
let canopy_height_plus2 = Canopy.activation_height(network).unwrap() + 2; | ||
|
||
let mut hash_map = HashMap::new(); | ||
hash_map.insert(FundingStreamReceiver::Ecc, Amount::try_from(21_875_000)?); | ||
hash_map.insert( | ||
FundingStreamReceiver::ZcashFoundation, | ||
Amount::try_from(15_625_000)?, | ||
); | ||
hash_map.insert( | ||
FundingStreamReceiver::MajorGrants, | ||
Amount::try_from(25_000_000)?, | ||
); | ||
|
||
assert_eq!( | ||
funding_stream_values(canopy_height.unwrap(), network).unwrap(), | ||
hash_map | ||
); | ||
assert_eq!( | ||
funding_stream_values(canopy_height_plus1.unwrap(), network).unwrap(), | ||
hash_map | ||
); | ||
assert_eq!( | ||
funding_stream_values(canopy_height_plus2.unwrap(), network).unwrap(), | ||
hash_map | ||
); | ||
|
||
// funding stream period is ending | ||
let range = FUNDING_STREAM_HEIGHT_RANGES.get(&network).unwrap(); | ||
let end = range.end; | ||
let last = end - 1; | ||
|
||
assert_eq!( | ||
funding_stream_values(last.unwrap(), network).unwrap(), | ||
hash_map | ||
); | ||
assert!(funding_stream_values(end, network)?.is_empty()); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters