Moves `subsidy.rs` to `zebra-chain`, refactors funding streams into structs, splits them into pre/post NU6 funding streams, and adds them as a field on `testnet::Parameters`

This commit is contained in:
Arya 2024-07-23 12:40:20 -04:00
parent 502b174c97
commit 930c488bf7
13 changed files with 304 additions and 144 deletions

View File

@ -22,7 +22,7 @@ mod transaction;
pub mod arbitrary;
pub use genesis::*;
pub use network::{magic::Magic, testnet, Network, NetworkKind};
pub use network::{magic::Magic, subsidy, testnet, Network, NetworkKind};
pub use network_upgrade::*;
pub use transaction::*;

View File

@ -10,6 +10,7 @@ use crate::{
};
pub mod magic;
pub mod subsidy;
pub mod testnet;
#[cfg(test)]

View File

@ -1,13 +1,11 @@
//! Constants for Block Subsidy and Funding Streams
use std::collections::HashMap;
use lazy_static::lazy_static;
use zebra_chain::{
use crate::{
amount::COIN,
block::{Height, HeightDiff},
parameters::{Network, NetworkKind, NetworkUpgrade},
parameters::{Network, NetworkUpgrade},
};
/// The largest block subsidy, used before the first halving.
@ -60,76 +58,182 @@ pub const FUNDING_STREAM_RECEIVER_DENOMINATOR: u64 = 100;
/// [ZIP-214]: https://zips.z.cash/zip-0214
pub const FUNDING_STREAM_SPECIFICATION: &str = "https://zips.z.cash/zip-0214";
// TODO: use a struct for the info for each funding stream, like zcashd does:
// https://github.com/zcash/zcash/blob/3f09cfa00a3c90336580a127e0096d99e25a38d6/src/consensus/funding.cpp#L13-L32
/// Funding stream recipients and height ranges.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FundingStreams {
recipients: Vec<FundingStreamRecipient>,
height_range: std::ops::Range<Height>,
}
impl FundingStreams {
/// Returns height range where these [`FundingStreams`] should apply.
pub fn height_range(&self) -> &std::ops::Range<Height> {
&self.height_range
}
/// Returns recipients of these [`FundingStreams`].
pub fn recipients(&self) -> &[FundingStreamRecipient] {
&self.recipients
}
/// Returns a recipient with the provided receiver.
pub fn recipient_by_receiver(
&self,
receiver: FundingStreamReceiver,
) -> Option<&FundingStreamRecipient> {
self.recipients
.iter()
.find(|recipient| recipient.receiver() == receiver)
}
}
/// A funding stream recipient as specified in [protocol specification §7.10.1][7.10.1]
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FundingStreamRecipient {
receiver: FundingStreamReceiver,
name: String,
numerator: u64,
addresses: Vec<String>,
}
impl FundingStreamRecipient {
/// Creates a new [`FundingStreamRecipient`].
pub fn new(
receiver: FundingStreamReceiver,
name: impl Into<String>,
numerator: u64,
addresses: Vec<String>,
) -> Self {
Self {
receiver,
name: name.into(),
numerator,
addresses,
}
}
/// Returns the receiver of this funding stream.
pub fn receiver(&self) -> FundingStreamReceiver {
self.receiver
}
/// Returns the name of this funding stream.
pub fn name(&self) -> &str {
&self.name
}
/// Returns the numerator for this funding stream.
pub fn numerator(&self) -> u64 {
self.numerator
}
/// Returns the receiver of this funding stream.
pub fn addresses(&self) -> &[String] {
&self.addresses
}
}
lazy_static! {
/// The name for each funding stream receiver, as described in [ZIP-1014] and [`zcashd`].
///
/// [ZIP-1014]: https://zips.z.cash/zip-1014#abstract
/// [`zcashd`]: https://github.com/zcash/zcash/blob/3f09cfa00a3c90336580a127e0096d99e25a38d6/src/consensus/funding.cpp#L13-L32
pub static ref FUNDING_STREAM_NAMES: HashMap<FundingStreamReceiver, &'static str> = {
let mut hash_map = HashMap::new();
hash_map.insert(FundingStreamReceiver::Ecc, "Electric Coin Company");
hash_map.insert(FundingStreamReceiver::ZcashFoundation, "Zcash Foundation");
hash_map.insert(FundingStreamReceiver::MajorGrants, "Major Grants");
hash_map
/// The pre-NU6 funding streams for Mainnet
pub static ref PRE_NU6_FUNDING_STREAMS_MAINNET: FundingStreams = FundingStreams {
recipients: vec![
FundingStreamRecipient::new(
FundingStreamReceiver::Ecc,
"Electric Coin Company",
7,
FUNDING_STREAM_ECC_ADDRESSES_MAINNET
.iter()
.map(ToString::to_string)
.collect(),
),
FundingStreamRecipient::new(
FundingStreamReceiver::ZcashFoundation,
"Zcash Foundation",
5,
FUNDING_STREAM_ZF_ADDRESSES_MAINNET
.iter()
.map(ToString::to_string)
.collect(),
),
FundingStreamRecipient::new(
FundingStreamReceiver::MajorGrants,
"Major Grants",
8,
FUNDING_STREAM_MG_ADDRESSES_MAINNET
.iter()
.map(ToString::to_string)
.collect(),
),
],
height_range: Height(1_046_400)..Height(2_726_400),
};
/// The numerator for each funding stream receiver category
/// as described in [protocol specification §7.10.1][7.10.1].
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub static ref FUNDING_STREAM_RECEIVER_NUMERATORS: HashMap<FundingStreamReceiver, u64> = {
let mut hash_map = HashMap::new();
hash_map.insert(FundingStreamReceiver::Ecc, 7);
hash_map.insert(FundingStreamReceiver::ZcashFoundation, 5);
hash_map.insert(FundingStreamReceiver::MajorGrants, 8);
hash_map
/// The pre-NU6 funding streams for Testnet
pub static ref PRE_NU6_FUNDING_STREAMS_TESTNET: FundingStreams = FundingStreams {
recipients: vec![
FundingStreamRecipient::new(
FundingStreamReceiver::Ecc,
"Electric Coin Company",
7,
FUNDING_STREAM_ECC_ADDRESSES_TESTNET
.iter()
.map(ToString::to_string)
.collect(),
),
FundingStreamRecipient::new(
FundingStreamReceiver::ZcashFoundation,
"Zcash Foundation",
5,
FUNDING_STREAM_ZF_ADDRESSES_TESTNET
.iter()
.map(ToString::to_string)
.collect(),
),
FundingStreamRecipient::new(
FundingStreamReceiver::MajorGrants,
"Major Grants",
8,
FUNDING_STREAM_MG_ADDRESSES_TESTNET
.iter()
.map(ToString::to_string)
.collect(),
),
],
height_range: Height(1_028_500)..Height(2_796_000),
};
/// Start and end Heights for funding streams
/// as described in [protocol specification §7.10.1][7.10.1].
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
pub static ref FUNDING_STREAM_HEIGHT_RANGES: HashMap<NetworkKind, std::ops::Range<Height>> = {
let mut hash_map = HashMap::new();
hash_map.insert(NetworkKind::Mainnet, Height(1_046_400)..Height(2_726_400));
hash_map.insert(NetworkKind::Testnet, Height(1_028_500)..Height(2_796_000));
hash_map.insert(NetworkKind::Regtest, Height(1_028_500)..Height(2_796_000));
hash_map
/// The post-NU6 funding streams for Mainnet
pub static ref POST_NU6_FUNDING_STREAMS_MAINNET: FundingStreams = FundingStreams {
recipients: vec![
FundingStreamRecipient::new(
FundingStreamReceiver::MajorGrants,
"Major Grants",
8,
FUNDING_STREAM_MG_ADDRESSES_MAINNET
.iter()
.map(ToString::to_string)
.collect(),
),
],
height_range: Height(2_726_400)..Height(3_146_400),
};
/// Convenient storage for all addresses, for all receivers and networks
pub static ref FUNDING_STREAM_ADDRESSES: HashMap<NetworkKind, HashMap<FundingStreamReceiver, Vec<String>>> = {
let mut addresses_by_network = HashMap::with_capacity(2);
// Mainnet addresses
let mut mainnet_addresses = HashMap::with_capacity(3);
mainnet_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_MAINNET.iter().map(|a| a.to_string()).collect());
mainnet_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_MAINNET.iter().map(|a| a.to_string()).collect());
mainnet_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_MAINNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Mainnet, mainnet_addresses);
// Testnet addresses
let mut testnet_addresses = HashMap::with_capacity(3);
testnet_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
testnet_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
testnet_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Testnet, testnet_addresses);
// Regtest addresses
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
// There are no funding stream addresses on Regtest in zcashd, zebrad should do the same for compatibility.
let mut regtest_addresses = HashMap::with_capacity(3);
regtest_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
regtest_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
regtest_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Testnet, regtest_addresses);
addresses_by_network
/// The post-NU6 funding streams for Testnet
pub static ref POST_NU6_FUNDING_STREAMS_TESTNET: FundingStreams = FundingStreams {
recipients: vec![
FundingStreamRecipient::new(
FundingStreamReceiver::MajorGrants,
"Major Grants",
8,
FUNDING_STREAM_MG_ADDRESSES_TESTNET
.iter()
.map(ToString::to_string)
.collect(),
),
],
height_range: Height(2_942_000)..Height(3_362_000),
};
}
@ -200,9 +304,6 @@ pub const FUNDING_STREAM_ECC_ADDRESSES_MAINNET: [&str; FUNDING_STREAMS_NUM_ADDRE
/// Functionality specific to block subsidy-related consensus rules
pub trait ParameterSubsidy {
/// Number of addresses for each funding stream in the Network.
/// [7.10]: <https://zips.z.cash/protocol/protocol.pdf#fundingstreams>
fn num_funding_streams(&self) -> usize;
/// Returns the minimum height after the first halving
/// as described in [protocol specification §7.10][7.10]
///
@ -212,14 +313,6 @@ pub trait ParameterSubsidy {
/// Network methods related to Block Subsidy and Funding Streams
impl ParameterSubsidy for Network {
fn num_funding_streams(&self) -> usize {
match self {
Network::Mainnet => FUNDING_STREAMS_NUM_ADDRESSES_MAINNET,
// TODO: Check what zcashd does here, consider adding a field to `NetworkParamters` to make this configurable.
Network::Testnet(_params) => FUNDING_STREAMS_NUM_ADDRESSES_TESTNET,
}
}
fn height_for_first_halving(&self) -> Height {
// First halving on Mainnet is at Canopy
// while in Testnet is at block constant height of `1_116_000`

View File

@ -11,7 +11,13 @@ use crate::{
work::difficulty::{ExpandedDifficulty, U256},
};
use super::magic::Magic;
use super::{
magic::Magic,
subsidy::{
FundingStreams, POST_NU6_FUNDING_STREAMS_MAINNET, POST_NU6_FUNDING_STREAMS_TESTNET,
PRE_NU6_FUNDING_STREAMS_MAINNET, PRE_NU6_FUNDING_STREAMS_TESTNET,
},
};
/// The Regtest NU5 activation height in tests
// TODO: Serialize testnet parameters in Config then remove this and use a configured NU5 activation height.
@ -79,6 +85,10 @@ pub struct ParametersBuilder {
activation_heights: BTreeMap<Height, NetworkUpgrade>,
/// Slow start interval for this network
slow_start_interval: Height,
/// Pre-NU6 funding streams for this network
pre_nu6_funding_streams: FundingStreams,
/// Post-NU6 funding streams for this network
post_nu6_funding_streams: FundingStreams,
/// Target difficulty limit for this network
target_difficulty_limit: ExpandedDifficulty,
/// A flag for disabling proof-of-work checks when Zebra is validating blocks
@ -113,6 +123,8 @@ impl Default for ParametersBuilder {
.to_expanded()
.expect("difficulty limits are valid expanded values"),
disable_pow: false,
pre_nu6_funding_streams: PRE_NU6_FUNDING_STREAMS_TESTNET.clone(),
post_nu6_funding_streams: POST_NU6_FUNDING_STREAMS_TESTNET.clone(),
}
}
}
@ -263,6 +275,8 @@ impl ParametersBuilder {
genesis_hash,
activation_heights,
slow_start_interval,
pre_nu6_funding_streams,
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
} = self;
@ -273,6 +287,8 @@ impl ParametersBuilder {
activation_heights,
slow_start_interval,
slow_start_shift: Height(slow_start_interval.0 / 2),
pre_nu6_funding_streams,
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
}
@ -291,6 +307,8 @@ impl ParametersBuilder {
genesis_hash,
activation_heights,
slow_start_interval,
pre_nu6_funding_streams,
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
} = Self::default();
@ -299,6 +317,8 @@ impl ParametersBuilder {
&& self.network_magic == network_magic
&& self.genesis_hash == genesis_hash
&& self.slow_start_interval == slow_start_interval
&& self.pre_nu6_funding_streams == pre_nu6_funding_streams
&& self.post_nu6_funding_streams == post_nu6_funding_streams
&& self.target_difficulty_limit == target_difficulty_limit
&& self.disable_pow == disable_pow
}
@ -323,6 +343,10 @@ pub struct Parameters {
slow_start_interval: Height,
/// Slow start shift for this network, always half the slow start interval
slow_start_shift: Height,
/// Pre-NU6 funding streams for this network
pre_nu6_funding_streams: FundingStreams,
/// Post-NU6 funding streams for this network
post_nu6_funding_streams: FundingStreams,
/// Target difficulty limit for this network
target_difficulty_limit: ExpandedDifficulty,
/// A flag for disabling proof-of-work checks when Zebra is validating blocks
@ -396,6 +420,8 @@ impl Parameters {
activation_heights: _,
slow_start_interval,
slow_start_shift,
pre_nu6_funding_streams,
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
} = Self::new_regtest(None, None);
@ -404,6 +430,8 @@ impl Parameters {
&& self.genesis_hash == genesis_hash
&& self.slow_start_interval == slow_start_interval
&& self.slow_start_shift == slow_start_shift
&& self.pre_nu6_funding_streams == pre_nu6_funding_streams
&& self.post_nu6_funding_streams == post_nu6_funding_streams
&& self.target_difficulty_limit == target_difficulty_limit
&& self.disable_pow == disable_pow
}
@ -438,6 +466,16 @@ impl Parameters {
self.slow_start_shift
}
/// Returns pre-NU6 funding streams for this network
pub fn pre_nu6_funding_streams(&self) -> &FundingStreams {
&self.pre_nu6_funding_streams
}
/// Returns post-NU6 funding streams for this network
pub fn post_nu6_funding_streams(&self) -> &FundingStreams {
&self.post_nu6_funding_streams
}
/// Returns the target difficulty limit for this network
pub fn target_difficulty_limit(&self) -> ExpandedDifficulty {
self.target_difficulty_limit
@ -476,4 +514,31 @@ impl Network {
SLOW_START_SHIFT
}
}
/// Returns pre-NU6 funding streams for this network
pub fn pre_nu6_funding_streams(&self) -> &FundingStreams {
if let Self::Testnet(params) = self {
params.pre_nu6_funding_streams()
} else {
&PRE_NU6_FUNDING_STREAMS_MAINNET
}
}
/// Returns post-NU6 funding streams for this network
pub fn post_nu6_funding_streams(&self) -> &FundingStreams {
if let Self::Testnet(params) = self {
params.pre_nu6_funding_streams()
} else {
&POST_NU6_FUNDING_STREAMS_MAINNET
}
}
/// Returns funding streams for this network at the provided height
pub fn funding_streams(&self, height: Height) -> &FundingStreams {
if NetworkUpgrade::current(self, height) < NetworkUpgrade::Nu6 {
self.pre_nu6_funding_streams()
} else {
self.post_nu6_funding_streams()
}
}
}

View File

@ -7,12 +7,12 @@ use std::{collections::HashMap, str::FromStr};
use zebra_chain::{
amount::{Amount, Error, NonNegative},
block::Height,
parameters::{Network, NetworkUpgrade::*},
parameters::{subsidy::*, Network, NetworkUpgrade::*},
transaction::Transaction,
transparent::{self, Script},
};
use crate::{block::subsidy::general::block_subsidy, parameters::subsidy::*};
use crate::block::subsidy::general::block_subsidy;
#[cfg(test)]
mod tests;
@ -29,19 +29,19 @@ pub fn funding_stream_values(
let mut results = HashMap::new();
if height >= canopy_height {
let range = FUNDING_STREAM_HEIGHT_RANGES.get(&network.kind()).unwrap();
if range.contains(&height) {
let funding_streams = network.funding_streams(height);
if funding_streams.height_range().contains(&height) {
let block_subsidy = block_subsidy(height, network)?;
for (&receiver, &numerator) in FUNDING_STREAM_RECEIVER_NUMERATORS.iter() {
for recipient in funding_streams.recipients() {
// - 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)?;
let amount_value = ((block_subsidy * recipient.numerator())?
/ FUNDING_STREAM_RECEIVER_DENOMINATOR)?;
results.insert(receiver, amount_value);
results.insert(recipient.receiver(), amount_value);
}
}
}
@ -77,20 +77,23 @@ fn funding_stream_address_period(height: Height, network: &Network) -> u32 {
///
/// [7.10]: https://zips.z.cash/protocol/protocol.pdf#fundingstreams
fn funding_stream_address_index(height: Height, network: &Network) -> usize {
let num_addresses = network.num_funding_streams();
let funding_streams = network.funding_streams(height);
let index = 1u32
.checked_add(funding_stream_address_period(height, network))
.expect("no overflow should happen in this sum")
.checked_sub(funding_stream_address_period(
FUNDING_STREAM_HEIGHT_RANGES
.get(&network.kind())
.unwrap()
.start,
funding_streams.height_range().start,
network,
))
.expect("no overflow should happen in this sub") as usize;
let num_addresses = funding_streams
.recipients()
.first()
.map(|recipient| recipient.addresses().len())
.unwrap_or_default();
assert!(index > 0 && index <= num_addresses);
// spec formula will output an index starting at 1 but
// Zebra indices for addresses start at zero, return converted.
@ -107,21 +110,31 @@ pub fn funding_stream_address(
receiver: FundingStreamReceiver,
) -> transparent::Address {
let index = funding_stream_address_index(height, network);
let address = &FUNDING_STREAM_ADDRESSES
.get(&network.kind())
.expect("there is always another hash map as value for a given valid network")
.get(&receiver)
.expect("in the inner hash map there is always a vector of strings with addresses")[index];
let funding_streams = network.funding_streams(height);
let address = &funding_streams
.recipient_by_receiver(receiver)
// TODO: Change return type to option and return None here instead of panicking
.unwrap()
.addresses()
.get(index)
// TODO: Change return type to option and return None here instead of panicking
.unwrap();
transparent::Address::from_str(address).expect("address should deserialize")
}
/// Return a human-readable name and a specification URL for the funding stream `receiver`.
pub fn funding_stream_recipient_info(
network: &Network,
height: Height,
receiver: FundingStreamReceiver,
) -> (&'static str, &'static str) {
let name = FUNDING_STREAM_NAMES
.get(&receiver)
.expect("all funding streams have a name");
) -> (String, &'static str) {
let name = network
.funding_streams(height)
.recipient_by_receiver(receiver)
// TODO: Replace with optional return type
.unwrap()
.name()
.to_string();
(name, FUNDING_STREAM_SPECIFICATION)
}

View File

@ -1,6 +1,7 @@
//! Tests for funding streams.
use color_eyre::Report;
use zebra_chain::parameters::subsidy::FundingStreamReceiver;
use super::*;
@ -44,7 +45,8 @@ fn test_funding_stream_values() -> Result<(), Report> {
);
// funding stream period is ending
let range = FUNDING_STREAM_HEIGHT_RANGES.get(&network.kind()).unwrap();
let funding_streams = network.pre_nu6_funding_streams();
let range = funding_streams.height_range();
let end = range.end;
let last = end - 1;
@ -61,15 +63,16 @@ fn test_funding_stream_values() -> Result<(), Report> {
#[test]
fn test_funding_stream_addresses() -> Result<(), Report> {
let _init_guard = zebra_test::init();
for (network, receivers) in FUNDING_STREAM_ADDRESSES.iter() {
for (receiver, addresses) in receivers {
for address in addresses {
for network in Network::iter() {
for funding_stream_recipient in network.pre_nu6_funding_streams().recipients() {
let receiver = funding_stream_recipient.receiver();
for address in funding_stream_recipient.addresses() {
let address =
transparent::Address::from_str(address).expect("address should deserialize");
assert_eq!(
&address.network_kind(),
network,
address.network_kind(),
network.kind(),
"incorrect network for {receiver:?} funding stream address constant: {address}",
);

View File

@ -7,11 +7,11 @@ use std::collections::HashSet;
use zebra_chain::{
amount::{Amount, Error, NonNegative},
block::{Height, HeightDiff},
parameters::{Network, NetworkUpgrade::*},
parameters::{subsidy::*, Network, NetworkUpgrade::*},
transaction::Transaction,
};
use crate::{funding_stream_values, parameters::subsidy::*};
use crate::funding_stream_values;
/// The divisor used for halvings.
///

View File

@ -36,7 +36,6 @@
mod block;
mod checkpoint;
mod parameters;
mod primitives;
mod script;
@ -64,7 +63,6 @@ pub use checkpoint::{
};
pub use config::Config;
pub use error::BlockError;
pub use parameters::{FundingStreamReceiver, ParameterSubsidy};
pub use primitives::{ed25519, groth16, halo2, redjubjub, redpallas};
pub use router::RouterError;

View File

@ -1,17 +0,0 @@
//! The consensus parameters for each Zcash network.
//!
//! This module contains the consensus parameters which are required for
//! verification.
//!
//! Some consensus parameters change based on network upgrades. Each network
//! upgrade happens at a particular block height. Some parameters have a value
//! (or function) before the upgrade height, at the upgrade height, and after
//! the upgrade height. (For example, the value of the reserved field in the
//! block header during the Heartwood upgrade.)
//!
//! Typically, consensus parameters are accessed via a function that takes a
//! `Network` and `block::Height`.
pub mod subsidy;
pub use subsidy::*;

View File

@ -14,7 +14,7 @@ use zebra_chain::{
block::{self, Block, Height, TryIntoHeight},
chain_sync_status::ChainSyncStatus,
chain_tip::ChainTip,
parameters::{Network, NetworkKind, POW_AVERAGING_WINDOW},
parameters::{subsidy::ParameterSubsidy, Network, NetworkKind, POW_AVERAGING_WINDOW},
primitives,
serialization::ZcashDeserializeInto,
transparent::{
@ -22,10 +22,7 @@ use zebra_chain::{
},
work::difficulty::{ParameterDifficulty as _, U256},
};
use zebra_consensus::{
funding_stream_address, funding_stream_values, miner_subsidy, ParameterSubsidy as _,
RouterError,
};
use zebra_consensus::{funding_stream_address, funding_stream_values, miner_subsidy, RouterError};
use zebra_network::AddressBookPeers;
use zebra_node_services::mempool;
use zebra_state::{ReadRequest, ReadResponse};
@ -1202,7 +1199,10 @@ where
.iter()
.map(|(receiver, value)| {
let address = funding_stream_address(height, &network, *receiver);
(*receiver, FundingStream::new(*receiver, *value, address))
(
*receiver,
FundingStream::new(&network, height, *receiver, *value, address),
)
})
.collect();

View File

@ -2,8 +2,10 @@
use jsonrpc_core::ErrorCode;
use zebra_chain::block;
use zebra_consensus::FundingStreamReceiver::{self, *};
use zebra_chain::{
block,
parameters::subsidy::FundingStreamReceiver::{self, *},
};
/// When long polling, the amount of time we wait between mempool queries.
/// (And sync status queries, which we do right before mempool queries.)

View File

@ -14,14 +14,12 @@ use zebra_chain::{
},
chain_sync_status::ChainSyncStatus,
chain_tip::ChainTip,
parameters::{Network, NetworkUpgrade},
parameters::{subsidy::FundingStreamReceiver, Network, NetworkUpgrade},
serialization::ZcashDeserializeInto,
transaction::{Transaction, UnminedTx, VerifiedUnminedTx},
transparent,
};
use zebra_consensus::{
funding_stream_address, funding_stream_values, miner_subsidy, FundingStreamReceiver,
};
use zebra_consensus::{funding_stream_address, funding_stream_values, miner_subsidy};
use zebra_node_services::mempool;
use zebra_state::GetBlockTemplateChainInfo;

View File

@ -2,9 +2,11 @@
use zebra_chain::{
amount::{Amount, NonNegative},
block::Height,
parameters::{subsidy::FundingStreamReceiver, Network},
transparent,
};
use zebra_consensus::{funding_stream_recipient_info, FundingStreamReceiver};
use zebra_consensus::funding_stream_recipient_info;
use crate::methods::get_block_template_rpcs::types::zec::Zec;
@ -64,11 +66,13 @@ pub struct FundingStream {
impl FundingStream {
/// Convert a `receiver`, `value`, and `address` into a `FundingStream` response.
pub fn new(
network: &Network,
height: Height,
receiver: FundingStreamReceiver,
value: Amount<NonNegative>,
address: transparent::Address,
) -> FundingStream {
let (recipient, specification) = funding_stream_recipient_info(receiver);
let (recipient, specification) = funding_stream_recipient_info(network, height, receiver);
FundingStream {
recipient: recipient.to_string(),