Skip to content

Commit

Permalink
feat(regtest): Add regtest halving interval and port test (#8888)
Browse files Browse the repository at this point in the history
* add halving interval to regtest and to custom testnet

* add nuparams.py rpc test

* fix inconsistency in nu6 name in rpc methods

* rename `halving_interval` to `pre_blossom_halving_interval` in the config

* make fixes

* Suggestion for "feat(regtest): Add regtest halving interval and port test" (#8894)

* adds `height_for_halving_index()` and `num_halvings()` fns

* avoid unnecessary panic

* avoid using constant pre/post blossom halving intervals in num_halvings()

* make regtest and testnet constant more private

* move `height_for_halving_index`

* fmt

* add a `funding_stream_address_change_interval` method

* add checked operations to `height_for_halving_index` fn

* add post_blossom interval as paramneters + other refactors

* rename function

* fix docs

* move constant

* Updates `new_regtest()` method to return a Testnet without funding streams, updates funding stream setter methods to set a flag indicating that parameters affecting the funding stream address period should be locked, updates the setter methods for parameters that affect the funding stream address period to panic if those parameters should be locked. (#8921)

---------

Co-authored-by: Arya <[email protected]>
  • Loading branch information
oxarbitrage and arya2 authored Oct 10, 2024
1 parent 8cd4d96 commit f2e7bc9
Show file tree
Hide file tree
Showing 11 changed files with 586 additions and 109 deletions.
96 changes: 91 additions & 5 deletions zebra-chain/src/parameters/network/subsidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ pub const POST_BLOSSOM_HALVING_INTERVAL: HeightDiff =
/// as specified in [protocol specification §7.10.1][7.10.1]
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub const FIRST_HALVING_TESTNET: Height = Height(1_116_000);
pub(crate) const FIRST_HALVING_TESTNET: Height = Height(1_116_000);

/// The first halving height in the regtest is at block height `287`.
const FIRST_HALVING_REGTEST: Height = Height(287);

/// The funding stream receiver categories.
#[derive(Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -378,6 +381,20 @@ pub trait ParameterSubsidy {
///
/// [7.10]: <https://zips.z.cash/protocol/protocol.pdf#fundingstreams>
fn height_for_first_halving(&self) -> Height;

/// Returns the halving interval after Blossom
fn post_blossom_halving_interval(&self) -> HeightDiff;

/// Returns the halving interval before Blossom
fn pre_blossom_halving_interval(&self) -> HeightDiff;

/// Returns the address change interval for funding streams
/// as described in [protocol specification §7.10][7.10].
///
/// > FSRecipientChangeInterval := PostBlossomHalvingInterval / 48
///
/// [7.10]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
fn funding_stream_address_change_interval(&self) -> HeightDiff;
}

/// Network methods related to Block Subsidy and Funding Streams
Expand All @@ -390,10 +407,35 @@ impl ParameterSubsidy for Network {
Network::Mainnet => NetworkUpgrade::Canopy
.activation_height(self)
.expect("canopy activation height should be available"),
// TODO: Check what zcashd does here, consider adding a field to `testnet::Parameters` to make this configurable.
Network::Testnet(_params) => FIRST_HALVING_TESTNET,
Network::Testnet(params) => {
if params.is_regtest() {
FIRST_HALVING_REGTEST
} else if params.is_default_testnet() {
FIRST_HALVING_TESTNET
} else {
height_for_halving(1, self).expect("first halving height should be available")
}
}
}
}

fn post_blossom_halving_interval(&self) -> HeightDiff {
match self {
Network::Mainnet => POST_BLOSSOM_HALVING_INTERVAL,
Network::Testnet(params) => params.post_blossom_halving_interval(),
}
}

fn pre_blossom_halving_interval(&self) -> HeightDiff {
match self {
Network::Mainnet => PRE_BLOSSOM_HALVING_INTERVAL,
Network::Testnet(params) => params.pre_blossom_halving_interval(),
}
}

fn funding_stream_address_change_interval(&self) -> HeightDiff {
self.post_blossom_halving_interval() / 48
}
}

/// List of addresses for the Zcash Foundation funding stream in the Mainnet.
Expand Down Expand Up @@ -514,10 +556,54 @@ pub fn funding_stream_address_period<N: ParameterSubsidy>(height: Height, networ

let height_after_first_halving = height - network.height_for_first_halving();

let address_period = (height_after_first_halving + POST_BLOSSOM_HALVING_INTERVAL)
/ FUNDING_STREAM_ADDRESS_CHANGE_INTERVAL;
let address_period = (height_after_first_halving + network.post_blossom_halving_interval())
/ network.funding_stream_address_change_interval();

address_period
.try_into()
.expect("all values are positive and smaller than the input height")
}

/// The first block height of the halving at the provided halving index for a network.
///
/// See `Halving(height)`, as described in [protocol specification §7.8][7.8]
///
/// [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies
pub fn height_for_halving(halving: u32, network: &Network) -> Option<Height> {
if halving == 0 {
return Some(Height(0));
}

let slow_start_shift = i64::from(network.slow_start_shift().0);
let blossom_height = i64::from(
NetworkUpgrade::Blossom
.activation_height(network)
.expect("blossom activation height should be available")
.0,
);
let pre_blossom_halving_interval = network.pre_blossom_halving_interval();
let halving_index = i64::from(halving);

let unscaled_height = halving_index
.checked_mul(pre_blossom_halving_interval)
.expect("Multiplication overflow: consider reducing the halving interval");

let pre_blossom_height = unscaled_height
.min(blossom_height)
.checked_add(slow_start_shift)
.expect("Addition overflow: consider reducing the halving interval");

let post_blossom_height = 0
.max(unscaled_height - blossom_height)
.checked_mul(i64::from(BLOSSOM_POW_TARGET_SPACING_RATIO))
.expect("Multiplication overflow: consider reducing the halving interval")
.checked_add(slow_start_shift)
.expect("Addition overflow: consider reducing the halving interval");

let height = pre_blossom_height
.checked_add(post_blossom_height)
.expect("Addition overflow: consider reducing the halving interval");

let height = u32::try_from(height).ok()?;
height.try_into().ok()
}
Loading

0 comments on commit f2e7bc9

Please sign in to comment.