From 63bd3a4da40bdf176c85344ba8c35889fa2d93f4 Mon Sep 17 00:00:00 2001 From: pasta Date: Sat, 31 Oct 2026 23:58:44 +0000 Subject: [PATCH 1/5] params%feat!: add Release, ChainSetup and the devnet table ChainSetup is a network's parameters at a Release, one ChainParams read through Deref plus extra per-chain values. V23_1 keeps v23.1.8's values and Network gains Devnet with u8 discriminants a test pins. --- meta/dev/src/bin/bsdk_util/bspcheck.rs | 12 +- pkgs/params/src/builder.rs | 32 ++++ pkgs/params/src/consensus.rs | 63 ++++++ pkgs/params/src/deployment.rs | 41 ++++ pkgs/params/src/lib.rs | 35 +++- pkgs/params/src/params/devnet.rs | 176 +++++++++++++++++ pkgs/params/src/params/mainnet.rs | 5 + pkgs/params/src/params/mod.rs | 1 + pkgs/params/src/params/regtest.rs | 4 + pkgs/params/src/params/test3.rs | 4 + pkgs/params/src/prelude.rs | 1 + pkgs/params/src/release.rs | 114 +++++++++++ pkgs/params/src/setup.rs | 178 +++++++++++++++++ pkgs/params/src/setup/tables.rs | 254 +++++++++++++++++++++++++ pkgs/params/tests/setup.rs | 209 ++++++++++++++++++++ 15 files changed, 1115 insertions(+), 14 deletions(-) create mode 100644 pkgs/params/src/builder.rs create mode 100644 pkgs/params/src/params/devnet.rs create mode 100644 pkgs/params/src/release.rs create mode 100644 pkgs/params/src/setup.rs create mode 100644 pkgs/params/src/setup/tables.rs create mode 100644 pkgs/params/tests/setup.rs diff --git a/meta/dev/src/bin/bsdk_util/bspcheck.rs b/meta/dev/src/bin/bsdk_util/bspcheck.rs index 591c16f77..e67a4b3f0 100644 --- a/meta/dev/src/bin/bsdk_util/bspcheck.rs +++ b/meta/dev/src/bin/bsdk_util/bspcheck.rs @@ -112,17 +112,11 @@ mod magic { use dash_params::{ChainParams, MessageStart, Network}; - const KNOWN_NETWORKS: &[&ChainParams] = &[ - Network::Main.chain(), - Network::Testnet3.chain(), - Network::Regtest.chain(), - ]; - fn detect(magic: MessageStart) -> Result<&'static ChainParams, BootstrapError> { - KNOWN_NETWORKS - .iter() + Network::ALL + .into_iter() + .map(Network::chain) .find(|p| p.message_start == magic) - .copied() .ok_or(BootstrapError::UnknownMagic { magic }) } diff --git a/pkgs/params/src/builder.rs b/pkgs/params/src/builder.rs new file mode 100644 index 000000000..78a9f6094 --- /dev/null +++ b/pkgs/params/src/builder.rs @@ -0,0 +1,32 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Builder of the chain parameters a node runs. + +use crate::{ChainSetup, Network, Release}; + +#[cfg(feature = "codec")] +use dash_types::type_id::Unencodable; + +/// Builds the [`ChainSetup`] of a network at a release. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub struct ChainParamsBuilder { + network: Network, + release: Release, +} + +impl ChainParamsBuilder { + /// A builder for `network` at `release`. + pub const fn new(network: Network, release: Release) -> Self { + Self { network, release } + } + + /// The chain parameters. + pub fn build(&self) -> ChainSetup { + ChainSetup::new(self.network, self.release) + } +} diff --git a/pkgs/params/src/consensus.rs b/pkgs/params/src/consensus.rs index e3c97bca9..df1df828a 100644 --- a/pkgs/params/src/consensus.rs +++ b/pkgs/params/src/consensus.rs @@ -16,6 +16,17 @@ use dash_types::type_id::Unencodable; /// Block height paired with its block hash. pub type Checkpoint = (BlockHeight, Hash256); +/// The masternode share of the block value in the classic reward era, in +/// permille, for each block reward reallocation period of three superblock +/// cycles. +/// +/// The first period starts with the first superblock cycle after +/// [`ConsensusParams::brr_height`], and the last share then holds. The same at +/// both releases and on every network. +pub const BRR_PERIODS_PERMILLE: [u16; 19] = [ + 513, 526, 533, 540, 546, 552, 557, 562, 567, 572, 577, 582, 585, 588, 591, 594, 597, 599, 600, +]; + /// Buried deployment positions with hardcoded activation heights. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[cfg_attr(feature = "codec", derive(Unencodable))] @@ -52,12 +63,56 @@ pub enum BuriedDeployment { Withdrawals, } +impl BuriedDeployment { + /// Every buried deployment, in the reference implementation's order. + pub const ALL: [Self; 15] = [ + Self::HeightInCoinbase, + Self::Cltv, + Self::DerSig, + Self::Bip147, + Self::Csv, + Self::Dip0001, + Self::Dip0003, + Self::Dip0008, + Self::Dip0020, + Self::Dip0024, + Self::Brr, + Self::V19, + Self::V20, + Self::MnRr, + Self::Withdrawals, + ]; + + /// The deployment's name, as the `getdeploymentinfo` RPC reports it. + pub const fn name(self) -> &'static str { + match self { + Self::HeightInCoinbase => "bip34", + Self::Cltv => "bip65", + Self::DerSig => "bip66", + Self::Bip147 => "bip147", + Self::Csv => "csv", + Self::Dip0001 => "dip0001", + Self::Dip0003 => "dip0003", + Self::Dip0008 => "dip0008", + Self::Dip0020 => "dip0020", + Self::Dip0024 => "dip0024", + Self::Brr => "realloc", + Self::V19 => "v19", + Self::V20 => "v20", + Self::MnRr => "mn_rr", + Self::Withdrawals => "withdrawals", + } + } +} + /// Parameters that influence chain consensus. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[cfg_attr(feature = "codec", derive(Unencodable))] pub struct ConsensusParams { /// Hash of the genesis block. pub hash_genesis_block: Hash256, + /// Hash of the devnet genesis block (height 1), zero off devnets. + pub hash_devnet_genesis_block: Hash256, /// Number of blocks between subsidy halvings. pub subsidy_halving_interval: i32, /// Block height at which masternode payments @@ -163,6 +218,14 @@ pub struct ConsensusParams { /// Block hash assumed valid for fast initial /// sync. pub default_assume_valid: Hash256, + /// Blocks mined at minimum difficulty at the start of a devnet. A signed + /// count the reference implementation leaves unchecked. + pub minimum_difficulty_blocks: i32, + /// Blocks with a raised subsidy at the start of a devnet. A signed count + /// the reference implementation leaves unchecked. + pub high_subsidy_blocks: i32, + /// Subsidy multiplier for those blocks, which may be zero or negative. + pub high_subsidy_factor: i32, /// LLMQ types the chain runs, in the reference implementation's order. pub llmqs: &'static [LlmqType], /// LLMQ type used for ChainLocks. diff --git a/pkgs/params/src/deployment.rs b/pkgs/params/src/deployment.rs index 292faaea7..d6b548d88 100644 --- a/pkgs/params/src/deployment.rs +++ b/pkgs/params/src/deployment.rs @@ -10,6 +10,36 @@ use bitcoin_units::BlockHeight; #[cfg(feature = "codec")] use dash_types::type_id::Unencodable; +/// Position of a version-bits deployment in the reference implementation's +/// deployment array. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub enum DeploymentPos { + /// `testdummy`, used only for testing. + TestDummy = 0, + /// `v24`, the v24 upgrade. + V24 = 1, + /// `evo_shares`, EvoNode shared collateral (v24 release only). + EvoShares = 2, +} + +impl DeploymentPos { + /// The deployment's name, as the `-vbparams` option and RPC spell it. + pub const fn name(self) -> &'static str { + match self { + Self::TestDummy => "testdummy", + Self::V24 => "v24", + Self::EvoShares => "evo_shares", + } + } + + /// Whether `getblocktemplate` clients may safely ignore the deployment's + /// rule in simplified usage; true for every deployment. + pub const fn gbt_force(self) -> bool { + true + } +} + /// Version bits deployment for a consensus rule change (BIP9). #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[cfg_attr(feature = "codec", derive(Unencodable))] @@ -54,3 +84,14 @@ pub struct Bip9Deployments { /// Deployment enabling EvoNode shared collateral and multiple owner payouts. pub evo_shares: Bip9Deployment, } + +impl Bip9Deployments { + /// The deployment at `pos`. + pub(crate) const fn at(&self, pos: DeploymentPos) -> &Bip9Deployment { + match pos { + DeploymentPos::TestDummy => &self.test_dummy, + DeploymentPos::V24 => &self.v24, + DeploymentPos::EvoShares => &self.evo_shares, + } + } +} diff --git a/pkgs/params/src/lib.rs b/pkgs/params/src/lib.rs index 2bab02bd2..7ac157183 100644 --- a/pkgs/params/src/lib.rs +++ b/pkgs/params/src/lib.rs @@ -4,7 +4,7 @@ // See the accompanying file LICENSE or https://opensource.org/license/MIT // -//! Network parameters for Dash (mainnet, testnet3, regtest). +//! Network parameters for Dash (mainnet, testnet3, devnet, regtest). #![no_std] @@ -13,6 +13,7 @@ extern crate alloc; extern crate std; mod addr; +mod builder; mod chain; mod consensus; mod deployment; @@ -21,37 +22,61 @@ mod llmq; mod params; #[allow(unused_imports, reason = "ergonomic shim, exports may be unused")] mod prelude; +mod release; +mod setup; -use crate::params::{mainnet, regtest, test3}; +use crate::params::{devnet, mainnet, regtest, test3}; #[cfg(feature = "codec")] use dash_types::type_id::Unencodable; pub use addr::AddrParams; +pub use builder::ChainParamsBuilder; pub use chain::{ChainParams, ChainTxData, MessageStart}; -pub use consensus::{BuriedDeployment, Checkpoint, ConsensusParams}; -pub use deployment::{Bip9Deployment, Bip9Deployments}; +pub use consensus::{BuriedDeployment, Checkpoint, ConsensusParams, BRR_PERIODS_PERMILLE}; +pub use deployment::{Bip9Deployment, Bip9Deployments, DeploymentPos}; pub use genesis::GenesisParams; pub use llmq::{LlmqParams, LlmqType}; +pub use release::Release; +pub use setup::{AssumeutxoData, ChainSetup, HardCodedHeights}; /// Dash network identifier. -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +/// +/// The discriminants are stable, 0 to 3 in declaration order. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "codec", derive(Unencodable))] +#[repr(u8)] pub enum Network { /// Production network. Main, /// Public testnet. Testnet3, + /// Development network, the devnet named `devnet`. + Devnet, /// Local regression test network. Regtest, } impl Network { + /// Every network, in discriminant order. + pub const ALL: [Self; 4] = [Self::Main, Self::Testnet3, Self::Devnet, Self::Regtest]; + + /// The network's identifier, `main`, `test`, `devnet` or `regtest`. + pub const fn network_id(self) -> &'static str { + self.chain().network_id + } + + /// The network whose [`network_id`](Self::network_id) is `id`, exactly. + pub fn from_network_id(id: &str) -> Option { + Self::ALL.into_iter().find(|network| network.network_id() == id) + } + /// Full chain parameters for this network. pub const fn chain(self) -> &'static ChainParams { match self { Self::Main => &mainnet::PARAMS, Self::Testnet3 => &test3::PARAMS, + Self::Devnet => &devnet::PARAMS, Self::Regtest => ®test::PARAMS, } } diff --git a/pkgs/params/src/params/devnet.rs b/pkgs/params/src/params/devnet.rs new file mode 100644 index 000000000..a3cfcd37e --- /dev/null +++ b/pkgs/params/src/params/devnet.rs @@ -0,0 +1,176 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Devnet chain parameters, of the devnet named `devnet`. + +use crate::{ + AddrParams, Bip9Deployment, Bip9Deployments, ChainParams, ChainTxData, Checkpoint, ConsensusParams, GenesisParams, + LlmqType, +}; + +use bitcoin_units::{Amount, BlockHeight}; +use dash_num::{Arith256, Hash256}; +use dash_types::Numeric; +use hex_conservative::hex; + +/// Hash of the genesis block, which is regtest's. +const GENESIS_HASH: Hash256 = + Hash256::from_bendian(hex!("000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e")); + +/// Hash of the devnet genesis block (height 1) of the devnet named `devnet`. +const DEVNET_GENESIS_HASH: Hash256 = + Hash256::from_bendian(hex!("65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b")); + +pub static PARAMS: ChainParams = ChainParams { + consensus: ConsensusParams { + hash_genesis_block: GENESIS_HASH, + hash_devnet_genesis_block: DEVNET_GENESIS_HASH, + subsidy_halving_interval: 210_240, + masternode_payments_start_block: BlockHeight::from_u32(4010), + masternode_payments_increase_block: BlockHeight::from_u32(4030), + masternode_payments_increase_period: 10, + instant_send_confirmations_required: 2, + instant_send_keep_lock: 6, + budget_payments_start_block: BlockHeight::from_u32(4100), + budget_payments_cycle_blocks: 50, + budget_payments_window_blocks: 10, + superblock_start: (BlockHeight::from_u32(4200), Hash256::ZERO), + superblock_cycle: 24, + superblock_maturity_window: 8, + governance_min_quorum: 1, + governance_filter_elements: 500, + masternode_minimum_confirmations: 1, + bip34: (BlockHeight::from_u32(1), Hash256::ZERO), + bip65_height: BlockHeight::from_u32(1), + bip66_height: BlockHeight::from_u32(1), + bip147_height: BlockHeight::from_u32(1), + csv_height: BlockHeight::from_u32(1), + dip0001_height: BlockHeight::from_u32(2), + dip0003_height: BlockHeight::from_u32(2), + dip0003_enforcement: (BlockHeight::from_u32(2), Hash256::ZERO), + dip0008_height: BlockHeight::from_u32(2), + brr_height: BlockHeight::from_u32(2), + dip0020_height: BlockHeight::from_u32(2), + dip0024_height: BlockHeight::from_u32(2), + dip0024_quorums_height: BlockHeight::from_u32(2), + v19_height: BlockHeight::from_u32(2), + v20_height: BlockHeight::from_u32(2), + mn_rr_height: BlockHeight::from_u32(2), + withdrawals_height: BlockHeight::from_u32(2), + min_bip9_warning_height: BlockHeight::from_u32(2 + 2016), // withdrawals_height + miner_confirmation_window + rule_change_activation_threshold: 1512, // 75% of 2016 + miner_confirmation_window: 2016, + deployments: Bip9Deployments { + test_dummy: Bip9Deployment { + bit: 28, + start_time: Bip9Deployment::NEVER_ACTIVE, + timeout: Bip9Deployment::NO_TIMEOUT, + min_activation_height: BlockHeight::from_u32(0), + window_size: 0, + threshold_start: 0, + threshold_min: 0, + falloff_coeff: 0, + use_ehf: false, + }, + v24: Bip9Deployment { + bit: 13, + start_time: 1_751_328_000, // July 1, 2025 + timeout: Bip9Deployment::NO_TIMEOUT, + min_activation_height: BlockHeight::from_u32(0), + window_size: 120, + threshold_start: 96, // 80% of 120 + threshold_min: 72, // 60% of 120 + falloff_coeff: 5, + use_ehf: true, + }, + evo_shares: Bip9Deployment { + bit: 14, + start_time: 1_751_328_000, // July 1, 2025 + timeout: Bip9Deployment::NO_TIMEOUT, + min_activation_height: BlockHeight::from_u32(0), + window_size: 120, + threshold_start: 96, // 80% of 120 + threshold_min: 72, // 60% of 120 + falloff_coeff: 5, + use_ehf: true, + }, + }, + pow_limit: Arith256::from_bendian(hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), + pow_allow_min_difficulty_blocks: true, + pow_no_retargeting: false, + pow_target_spacing: 150, // 2.5 minutes + pow_target_timespan: 86_400, // 1 day + pow_kgw_height: BlockHeight::from_u32(4001), + pow_dgw_height: BlockHeight::from_u32(4001), + minimum_chain_work: Arith256::ZERO, + default_assume_valid: Hash256::ZERO, + minimum_difficulty_blocks: 0, + high_subsidy_blocks: 0, + high_subsidy_factor: 1, + llmqs: &[ + LlmqType::Llmq50_60, + LlmqType::Llmq60_75, + LlmqType::Llmq400_60, + LlmqType::Llmq400_85, + LlmqType::Llmq100_67, + LlmqType::LlmqDevnet, + LlmqType::LlmqDevnetDip0024, + LlmqType::LlmqDevnetPlatform, + ], + llmq_type_chain_locks: LlmqType::LlmqDevnet, + llmq_type_dip0024_instant_send: LlmqType::LlmqDevnetDip0024, + llmq_type_platform: LlmqType::LlmqDevnetPlatform, + llmq_type_mnhf: LlmqType::LlmqDevnet, + }, + genesis: GenesisParams { + version: 1, + time: 1_417_713_337, + bits: 0x207f_ffff, + nonce: 1_096_447, + script_sig: GenesisParams::COINBASE_SCRIPT_SIG, + script_pubkey: GenesisParams::COINBASE_SCRIPT_PUBKEY, + reward: Amount::from_btc_u16(50), + }, + message_start: [0xe2, 0xca, 0xff, 0xce], + default_port: 19799, + default_platform_p2p_port: 22100, + default_platform_http_port: 22101, + rpc_port: 19798, + onion_service_target_port: 19796, + prune_after_height: 3000, + min_blocks_to_keep: 2304, + assumed_blockchain_size_gb: 0, + assumed_chain_state_size_gb: 0, + dns_seeds: &[], + addr_params: AddrParams { + pubkey_addr: 140, // addresses start with 'y' + script_addr: 19, // addresses start with '8' or '9' + secret_key: 239, // keys start with '9' or 'c' + ext_pubkey: [0x04, 0x35, 0x87, 0xCF], // tpub + ext_secret: [0x04, 0x35, 0x83, 0x94], // tprv + bip44_idx: 1, + bech32_hrp: "tdash", + }, + network_id: "devnet", + is_test_chain: true, + default_consistency_checks: false, + is_mockable_chain: false, + pool_min_participants: 2, + pool_max_participants: 20, + spork_address: "yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55", + credit_pool_period_blocks: 576, + checkpoints: &CHECKPOINTS, + chain_tx_data: ChainTxData { + timestamp: 1_417_713_338, // the devnet genesis block's time + tx_count: 2, + tx_rate: 0.01, + }, +}; + +const CHECKPOINTS: [Checkpoint; 2] = [ + (BlockHeight::from_u32(0), GENESIS_HASH), + (BlockHeight::from_u32(1), DEVNET_GENESIS_HASH), +]; diff --git a/pkgs/params/src/params/mainnet.rs b/pkgs/params/src/params/mainnet.rs index 390165377..17490f1ee 100644 --- a/pkgs/params/src/params/mainnet.rs +++ b/pkgs/params/src/params/mainnet.rs @@ -13,11 +13,13 @@ use crate::{ use bitcoin_units::{Amount, BlockHeight}; use dash_num::{Arith256, Hash256}; +use dash_types::Numeric; use hex_conservative::hex; pub static PARAMS: ChainParams = ChainParams { consensus: ConsensusParams { hash_genesis_block: Hash256::from_bendian(hex!("00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6")), + hash_devnet_genesis_block: Hash256::ZERO, subsidy_halving_interval: 210_240, masternode_payments_start_block: BlockHeight::from_u32(100_000), masternode_payments_increase_block: BlockHeight::from_u32(158_000), @@ -110,6 +112,9 @@ pub static PARAMS: ChainParams = ChainParams { default_assume_valid: Hash256::from_bendian(hex!( "000000000000000346a1804da4832b0b69dd9a7f96b14c7cb54585a9ac6ae98f" )), + minimum_difficulty_blocks: 0, + high_subsidy_blocks: 0, + high_subsidy_factor: 1, llmqs: &[ LlmqType::Llmq50_60, LlmqType::Llmq60_75, diff --git a/pkgs/params/src/params/mod.rs b/pkgs/params/src/params/mod.rs index a96e689dc..34a21aec6 100644 --- a/pkgs/params/src/params/mod.rs +++ b/pkgs/params/src/params/mod.rs @@ -6,6 +6,7 @@ //! Chain parameters of each network. +pub(crate) mod devnet; pub(crate) mod mainnet; pub(crate) mod regtest; pub(crate) mod test3; diff --git a/pkgs/params/src/params/regtest.rs b/pkgs/params/src/params/regtest.rs index b40a5dbaf..72844ae50 100644 --- a/pkgs/params/src/params/regtest.rs +++ b/pkgs/params/src/params/regtest.rs @@ -19,6 +19,7 @@ use hex_conservative::hex; pub static PARAMS: ChainParams = ChainParams { consensus: ConsensusParams { hash_genesis_block: Hash256::from_bendian(hex!("000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e")), + hash_devnet_genesis_block: Hash256::ZERO, subsidy_halving_interval: 150, masternode_payments_start_block: BlockHeight::from_u32(240), masternode_payments_increase_block: BlockHeight::from_u32(350), @@ -98,6 +99,9 @@ pub static PARAMS: ChainParams = ChainParams { pow_dgw_height: BlockHeight::from_u32(34_140), minimum_chain_work: Arith256::ZERO, default_assume_valid: Hash256::ZERO, + minimum_difficulty_blocks: 0, + high_subsidy_blocks: 0, + high_subsidy_factor: 1, llmqs: &[ LlmqType::LlmqTest, LlmqType::LlmqTestInstantsend, diff --git a/pkgs/params/src/params/test3.rs b/pkgs/params/src/params/test3.rs index c0f0c2adb..575557ad1 100644 --- a/pkgs/params/src/params/test3.rs +++ b/pkgs/params/src/params/test3.rs @@ -19,6 +19,7 @@ use hex_conservative::hex; pub static PARAMS: ChainParams = ChainParams { consensus: ConsensusParams { hash_genesis_block: Hash256::from_bendian(hex!("00000bafbc94add76cb75e2ec92894837288a481e5c005f6563d91623bf8bc2c")), + hash_devnet_genesis_block: Hash256::ZERO, subsidy_halving_interval: 210_240, masternode_payments_start_block: BlockHeight::from_u32(4010), masternode_payments_increase_block: BlockHeight::from_u32(4030), @@ -108,6 +109,9 @@ pub static PARAMS: ChainParams = ChainParams { default_assume_valid: Hash256::from_bendian(hex!( "000000116cd3c11d44c88cbc0a26804bd277a5d790f684ec3a8aaa820690318c" )), + minimum_difficulty_blocks: 0, + high_subsidy_blocks: 0, + high_subsidy_factor: 1, llmqs: &[ LlmqType::Llmq50_60, LlmqType::Llmq60_75, diff --git a/pkgs/params/src/prelude.rs b/pkgs/params/src/prelude.rs index b8b8e3a15..ffa75fa42 100644 --- a/pkgs/params/src/prelude.rs +++ b/pkgs/params/src/prelude.rs @@ -6,5 +6,6 @@ //! Re-exports for no_std compatibility. +pub(crate) use alloc::string::String; pub(crate) use alloc::vec; pub(crate) use alloc::vec::Vec; diff --git a/pkgs/params/src/release.rs b/pkgs/params/src/release.rs new file mode 100644 index 000000000..bb6d64a38 --- /dev/null +++ b/pkgs/params/src/release.rs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Reference implementation releases with known chain parameters, and how +//! the older one differs from the network tables. + +use crate::{Bip9Deployment, ChainParams, ChainTxData, Checkpoint, DeploymentPos, Network}; + +use bitcoin_units::BlockHeight; +use dash_num::{Arith256, Hash256}; +#[cfg(feature = "codec")] +use dash_types::type_id::Unencodable; +use hex_conservative::hex; + +/// A release line of the reference implementation whose chain parameters +/// are known. +/// +/// Each variant stands for one tag of its line. `V23_1` is v23.1.8 and +/// `V24_0` is v24.0.0-rc.5. The network tables hold `V24_0`. `V23_1` differs +/// in the version-bits deployments, the Platform address HRP, the standard +/// transaction policy, the sync anchors, the fixed seeds and the pruning +/// values. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub enum Release { + /// The v23.1 line (v23.1.8). + V23_1, + /// The v24.0 line (v24.0.0-rc.5). + V24_0, +} + +impl Release { + /// Every release, oldest first. + pub const ALL: [Self; 2] = [Self::V23_1, Self::V24_0]; + + /// The release's version-bits deployments, in position order. + pub const fn deployments(self) -> &'static [DeploymentPos] { + match self { + Self::V23_1 => &[DeploymentPos::TestDummy, DeploymentPos::V24], + Self::V24_0 => &[DeploymentPos::TestDummy, DeploymentPos::V24, DeploymentPos::EvoShares], + } + } + + /// Writes the release's values into `chain`, the table of `network`. + /// + /// v23.1.8 has earlier sync anchors, mainnet size, prune heights and + /// pruning depth, and no Platform address HRP, which is left empty. Its + /// `v24` signals on bit 12 and has no mainnet or testnet start. It has no + /// `evo_shares`, whose slot here never activates. + pub(crate) fn write_chain(self, network: Network, chain: &mut ChainParams) { + if self == Self::V24_0 { + return; + } + chain.min_blocks_to_keep = 288; + chain.addr_params.bech32_hrp = ""; + let consensus = &mut chain.consensus; + let deployments = &mut consensus.deployments; + deployments.v24.bit = 12; + if matches!(network, Network::Main | Network::Testnet3) { + deployments.v24.start_time = Bip9Deployment::NEVER_ACTIVE; + deployments.v24.timeout = Bip9Deployment::NO_TIMEOUT; + } + let shares = &mut deployments.evo_shares; + (shares.start_time, shares.timeout) = (Bip9Deployment::NEVER_ACTIVE, Bip9Deployment::NO_TIMEOUT); + match network { + Network::Main => { + consensus.minimum_chain_work = + Arith256::from_bendian(hex!("00000000000000000000000000000000000000000000ba7225adc3153945d14d")); + consensus.default_assume_valid = + Hash256::from_bendian(hex!("00000000000000119fe42827219e0686d3f7b494ae65f823194c740c5dbab492")); + chain.chain_tx_data = ChainTxData { + timestamp: 1_781_318_234, + tx_count: 69_770_814, + tx_rate: 0.1569520632249578, + }; + chain.assumed_blockchain_size_gb = 57; + chain.checkpoints = up_to(chain.checkpoints, BlockHeight::from_u32(2_487_500)); + } + Network::Testnet3 => { + consensus.minimum_chain_work = + Arith256::from_bendian(hex!("000000000000000000000000000000000000000000000000036c8f738da818d2")); + consensus.default_assume_valid = + Hash256::from_bendian(hex!("000000541a23f9db7411cddbe50f9f1ebd4aa7108ebdcad62214753f648c0239")); + chain.chain_tx_data = ChainTxData { + timestamp: 1_765_334_452, + tx_count: 8_182_713, + tx_rate: 0.1796716675173412, + }; + chain.prune_after_height = 1000; + chain.checkpoints = up_to(chain.checkpoints, BlockHeight::from_u32(1_380_000)); + } + Network::Devnet => chain.prune_after_height = 1000, + Network::Regtest => {} + } + } + + /// Whether `network` rejects non-standard transactions by default, at + /// v23.1 only. v24 dropped the setting. + pub(crate) const fn require_standard(self, network: Network) -> Option { + match self { + Self::V23_1 => Some(matches!(network, Network::Main | Network::Regtest)), + Self::V24_0 => None, + } + } +} + +/// The leading `checkpoints`, which are sorted by height, up to `last`. +fn up_to(checkpoints: &'static [Checkpoint], last: BlockHeight) -> &'static [Checkpoint] { + let end = checkpoints.partition_point(|(height, _)| *height <= last); + checkpoints.get(..end).unwrap_or(checkpoints) +} diff --git a/pkgs/params/src/setup.rs b/pkgs/params/src/setup.rs new file mode 100644 index 000000000..c400b7bb3 --- /dev/null +++ b/pkgs/params/src/setup.rs @@ -0,0 +1,178 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Chain parameters as a node runs them, a network's at a release. + +mod tables; + +use crate::prelude::*; +use crate::{Bip9Deployment, ChainParams, DeploymentPos, Network, Release}; + +use bitcoin_units::BlockHeight; +use dash_num::Hash256; +#[cfg(feature = "codec")] +use dash_types::type_id::Unencodable; + +use core::ops::Deref; + +/// Chain parameters as a node runs them, built by +/// [`ChainParamsBuilder`](crate::ChainParamsBuilder). These are the reference +/// implementation's chain parameters of a network at a [`Release`]. +/// +/// Every [`ChainParams`] field is read through `Deref` and holds the +/// release's value. A version-bits deployment the release lacks never +/// activates there, and [`deployment`](Self::deployment) omits it. +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub struct ChainSetup { + /// The network. + network: Network, + /// Release whose parameters these are. + release: Release, + /// The parameters at the release. + chain: ChainParams, + /// The devnet's name, on a devnet. + devnet_name: Option, + /// Whether non-standard transactions are rejected by default (v23 release + /// only). + pub require_standard: Option, + /// Trusted assumeutxo snapshots. + pub assumeutxo: &'static [AssumeutxoData], + /// BIP155-serialized fixed seed addresses. + pub fixed_seeds: &'static [u8], + /// Whether a masternode's external IP must be routable. + pub require_routable_external_ip: bool, + /// Whether several masternode addresses may share a network group. + pub allow_multiple_addresses_from_group: bool, + /// Seconds before an LLMQ connection is retried. + pub llmq_connection_retry_timeout: i32, + /// Seconds until a fulfilled request expires. + pub fulfilled_request_expire_time: i32, + /// Heights the reference implementation hard-codes outside its chain + /// parameters. + pub hard_coded: HardCodedHeights, +} + +impl ChainSetup { + /// The parameters of `network` at `release`. + pub(crate) fn new(network: Network, release: Release) -> Self { + let mut chain = *network.chain(); + release.write_chain(network, &mut chain); + let devnet_name = (network == Network::Devnet).then(|| String::from("devnet")); + let extras = tables::extras(network); + Self { + network, + release, + chain, + devnet_name, + require_standard: release.require_standard(network), + assumeutxo: tables::assumeutxo(network, release), + fixed_seeds: tables::fixed_seeds(network, release), + require_routable_external_ip: extras.require_routable_external_ip, + allow_multiple_addresses_from_group: extras.allow_multiple_addresses_from_group, + llmq_connection_retry_timeout: extras.llmq_connection_retry_timeout, + fulfilled_request_expire_time: extras.fulfilled_request_expire_time, + hard_coded: extras.hard_coded, + } + } + + /// The network. + pub const fn network(&self) -> Network { + self.network + } + + /// The release whose parameters these are. + pub const fn release(&self) -> Release { + self.release + } + + /// The devnet's name on a devnet, `devnet` or `devnet-`, and `None` + /// elsewhere. + pub fn devnet_name(&self) -> Option<&str> { + self.devnet_name.as_deref() + } + + /// The chain's data directory, under the base data directory. Mainnet + /// uses the base directory itself. + pub fn data_dir(&self) -> &str { + match self.network { + Network::Main => "", + Network::Testnet3 => "testnet3", + Network::Devnet => self.devnet_name().unwrap_or("devnet"), + Network::Regtest => "regtest", + } + } + + /// The DIP-18 Platform address bech32m HRP, if the release has one (v24 + /// release only). + pub fn platform_hrp(&self) -> Option<&'static str> { + let hrp = self.chain.addr_params.bech32_hrp; + (!hrp.is_empty()).then_some(hrp) + } + + /// The version-bits deployment at `pos`, if this release has it. + pub fn deployment(&self, pos: DeploymentPos) -> Option<&Bip9Deployment> { + self + .release + .deployments() + .contains(&pos) + .then(|| self.chain.consensus.deployments.at(pos)) + } + + /// The release's version-bits deployments, in position order. + pub fn deployments(&self) -> impl Iterator { + let deployments = &self.chain.consensus.deployments; + self + .release + .deployments() + .iter() + .map(move |&pos| (pos, deployments.at(pos))) + } +} + +impl Deref for ChainSetup { + type Target = ChainParams; + + fn deref(&self) -> &ChainParams { + &self.chain + } +} + +/// An assumeutxo snapshot the chain trusts. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub struct AssumeutxoData { + /// Height of the snapshot base block. + pub height: BlockHeight, + /// Expected hash of the serialized UTXO set. + pub hash_serialized: Hash256, + /// Expected hash of the evo section (v24 release only). + pub evo_hash: Option, + /// Transactions up to and including the base block. + pub chain_tx: u32, +} + +/// Heights the reference implementation hard-codes by network, outside its +/// chain parameters. +/// +/// The superblock start and DIP0003 enforcement blocks are chain parameters +/// already, [`ConsensusParams::superblock_start`][start] and +/// [`ConsensusParams::dip0003_enforcement`][dip3]. Literals that choose a +/// rule's path by network rather than set a height stay with their rules. +/// +/// [start]: crate::ConsensusParams::superblock_start +/// [dip3]: crate::ConsensusParams::dip0003_enforcement +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub struct HardCodedHeights { + /// Last height whose header difficulty only needs to be within 50% of the + /// required difficulty, on mainnet only. + pub pre_dgw_tolerance_until: Option, + /// [`LlmqType::Llmq25_67`](crate::LlmqType::Llmq25_67) is enabled once the + /// previous block is at or above this height, on any chain that runs it. + /// Only testnet does. + pub llmq_25_67_activation_height: BlockHeight, +} diff --git a/pkgs/params/src/setup/tables.rs b/pkgs/params/src/setup/tables.rs new file mode 100644 index 000000000..9e2bc2e43 --- /dev/null +++ b/pkgs/params/src/setup/tables.rs @@ -0,0 +1,254 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Per-network values outside [`ChainParams`](crate::ChainParams), the same +//! at v23.1.8 and v24.0.0-rc.5 but for the fixed seeds and assumeutxo. + +use super::{AssumeutxoData, HardCodedHeights}; +use crate::{Network, Release}; + +use bitcoin_units::BlockHeight; +use dash_num::Hash256; +#[cfg(feature = "codec")] +use dash_types::type_id::Unencodable; +use dash_types::Numeric; +use hex_conservative::hex; + +/// The per-network values a [`ChainSetup`](super::ChainSetup) holds besides +/// the ones of [`ChainParams`](crate::ChainParams). +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub(super) struct Extras { + /// Whether a masternode's external IP must be routable. + pub(super) require_routable_external_ip: bool, + /// Whether several masternode addresses may share a network group. + pub(super) allow_multiple_addresses_from_group: bool, + /// Seconds before an LLMQ connection is retried. + pub(super) llmq_connection_retry_timeout: i32, + /// Seconds until a fulfilled request expires. + pub(super) fulfilled_request_expire_time: i32, + /// Heights the reference implementation hard-codes outside its chain + /// parameters. + pub(super) hard_coded: HardCodedHeights, +} + +/// Height the previous block must reach for `llmq_25_67` to be enabled. +const LLMQ_25_67_ACTIVATION_HEIGHT: BlockHeight = BlockHeight::from_u32(847_000); + +/// Hard-coded heights of every chain but mainnet. +const TEST_HEIGHTS: HardCodedHeights = HardCodedHeights { + pre_dgw_tolerance_until: None, + llmq_25_67_activation_height: LLMQ_25_67_ACTIVATION_HEIGHT, +}; + +/// The values of `network`. +pub(super) const fn extras(network: Network) -> Extras { + match network { + Network::Main => Extras { + require_routable_external_ip: true, + allow_multiple_addresses_from_group: false, + llmq_connection_retry_timeout: 60, + fulfilled_request_expire_time: 60 * 60, + hard_coded: HardCodedHeights { + pre_dgw_tolerance_until: Some(BlockHeight::from_u32(68_589)), + llmq_25_67_activation_height: LLMQ_25_67_ACTIVATION_HEIGHT, + }, + }, + Network::Testnet3 => Extras { + require_routable_external_ip: true, + allow_multiple_addresses_from_group: false, + llmq_connection_retry_timeout: 60, + fulfilled_request_expire_time: 5 * 60, + hard_coded: TEST_HEIGHTS, + }, + Network::Devnet => Extras { + require_routable_external_ip: true, + allow_multiple_addresses_from_group: true, + llmq_connection_retry_timeout: 60, + fulfilled_request_expire_time: 5 * 60, + hard_coded: TEST_HEIGHTS, + }, + Network::Regtest => Extras { + require_routable_external_ip: false, + allow_multiple_addresses_from_group: true, + llmq_connection_retry_timeout: 1, + fulfilled_request_expire_time: 5 * 60, + hard_coded: TEST_HEIGHTS, + }, + } +} + +/// The BIP155-serialized fixed seed addresses of `network` at `release`. +pub(super) const fn fixed_seeds(network: Network, release: Release) -> &'static [u8] { + match (network, release) { + (Network::Main, Release::V23_1) => &MAINNET_FIXED_SEEDS_V23, + (Network::Main, Release::V24_0) => &MAINNET_FIXED_SEEDS_V24, + (Network::Testnet3, Release::V23_1) => &TESTNET_FIXED_SEEDS_V23, + (Network::Testnet3, Release::V24_0) => &TESTNET_FIXED_SEEDS_V24, + (Network::Devnet | Network::Regtest, _) => &[], + } +} + +/// The assumeutxo snapshots `network` trusts at `release`. +pub(super) const fn assumeutxo(network: Network, release: Release) -> &'static [AssumeutxoData] { + match (network, release) { + (Network::Regtest, Release::V23_1) => &ASSUMEUTXO_V23, + (Network::Regtest, Release::V24_0) => &ASSUMEUTXO_V24, + _ => &[], + } +} + +/// Regtest snapshot at `height` with UTXO-set hash `hash` and evo-section +/// hash `evo_hash`. +const fn snapshot(height: u32, hash: [u8; 32], evo_hash: Option) -> AssumeutxoData { + AssumeutxoData { + height: BlockHeight::from_u32(height), + hash_serialized: Hash256::from_bendian(hash), + evo_hash, + chain_tx: height, + } +} + +const SNAPSHOT_110: [u8; 32] = hex!("9b2a277a3e3b979f1a539d57e949495d7f8247312dbc32bce6619128c192b44b"); +const SNAPSHOT_200: [u8; 32] = hex!("8a5bdd92252fc6b24663244bbe958c947bb036dc1f94ccd15439f48d8d1cb4e3"); +const ZERO: Option = Some(Hash256::ZERO); + +static ASSUMEUTXO_V23: [AssumeutxoData; 2] = [snapshot(110, SNAPSHOT_110, None), snapshot(200, SNAPSHOT_200, None)]; +static ASSUMEUTXO_V24: [AssumeutxoData; 2] = [snapshot(110, SNAPSHOT_110, ZERO), snapshot(200, SNAPSHOT_200, ZERO)]; + +#[rustfmt::skip] +static MAINNET_FIXED_SEEDS_V23: [u8; 2260] = hex!(concat!( + "0420ba5bab3a877c7498c27006d1350849b96b17d52621cca8c173319a4476cbd777270f0420b4c38d95481f090029a5", + "ab00a37aae2d5e30728a3d082fabba6bbfe6fa59b8aa270f04209d329c4d1e352dbd4982b9a5664f455256ac5db3e7e3", + "393eac8122102f23260d270f04207e87e89bd53f4bb62621ff57a7bef3085e90979dacc987ec5ca6db72b9b67932270f", + "0420627b986dc470d769116ae85b7eace8a1ed4a67d733109bf1416bda703145ecfe270f04205c0de69424577850c8c3", + "c0a1e8913f20e02371f2f320caca11f73a820833f8b3270f04205783984d479e719412674376a5625be6a2bc89905465", + "d404123c04b1535b21e9270f0420574c369aa062ed8658fa037d05832f355675468a049de6d7be1efaf2366f29d0270f", + "04204c2524e1b55c2c543a236d2faac27e32db1d970fc3cb604a28c85f63853a5d67270f04204a527b624ae4f68fb629", + "c5f112f3094c18e5938373ac607dad561283ecec47e1270f0420463d6c95fee97af210f0a404783c91bf63c84b012b2b", + "51a4e4d015b41bcf9ec1270f042044d4098b4679554a85892aee6881aa9a6327285fb0a8da6bac87df38325f2d89270f", + "042047fb8b8727ca95e877ae41bd72206225e5679841850e9a5d4ab10f8f46a987a4270f04203f2381376b32e603dea5", + "bcc9e8e698a6dce06cbb075e2364eaa9fa104088fcb7270f04203e84f83123dc6043c5ddd4a643a3956e1c5be18580e4", + "4b88e72fc6f0854e8298270f0420304dab0f94b0baafdba9ddb9ecc49e8f50e2668b3262851277af2045603936b3270f", + "04202e5decf0624cca6e90df00651cca4acb66eea2a694278d6cec154be0a486e321270f04202109f10f0d0a69f782fc", + "e559b0bbe00651fd4030359537d55bf9dd737d2a8133270f0420060f6b3d30e44db0c9619cff8226183d058042410fe6", + "de742b3f23fba7dab15c270f0420ed7ab30c6e589039cf5061d95c281a258f3e314c627fb996d443162519900f57270f", + "0420ef3468e6b3c6c4d0cf22dc9209d02a634f6d6afd316ad4e9717306f046cb1713270f0420e0c1c978b5cead3f7f4a", + "bde0688388a45d39712dce5847ac239fc0145fdde952270f0420dd2a24e18845d1e6f99a7f8b23613755f42200921fc8", + "e7a36ffa5bbf711dcfb9270f0420d89d506e4d6230388c108cb29eaa2da25f632a843e94970e8de1ea8bab78eafb270f", + "0420d063bfe7a859b68dc416b2b2d61fcb38b217417dc8e2533140bb65c9bcb1bb29270f0104d99ae714270f0104d8ee", + "4b2e270f0104d8e6e87d270f0104d48469be270f0104d41868e1270f0104d18d24ce270f0104d057665b270f0104cff4", + "f728270f0104ca470e4f270f0104ca051021270f0104c3625fd2270f0104c31afee4270f0104c2ee19c7270f0104c287", + "5464270f0104c2059dd6270f0104c0af7fc6270f0104c0a90657270f0104b9f373db270f0104b9e4539c270f0104b9e4", + "5384270f0104b9d8b305270f0104b9c113d6270f0104b9b92868270f0104b9a6d99a270f0104b9a5ab75270f0104b9a4", + "a3da270f0104b9a4a355270f0104b970f935270f0104b970f931270f0104b91c6591270f0104b86bb6c6270f0104b2fd", + "fd05270f0104b2d7ed87270f0104b2d7ed86270f0104b2d057e2270f0104b2d057d5270f0104b29d5bb1270f0104b23f", + "7981270f0104b15d8d56270f0104b15d8d3c270f0104b0664191270f0104acee0719270f0104acecf451270f0104ac68", + "91a6270f0104ac565b9e270f0104ac5649a0270f0104a87757c4270f0104a8775004270f0104a768d81c270f0104a758", + "a910270f0104a516ea87270f0104a516dd61270f0104a3ac4229270f0104a161a573270f01049f4b79a3270f01049a10", + "3f70270f010498435fb8270f010497f455db270f010497f455c3270f010497f455b2270f010497f4557b270f01049568", + "6e77270f0104932d29d2270f0104901fbc2a270f01049018eeb2270f010488f46311270f0104851261e2270f010484f3", + "c5f0270f010484f3c5b3270f010484f3c563270f010484f3c517270f010482ff9ba3270f010482a2e9ba270f01047bc1", + "40a6270f010473bef839270f01047284acd7270f01046deb43f6270f01046ca083c0270f01046bbd034a270f01046bb3", + "ca4a270f01046baecce8270f01046baafea0270f01046a370916270f010468eaa773270f01045d73ac27270f01045d73", + "ac25270f01045bc795b1270f01045bc66c28270f01045bc66c27270f01045bc66c25270f01045bc66c23270f01045bb8", + "f9d1270f010459b34960270f0104597dd1c3270f0104597dd16e270f0104597dd145270f01045975391b270f01045975", + "03f2270f0104592e2ada270f010459238395270f010457e41840270f010455d1f1f5270f010455d1f15d270f010455d1", + "f157270f010455d1f156270f0104559bbc8a270f010454f7b4c9270f010454f2b3cc270f010454620cc4270f01045409", + "3211270f010453ef6328270f0104539564ba270f0104539564b9270f0104539564b8270f0104539564b7270f010452ca", + "e653270f010452b492c0270f010451e3fa33270f010450f99308270f010450f084e7270f010450d0e690270f01044e53", + "1300270f01044ddf6304270f01044ddd94cc270f01044a325a71270f0104483e3a6c270f0104483c26a0270f0104453d", + "6bd7270f010442f5c434270f010442f4f346270f010442a37171270f010442a3715b270f010442a37107270f01043eab", + "857d270f01043e3cf4ae270f01043424665b270f0104342109ac270f0104339ebc58270f0104339ea9ed270f0104339e", + "a71f270f01042efafe0a270f01042e2428f2270f01042e1ebdbb270f01042e04a27f270f01042d99ba64270f01042d95", + "9ac2270f01042d809c1e270f01042d4f126a270f01042d3dba79270f01042d3a384f270f01042cf063d6270f01042be5", + "4d2e270f01042ba7f46d270f01042ba7ef91270f01042b86b471270f01042b85ab65270f010426667d6c270f01042636", + "0c6f270f01042561e315270f010422f6b019270f01041f946394270f01041f0a6124270f010417a300ae270f010405a1", + "6e4f270f010405236713270f01040502493a270f0104050243be270f010402e97823270f0104023bdb36270f01040175", + "4bdc270f", +)); + +#[rustfmt::skip] +static TESTNET_FIXED_SEEDS_V23: [u8; 152] = hex!(concat!( + "0104d42f44c74e1f0104b9bba9c14e1f0104cef5a73f4e1f0104935d84094e1f010444437a484e1f010444437a2a4e1f", + "010444437a214e1f010444437a174e1f01043e3cf4ae4e1f010436d55ed84e1f010436bf92894e1f010436bc45594e1f", + "010434599a304e1f010423a212744e1f0104235c8f074e1f0104235bc5da4e1f0104235b86594e1f010422dc861e4e1f", + "010422d21ac34e1f", +)); + +#[rustfmt::skip] +static MAINNET_FIXED_SEEDS_V24: [u8; 2884] = hex!(concat!( + "0420cfb5e558be0d672d55acca2a4fb818888fd21548a91f186c7999baa586cecbba270f0420c236fcafff7c46843e75", + "26acea2ad4f1b121960194a81b0a1751cf5f521bc0db270f0420ba5bab3a877c7498c27006d1350849b96b17d52621cc", + "a8c173319a4476cbd777270f0420ae08410ddf89564f35fc2a45513e094181c7e3847d257f7122f895e47092a55b270f", + "04209d329c4d1e352dbd4982b9a5664f455256ac5db3e7e3393eac8122102f23260d270f0420835025a93357385d60d2", + "9e7b7b2bfbb172951c65b8b59515204ea4627b1637ea270f042080c965bbe7dd120ec185df981c8d0ea4f17c17b1f72c", + "faff9922f2cc8491fe63270f04207dd03c5edb99248efadc32cd6748d219e858d547b576eeda9cd57cbc6cfe93ac270f", + "04207e87e89bd53f4bb62621ff57a7bef3085e90979dacc987ec5ca6db72b9b67932270f04206d54e7bea858cd359980", + "b2326c86a2a911623d3b67345dd1203141923f8e5726270f0420609b96e1cafd869083e3eb908e372c584cb77986b84b", + "10b2929b7765466ccf84270f04205594a681ae3385fe02ec3dccc21e62230c1668eef868281e5c951fdf9ffe6d3d270f", + "04205783984d479e719412674376a5625be6a2bc89905465d404123c04b1535b21e9270f0420574c369aa062ed8658fa", + "037d05832f355675468a049de6d7be1efaf2366f29d0270f042049b9652324d9714256a068a15c734dc728ba96e6d69e", + "dd6afe00c9a40b325c19270f042045e9fa710ab15a05d18144165d62bfd8d24909b575e7979c3396504d1b440eae270f", + "042044d4098b4679554a85892aee6881aa9a6327285fb0a8da6bac87df38325f2d89270f04204167eea8aef7d77c7a80", + "5aaf2dfd9bd193ab8ae992234ccad9035ef9d71aa0aa270f04203f2381376b32e603dea5bcc9e8e698a6dce06cbb075e", + "2364eaa9fa104088fcb7270f04203e96f49d6bf8aedfcc0feb500899a0c17243c90f508f681f4b5a80110172203d270f", + "04202e5decf0624cca6e90df00651cca4acb66eea2a694278d6cec154be0a486e321270f04201f3b77a4090552600bdc", + "d424d04a50fa2d5c9cf1d0f24c2de9190dd2ff4491a3270f042015dd119818614281e2bfb88a4b70a31a93fc60405313", + "1379e8fca37cdc423b61270f0420060f6b3d30e44db0c9619cff8226183d058042410fe6de742b3f23fba7dab15c270f", + "0420070f6abe825444394a0063aa7b30fc0461046db1928f2f129a724722164f67e1270f0420dd75b606bc355055df7e", + "b0f9b26a6d2af16c348ccee8a41ee601f72fa917d14f270f0420d89d506e4d6230388c108cb29eaa2da25f632a843e94", + "970e8de1ea8bab78eafb270f0104d99ae714270f0104d8ee4b2e270f0104d8e6e87d270f0104d18d24ce270f0104d14a", + "5f42270f0104d14a42b0270f0104d057665b270f0104d0576659270f0104d0576656270f0104d0576215270f0104cff4", + "f728270f0104cfb4e906270f0104ca051021270f0104c75508bf270f0104c75508be270f0104c7550808270f0104c362", + "5fd2270f0104c31afee4270f0104c2ee19c7270f0104c2875464270f0104c2875021270f0104c0af7fc6270f0104c0a9", + "0657270f0104bc28b243270f0104b9f373db270f0104b9e4539c270f0104b9e45384270f0104b9d8b305270f0104b9c6", + "ea0c270f0104b9c113d6270f0104b9b928ab270f0104b9b92868270f0104b9a5ab75270f0104b9a4a3da270f0104b9a4", + "a355270f0104b98ed490270f0104b970f935270f0104b970f931270f0104b91c6591270f0104b86bb6c6270f0104b2fd", + "fd05270f0104b2d057e2270f0104b2d057d5270f0104b29d5bb8270f0104b29d5bb2270f0104b29d5bb1270f0104b280", + "e4c3270f0104b2689b05270f0104b23f7981270f0104b23eab10270f0104b15d8d56270f0104b15d8d3c270f0104b066", + "4191270f0104acee0719270f0104acecf451270f0104ac6891a6270f0104ac5675d2270f0104ac565b9e270f0104ac56", + "49a0270f0104a93ace3f270f0104a8775004270f0104a758a910270f0104a3ac4229270f0104a2d4236b270f0104a2d4", + "236a270f0104a2d42368270f0104a2d42364270f0104a161a573270f01049f4b79a3270f01049db45b4e270f01049dad", + "7a1a270f01049dad7a19270f01049dad7a15270f01049dad7a14270f01049c431d2d270f010498435fb8270f010497f4", + "55fd270f010497f455db270f010497f455b2270f010497f4557b270f010495686e77270f0104951c944d270f0104932d", + "29d2270f0104901fbc2a270f01049018eeb2270f01048f14210a270f01048bb48f93270f01048ba2d7a9270f01048ba2", + "d34c270f01048b54d85b270f01048b1c6102270f010486ffb6b9270f0104851261e2270f010484f3c5f0270f010484f3", + "c5b3270f010484f3c563270f010484f3c517270f010482ff9ba3270f010482a2e9ba270f010473bef839270f01047284", + "acd7270f01046deb43f6270f01046dadc643270f01046bbd034a270f01046bb3845d270f01046baecce8270f01046baa", + "fea0270f01046a370916270f010468cf4b90270f010468cf4b03270f010468cf49af270f01045bc795b1270f01045bc6", + "6c29270f01045bc66c28270f01045bc66c27270f01045bc66c23270f01045b63a9ba270f010459b34960270f0104597d", + "ffd3270f0104597dd1e2270f0104597d32ce270f0104597d320e270f0104597503f2270f0104592e2ada270f0104592e", + "2ad8270f010459280fde270f0104592383db270f0104592383da270f01045923839e270f010459238395270f010457e5", + "1694270f010457e5161f270f010457e41840270f0104566ba862270f0104566ba828270f010455d1f1f5270f010455d1", + "f15d270f010455d1f157270f010455d1f156270f010455bef303270f010454f7b4c9270f010454f2b3cc270f01045462", + "0cc4270f010454093211270f0104539564ba270f0104539564b8270f0104539564b7270f010452df517f270f010452ca", + "e653270f010452b492c0270f010451e3fa33270f010450f99308270f010450f084e7270f01044e531300270f01044e11", + "d4f9270f01044e114728270f01044dedecd6270f01044dedec42270f01044dedeb00270f01044ddf6304270f01044ddd", + "94cc270f01044d693d77270f01044d693d4f270f01044d2a5b48270f01044d2a4a44270f01044d2a102e270f01044a32", + "5a71270f0104483e3a6c270f0104483c26a0270f0104453d6bd7270f010442f4f346270f010442a37171270f010442a3", + "715b270f010442a37107270f01043eee7f94270f01043e3cf4ae270f0104362526e2270f01043424665b270f01043421", + "09ac270f010433a12286270f0104339ebc58270f0104339ea9ed270f0104339ea71f270f0104334f6db6270f01043344", + "031d270f01042efafe0a270f01042ee17833270f01042ee03297270f01042e94e779270f01042e3efaf7270f01042e3e", + "8490270f01042e2428f2270f01042e2423f4270f01042e1ebdfb270f01042e04a27f270f01042d99ba64270f01042d97", + "46cb270f01042d9746ca270f01042d959ac2270f01042d87b44f270f01042d87b444270f01042d809c1e270f01042d4f", + "126a270f01042d3dba79270f01042d3a384f270f01042cf063d6270f01042ba7f46d270f01042b9b87d0270f01042b86", + "b471270f01042b85ab65270f010426667d6c270f010426360c6f270f01042561e315270f0104253cf4fd270f010422d2", + "ee43270f01041f946394270f01041f4d6c88270f01041f3aaab5270f01041f3aaab4270f01041f3aaa8b270f01041f3a", + "aa82270f01041f3826b9270f01041f382601270f01041f382600270f01041f0a6124270f010405afa2d7270f010405af", + "a2bc270f010405afa2b9270f010405afa2b8270f010405357c78270f010405236719270f010405236713270f01040502", + "493a270f0104050243be270f010402e97823270f0104023bdb36270f0104021ceae6270f010402195070270f01040175", + "4bdc270f", +)); + +#[rustfmt::skip] +static TESTNET_FIXED_SEEDS_V24: [u8; 200] = hex!(concat!( + "0104cef5a73f4e1f0104a223f3554e1d010457e5167e4e1f010455d1f3294e1f010455d1f30a4e1f010455d1f3094e1f", + "010455d1f3084e1f010455d1f3074e1f010455d1f3064e1f010455d1f3054e1f010455d1f3044e1f010455d1f3034e1f", + "010455d1f3024e1f010444437a514e1f010444437a484e1f010444437a464e1f010444437a424e1f010444437a3e4e1f", + "010444437a334e1f010444437a2a4e1f010444437a214e1f010444437a1e4e1f010444437a174e1f01043e3cf4ae4e1f", + "010422b266904e1f", +)); diff --git a/pkgs/params/tests/setup.rs b/pkgs/params/tests/setup.rs new file mode 100644 index 000000000..5985ec622 --- /dev/null +++ b/pkgs/params/tests/setup.rs @@ -0,0 +1,209 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! The chain setup a node reads, against the network tables. + +use bitcoin_units::BlockHeight; +use dash_params::{ + AddrParams, Bip9Deployment, ChainParams, ChainParamsBuilder, ChainSetup, DeploymentPos, HardCodedHeights, Network, + Release, +}; +use rstest::rstest; + +use std::collections::BTreeSet; + +fn setup(network: Network, release: Release) -> ChainSetup { + ChainParamsBuilder::new(network, release).build() +} + +/// The [`ChainParams`] that `Deref` and coercion reach. +fn chain(setup: &ChainSetup) -> &ChainParams { + setup +} + +#[rstest] +fn network_discriminants_are_stable() { + let discriminants: Vec<(Network, u8)> = Network::ALL.into_iter().map(|n| (n, n as u8)).collect(); + assert_eq!( + discriminants, + [ + (Network::Main, 0), + (Network::Testnet3, 1), + (Network::Devnet, 2), + (Network::Regtest, 3) + ] + ); +} + +#[rstest] +#[case::mainnet(Network::Main, "main")] +#[case::testnet(Network::Testnet3, "test")] +#[case::devnet(Network::Devnet, "devnet")] +#[case::regtest(Network::Regtest, "regtest")] +fn network_ids_are_the_tables(#[case] network: Network, #[case] id: &str) { + assert_eq!(network.network_id(), id); + assert_eq!(network.chain().network_id, id); + assert_eq!(Network::from_network_id(id), Some(network)); +} + +#[rstest] +#[case("")] +#[case("Main")] +#[case("testnet3")] +#[case("devnet-x")] +fn other_network_ids_name_no_network(#[case] id: &str) { + assert_eq!(Network::from_network_id(id), None); +} + +/// With no options at v24.0, the parameters are the network's table and +/// every deployment is the table's. +#[rstest] +fn v24_setup_is_the_table( + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, +) { + let setup = setup(network, Release::V24_0); + assert_eq!((setup.network(), setup.release()), (network, Release::V24_0)); + assert_eq!(chain(&setup), network.chain()); + let table = network.consensus().deployments; + let deployments: Vec<_> = setup.deployments().map(|(pos, d)| (pos, *d)).collect(); + assert_eq!( + deployments, + [ + (DeploymentPos::TestDummy, table.test_dummy), + (DeploymentPos::V24, table.v24), + (DeploymentPos::EvoShares, table.evo_shares), + ] + ); + assert_eq!(setup.platform_hrp(), Some(network.addr().bech32_hrp)); +} + +/// At v23.1, `evo_shares` does not exist and never activates, `v24` signals +/// on bit 12 with no mainnet or testnet schedule and there is no Platform +/// address HRP. +#[rstest] +fn v23_setup_has_the_v23_deployments( + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, +) { + let setup = setup(network, Release::V23_1); + let positions: Vec = setup.deployments().map(|(pos, _)| pos).collect(); + assert_eq!(positions, [DeploymentPos::TestDummy, DeploymentPos::V24]); + assert_eq!(setup.deployment(DeploymentPos::EvoShares), None); + let bits: BTreeSet = setup.deployments().map(|(_, d)| d.bit).collect(); + assert_eq!(bits, BTreeSet::from([12, 28])); + let table = network.consensus().deployments; + let (start_time, timeout) = match network { + Network::Main | Network::Testnet3 => (Bip9Deployment::NEVER_ACTIVE, Bip9Deployment::NO_TIMEOUT), + _ => (table.v24.start_time, table.v24.timeout), + }; + let v24 = Bip9Deployment { + bit: 12, + start_time, + timeout, + ..table.v24 + }; + assert_eq!(setup.deployment(DeploymentPos::V24), Some(&v24)); + assert_eq!(setup.deployment(DeploymentPos::TestDummy), Some(&table.test_dummy)); + + let deployments = &setup.consensus.deployments; + assert_eq!((deployments.v24, deployments.test_dummy), (v24, table.test_dummy)); + assert_eq!(deployments.evo_shares.start_time, Bip9Deployment::NEVER_ACTIVE); + assert_eq!(deployments.evo_shares.timeout, Bip9Deployment::NO_TIMEOUT); + + assert_eq!(setup.platform_hrp(), None); + assert_eq!(setup.addr_params.bech32_hrp, ""); +} + +/// The address parameters hold the Platform HRP, empty at releases without +/// one. +#[rstest] +fn addr_params_hold_the_platform_hrp( + #[values(Release::V23_1, Release::V24_0)] release: Release, + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, +) { + let setup = setup(network, release); + let table = network.addr(); + let hrp = match release { + Release::V23_1 => "", + Release::V24_0 => table.bech32_hrp, + }; + assert_eq!(setup.platform_hrp(), (!hrp.is_empty()).then_some(hrp)); + assert_eq!( + setup.addr_params, + AddrParams { + bech32_hrp: hrp, + ..*table + } + ); +} + +/// The heights hard-coded outside the chain parameters, the same at both +/// releases. +#[rstest] +#[case::mainnet(Network::Main, Some(68_589))] +#[case::testnet(Network::Testnet3, None)] +#[case::devnet(Network::Devnet, None)] +#[case::regtest(Network::Regtest, None)] +fn hard_coded_heights_are_the_references(#[case] network: Network, #[case] pre_dgw: Option) { + let want = HardCodedHeights { + pre_dgw_tolerance_until: pre_dgw.map(BlockHeight::from_u32), + llmq_25_67_activation_height: BlockHeight::from_u32(847_000), + }; + for release in Release::ALL { + assert_eq!(setup(network, release).hard_coded, want, "{release:?}"); + } +} + +#[rstest] +#[case::mainnet(Network::Main, Some(true))] +#[case::testnet(Network::Testnet3, Some(false))] +#[case::devnet(Network::Devnet, Some(false))] +#[case::regtest(Network::Regtest, Some(true))] +fn only_v23_requires_standard(#[case] network: Network, #[case] v23: Option) { + assert_eq!(setup(network, Release::V23_1).require_standard, v23); + assert_eq!(setup(network, Release::V24_0).require_standard, None); +} + +/// The blocks pruning keeps, 288 on every chain at v23.1. At v24.0.0-rc.5 it +/// is 2304 (four days), but 288 on regtest. +#[rstest] +#[case::mainnet(Network::Main, 2304)] +#[case::testnet(Network::Testnet3, 2304)] +#[case::devnet(Network::Devnet, 2304)] +#[case::regtest(Network::Regtest, 288)] +fn min_blocks_to_keep_follows_the_release(#[case] network: Network, #[case] v24: u32) { + assert_eq!(setup(network, Release::V23_1).min_blocks_to_keep, 288); + assert_eq!(setup(network, Release::V24_0).min_blocks_to_keep, v24); +} + +#[rstest] +#[case::mainnet(Network::Main, "")] +#[case::testnet(Network::Testnet3, "testnet3")] +#[case::devnet(Network::Devnet, "devnet")] +#[case::regtest(Network::Regtest, "regtest")] +fn data_dirs_are_the_references(#[case] network: Network, #[case] dir: &str) { + assert_eq!(setup(network, Release::V24_0).data_dir(), dir); +} + +#[rstest] +fn devnet_checkpoints_hold_its_devnet_genesis_block(#[values(Release::V23_1, Release::V24_0)] release: Release) { + let setup = setup(Network::Devnet, release); + assert_eq!(setup.devnet_name(), Some("devnet")); + let consensus = &setup.consensus; + assert_eq!( + setup.checkpoints, + [ + (BlockHeight::from_u32(0), consensus.hash_genesis_block), + (BlockHeight::from_u32(1), consensus.hash_devnet_genesis_block), + ] + ); +} + +/// Off devnets, a setup has no devnet name. +#[rstest] +fn only_devnets_have_a_devnet_name(#[values(Network::Main, Network::Testnet3, Network::Regtest)] network: Network) { + let setup = setup(network, Release::V24_0); + assert_eq!(setup.devnet_name(), None); +} From 441a1855ba8f5cc2f31c2f09b0f894b32baaa254 Mon Sep 17 00:00:00 2001 From: pasta Date: Sun, 1 Nov 2026 00:03:07 +0000 Subject: [PATCH 2/5] params%feat: build devnet genesis blocks DevnetGenesisParams finds a devnet's genesis nonce with X11 (dash-pow, default features off, portable forwarded). Primitives builds the block, and a test ties both encoders over every push size of the devnet name. --- Cargo.lock | 1 + MODULE.bazel.lock | 10 +- pkgs/p2p_core/Cargo.toml | 1 + pkgs/params/BUILD.bazel | 2 + pkgs/params/Cargo.toml | 2 + pkgs/params/src/genesis.rs | 196 ++++++++++++++++++++++++- pkgs/params/src/lib.rs | 2 +- pkgs/params/src/setup.rs | 13 +- pkgs/params/tests/setup.rs | 19 ++- pkgs/primitives/Cargo.toml | 7 +- pkgs/primitives/src/block.rs | 36 ++++- pkgs/primitives/tests/genesis_valid.rs | 28 +++- pkgs/script/Cargo.toml | 2 +- 13 files changed, 304 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cba38fdba..d533f9a6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -483,6 +483,7 @@ dependencies = [ "bitcoin_hashes", "dash-dev", "dash-num", + "dash-pow", "dash-types", "hex-conservative", "rstest", diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0106cfcb4..6602d6b55 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -501,19 +501,19 @@ "REPO_MAPPING:rules_rust+,bazel_skylib bazel_skylib+", "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools", "REPO_MAPPING:rules_rust+,rules_cc rules_cc+", - "FILE:@@//Cargo.lock 590df2fdbab282abf409c3e2cd3ed7faba88a3b9ab33673036e0f5445cc86095", + "FILE:@@//Cargo.lock 1f10666b5a882ed372133d43695a98baed977bddad793119af4053d343bac31b", "FILE:@@//Cargo.toml 0c99f15255905f4007ab27422a37858db72bf3aa4b1f866abeb4ba6136c9c911", "FILE:@@//meta/bazel/Cargo.toml 18d39dfb79d3091469a8b1ce540703b22b523f7cb8e59436d6828457cc515d73", "FILE:@@//pkgs/num/Cargo.toml 04e621c98e203978d3a738292e5d6057f036d8d7eb94efd5e7dc3c57b2df5f51", "FILE:@@//pkgs/types/Cargo.toml 799d7b380252085f067daf6e89b8cc4853683cbf10495e97116abf3da8473143", "FILE:@@//pkgs/types/marker/Cargo.toml f942e6618c2cf5807e8186e69795f08a641bc25ca4fe7babb835c1970a181d26", "FILE:@@//meta/dev/Cargo.toml 6ce2554a5f2715d749e17db39c665ba4a0a4b06f0be435f6c96a602a26ce29bd", - "FILE:@@//pkgs/params/Cargo.toml e41ec68cf9db3ca5acec94c30c3718483cdba9a3f92cdf75ecc35973a3fa580c", + "FILE:@@//pkgs/params/Cargo.toml d94f707ec2dabf4efd536bf9dac1260cb080af5bdf3b10f60c4f806e3fcf64c8", "FILE:@@//pkgs/pow/Cargo.toml 3f33e4320c8dc8836ac9655cbadd5e9cacee225b30950e309f265a66d5c29512", - "FILE:@@//pkgs/primitives/Cargo.toml 7693a4e45c573f346126d8420e66b6cdfff3513d02234448737c03cfb4c9096a", + "FILE:@@//pkgs/primitives/Cargo.toml 28e2182d59a3ffb268e54c069ff6d2b676b72f9e524fb4fe28403a297cd297a8", "FILE:@@//pkgs/pkc/Cargo.toml a16f6907ab4048fbe3aa7423f49aaa615ec5ecdc1faabf13ee4e958593cea8cf", - "FILE:@@//pkgs/script/Cargo.toml 4af90a885200f6b1397f7775f0079ae22d4fbbc8cc65b0f125a0624df46dcd48", - "FILE:@@//pkgs/p2p_core/Cargo.toml 62ca5fa4bf9bf453d0b8948ed541363f3dff352f8aaf8ce52293549e283f29e8" + "FILE:@@//pkgs/script/Cargo.toml 03f00d9e883c509232e699351d112b242cadd23a2461166e5a29120a1b98528f", + "FILE:@@//pkgs/p2p_core/Cargo.toml 217e6404ea228420a7e08bf209b70e2f3543a835053c93a9d70bd3f29c391447" ], "generatedRepoSpecs": { "crates": { diff --git a/pkgs/p2p_core/Cargo.toml b/pkgs/p2p_core/Cargo.toml index 8d84a2e03..ea34d4a21 100644 --- a/pkgs/p2p_core/Cargo.toml +++ b/pkgs/p2p_core/Cargo.toml @@ -31,6 +31,7 @@ serde = [ ] full = ["std", "serde"] portable = [ + "dash-params/portable", "dash-pkc/portable", "dash-primitives/portable", "dash-script/portable", diff --git a/pkgs/params/BUILD.bazel b/pkgs/params/BUILD.bazel index 02a34582e..8c052609c 100644 --- a/pkgs/params/BUILD.bazel +++ b/pkgs/params/BUILD.bazel @@ -7,8 +7,10 @@ dash_rust_library( "full", "std", ], + portable = True, deps = [ "//pkgs/num:dash-num", + "//pkgs/pow:dash-pow", "//pkgs/types:dash-types", ], ) diff --git a/pkgs/params/Cargo.toml b/pkgs/params/Cargo.toml index 1f493344b..8efdce632 100644 --- a/pkgs/params/Cargo.toml +++ b/pkgs/params/Cargo.toml @@ -28,11 +28,13 @@ full = [ "codec", "std", ] +portable = ["dash-pow/portable"] [dependencies] bitcoin_hashes = { workspace = true, features = ["alloc"] } bitcoin-units = { workspace = true, features = ["alloc"] } dash-num = { version = "0.2.0-beta", path = "../num", default-features = false } +dash-pow = { version = "0.1.0-beta", path = "../pow", default-features = false } dash-types = { version = "0.2.0-beta", path = "../types", default-features = false } hex-conservative = { workspace = true } diff --git a/pkgs/params/src/genesis.rs b/pkgs/params/src/genesis.rs index 2b5e1626f..48597c255 100644 --- a/pkgs/params/src/genesis.rs +++ b/pkgs/params/src/genesis.rs @@ -4,11 +4,18 @@ // See the accompanying file LICENSE or https://opensource.org/license/MIT // -//! Genesis block descriptor. +//! Genesis and devnet genesis block descriptors. +use crate::prelude::*; + +use bitcoin_hashes::sha256d; use bitcoin_units::Amount; +use dash_num::{Arith256, CompactTarget, Hash256}; +use dash_pow::__deps::digest::Digest; +use dash_pow::X11; #[cfg(feature = "codec")] use dash_types::type_id::Unencodable; +use dash_types::Numeric; use hex_conservative::hex; /// Fields that define a genesis block with a single coinbase transaction. @@ -46,4 +53,191 @@ impl GenesisParams { "d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070", "ac7b03a9ac" )); + + /// The genesis block's hash, the X11 hash of its header. + pub(crate) fn block_hash(&self) -> Hash256 { + let coinbase = coinbase(self.script_sig, self.reward, self.script_pubkey); + let merkle_root = sha256d::Hash::hash(&coinbase).to_byte_array(); + let mut header = header(self.version, Hash256::ZERO, &merkle_root, self.time, self.bits); + header[NONCE].copy_from_slice(&self.nonce.to_le_bytes()); + Hash256::from_lendian(X11::digest(header).into()) + } +} + +/// Fields that define a devnet genesis block, the block at height 1 that +/// names its devnet in a single coinbase transaction. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "codec", derive(Unencodable))] +pub struct DevnetGenesisParams { + /// The devnet's name, `devnet` or `devnet-`, which the coinbase input + /// script pushes. + pub name: String, + /// Hash of the genesis block it builds on. + pub prev_hash: Hash256, + /// Block timestamp (unix epoch seconds). + pub time: u32, + /// Compact difficulty target. + pub bits: u32, + /// Nonce used for proof-of-work. + pub nonce: u32, + /// Hash of the block. + pub hash: Hash256, +} + +impl DevnetGenesisParams { + /// Block version. + pub const VERSION: i32 = 4; + + /// Value of the coinbase output. + pub const REWARD: Amount = Amount::from_btc_u16(50); + + /// Output script of the coinbase transaction, `OP_RETURN`. + pub const SCRIPT_PUBKEY: &[u8] = &[0x6a]; + + /// The devnet genesis block of the devnet `name` on top of `genesis`. Its + /// nonce is the first from 0 whose X11 hash meets the genesis block's + /// target. + /// + /// `None` if `name` is empty or too long for a script push, or if no + /// nonce below `u32::MAX` qualifies. + pub fn find(name: &str, genesis: &GenesisParams) -> Option { + if name.is_empty() || push_prefix(name.len()).is_none() { + return None; + } + let mut params = Self { + name: String::from(name), + prev_hash: genesis.block_hash(), + time: genesis.time.wrapping_add(1), + bits: genesis.bits, + nonce: 0, + hash: Hash256::ZERO, + }; + let coinbase = coinbase(¶ms.script_sig(), Self::REWARD, Self::SCRIPT_PUBKEY); + let merkle_root = sha256d::Hash::hash(&coinbase).to_byte_array(); + let target = CompactTarget::new(params.bits).expand().value; + let mut header = header(Self::VERSION, params.prev_hash, &merkle_root, params.time, params.bits); + for nonce in 0..u32::MAX { + header[NONCE].copy_from_slice(&nonce.to_le_bytes()); + let hash = X11::digest(header); + if Arith256::from_lendian(hash.into()) <= target { + params.nonce = nonce; + params.hash = Hash256::from_lendian(hash.into()); + return Some(params); + } + } + None + } + + /// Input script of the coinbase transaction, `OP_1` and then the shortest + /// push of [`name`](Self::name). + /// + /// A name too long for any push, which [`find`](Self::find) refuses, gets + /// no push opcode. + pub fn script_sig(&self) -> Vec { + let name = self.name.as_bytes(); + let mut script = vec![0x51]; + script.extend(push_prefix(name.len()).unwrap_or_default()); + script.extend_from_slice(name); + script + } +} + +/// The opcode and length bytes of the shortest push of `len` bytes, or `None` +/// if no push holds that many. +fn push_prefix(len: usize) -> Option> { + let len = u32::try_from(len).ok()?; + let [b0, b1, ..] = len.to_le_bytes(); + Some(match len { + 0..=0x4b => vec![b0], + 0x4c..=0xff => vec![0x4c, b0], + 0x100..=0xffff => vec![0x4d, b0, b1], + _ => [&[0x4e][..], &len.to_le_bytes()].concat(), + }) +} + +/// The serialized coinbase transaction of a genesis block, whose txid is +/// the merkle root. +fn coinbase(script_sig: &[u8], reward: Amount, script_pubkey: &[u8]) -> Vec { + let mut tx = Vec::new(); + tx.extend_from_slice(&1_i32.to_le_bytes()); + tx.push(1); + tx.extend_from_slice(&[0; 32]); + tx.extend_from_slice(&u32::MAX.to_le_bytes()); + compact_size(&mut tx, script_sig.len()); + tx.extend_from_slice(script_sig); + tx.extend_from_slice(&u32::MAX.to_le_bytes()); + tx.push(1); + tx.extend_from_slice(&reward.to_sat().to_le_bytes()); + compact_size(&mut tx, script_pubkey.len()); + tx.extend_from_slice(script_pubkey); + tx.extend_from_slice(&0_u32.to_le_bytes()); + tx +} + +/// Where a serialized block header holds its nonce, its last four bytes. +const NONCE: core::ops::Range = 76..80; + +/// A serialized block header with a zero nonce, which callers write at +/// [`NONCE`]. +fn header(version: i32, prev_hash: Hash256, merkle_root: &[u8; 32], time: u32, bits: u32) -> [u8; 80] { + let mut header = [0; 80]; + header[..4].copy_from_slice(&version.to_le_bytes()); + header[4..36].copy_from_slice(&prev_hash.to_lendian()); + header[36..68].copy_from_slice(merkle_root); + header[68..72].copy_from_slice(&time.to_le_bytes()); + header[72..76].copy_from_slice(&bits.to_le_bytes()); + header +} + +/// Appends the CompactSize encoding of `n`. +fn compact_size(buf: &mut Vec, n: usize) { + match u64::try_from(n).unwrap_or(u64::MAX) { + n @ 0..=0xfc => buf.extend_from_slice(&n.to_le_bytes()[..1]), + n @ 0xfd..=0xffff => { + buf.push(0xfd); + buf.extend_from_slice(&n.to_le_bytes()[..2]); + } + n @ 0x1_0000..=0xffff_ffff => { + buf.push(0xfe); + buf.extend_from_slice(&n.to_le_bytes()[..4]); + } + n => { + buf.push(0xff); + buf.extend_from_slice(&n.to_le_bytes()); + } + } +} + +#[cfg(test)] +mod tests { + use super::push_prefix; + use crate::Network; + + use rstest::rstest; + + /// Every network's genesis header hashes to its genesis block hash. + #[rstest] + fn genesis_header_hashes_to_the_genesis_hash( + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, + ) { + let chain = network.chain(); + assert_eq!(chain.genesis.block_hash(), chain.consensus.hash_genesis_block); + } + + #[rstest] + #[case(0, Some(&[0x00][..]))] + #[case(0x4b, Some(&[0x4b][..]))] + #[case(0x4c, Some(&[0x4c, 0x4c][..]))] + #[case(0x100, Some(&[0x4d, 0x00, 0x01][..]))] + #[case(0x1_0000, Some(&[0x4e, 0x00, 0x00, 0x01, 0x00][..]))] + fn push_prefixes_are_the_shortest(#[case] len: usize, #[case] want: Option<&[u8]>) { + assert_eq!(push_prefix(len).as_deref(), want); + } + + /// A name of 4 GiB or more has no push, so no devnet genesis block. + #[cfg(target_pointer_width = "64")] + #[rstest] + fn no_push_holds_4_gib() { + assert_eq!(push_prefix(0x1_0000_0000), None); + } } diff --git a/pkgs/params/src/lib.rs b/pkgs/params/src/lib.rs index 7ac157183..911e97dec 100644 --- a/pkgs/params/src/lib.rs +++ b/pkgs/params/src/lib.rs @@ -35,7 +35,7 @@ pub use builder::ChainParamsBuilder; pub use chain::{ChainParams, ChainTxData, MessageStart}; pub use consensus::{BuriedDeployment, Checkpoint, ConsensusParams, BRR_PERIODS_PERMILLE}; pub use deployment::{Bip9Deployment, Bip9Deployments, DeploymentPos}; -pub use genesis::GenesisParams; +pub use genesis::{DevnetGenesisParams, GenesisParams}; pub use llmq::{LlmqParams, LlmqType}; pub use release::Release; pub use setup::{AssumeutxoData, ChainSetup, HardCodedHeights}; diff --git a/pkgs/params/src/setup.rs b/pkgs/params/src/setup.rs index c400b7bb3..c6e24cdee 100644 --- a/pkgs/params/src/setup.rs +++ b/pkgs/params/src/setup.rs @@ -9,7 +9,7 @@ mod tables; use crate::prelude::*; -use crate::{Bip9Deployment, ChainParams, DeploymentPos, Network, Release}; +use crate::{Bip9Deployment, ChainParams, DeploymentPos, DevnetGenesisParams, Network, Release}; use bitcoin_units::BlockHeight; use dash_num::Hash256; @@ -36,6 +36,8 @@ pub struct ChainSetup { chain: ChainParams, /// The devnet's name, on a devnet. devnet_name: Option, + /// The devnet genesis block (height 1), on a devnet. + devnet_genesis: Option, /// Whether non-standard transactions are rejected by default (v23 release /// only). pub require_standard: Option, @@ -62,12 +64,16 @@ impl ChainSetup { let mut chain = *network.chain(); release.write_chain(network, &mut chain); let devnet_name = (network == Network::Devnet).then(|| String::from("devnet")); + let devnet_genesis = devnet_name + .as_deref() + .and_then(|name| DevnetGenesisParams::find(name, &chain.genesis)); let extras = tables::extras(network); Self { network, release, chain, devnet_name, + devnet_genesis, require_standard: release.require_standard(network), assumeutxo: tables::assumeutxo(network, release), fixed_seeds: tables::fixed_seeds(network, release), @@ -95,6 +101,11 @@ impl ChainSetup { self.devnet_name.as_deref() } + /// The devnet genesis block (height 1), on a devnet. + pub const fn devnet_genesis(&self) -> Option<&DevnetGenesisParams> { + self.devnet_genesis.as_ref() + } + /// The chain's data directory, under the base data directory. Mainnet /// uses the base directory itself. pub fn data_dir(&self) -> &str { diff --git a/pkgs/params/tests/setup.rs b/pkgs/params/tests/setup.rs index 5985ec622..981e6ae93 100644 --- a/pkgs/params/tests/setup.rs +++ b/pkgs/params/tests/setup.rs @@ -6,10 +6,12 @@ //! The chain setup a node reads, against the network tables. +#![expect(clippy::unwrap_used, reason = "test code")] + use bitcoin_units::BlockHeight; use dash_params::{ - AddrParams, Bip9Deployment, ChainParams, ChainParamsBuilder, ChainSetup, DeploymentPos, HardCodedHeights, Network, - Release, + AddrParams, Bip9Deployment, ChainParams, ChainParamsBuilder, ChainSetup, DeploymentPos, DevnetGenesisParams, + HardCodedHeights, Network, Release, }; use rstest::rstest; @@ -191,6 +193,10 @@ fn data_dirs_are_the_references(#[case] network: Network, #[case] dir: &str) { fn devnet_checkpoints_hold_its_devnet_genesis_block(#[values(Release::V23_1, Release::V24_0)] release: Release) { let setup = setup(Network::Devnet, release); assert_eq!(setup.devnet_name(), Some("devnet")); + let devnet_genesis = setup.devnet_genesis().unwrap(); + assert_eq!(devnet_genesis.name, "devnet"); + assert_eq!(devnet_genesis.hash, setup.consensus.hash_devnet_genesis_block); + assert_eq!(devnet_genesis.prev_hash, setup.consensus.hash_genesis_block); let consensus = &setup.consensus; assert_eq!( setup.checkpoints, @@ -201,9 +207,16 @@ fn devnet_checkpoints_hold_its_devnet_genesis_block(#[values(Release::V23_1, Rel ); } -/// Off devnets, a setup has no devnet name. +/// Off devnets, a setup has no devnet name or devnet genesis block. #[rstest] fn only_devnets_have_a_devnet_name(#[values(Network::Main, Network::Testnet3, Network::Regtest)] network: Network) { let setup = setup(network, Release::V24_0); assert_eq!(setup.devnet_name(), None); + assert_eq!(setup.devnet_genesis(), None); +} + +/// A devnet needs a name. +#[rstest] +fn an_unnamed_devnet_has_no_genesis_block() { + assert_eq!(DevnetGenesisParams::find("", &Network::Regtest.chain().genesis), None); } diff --git a/pkgs/primitives/Cargo.toml b/pkgs/primitives/Cargo.toml index 11e02660b..a64425049 100644 --- a/pkgs/primitives/Cargo.toml +++ b/pkgs/primitives/Cargo.toml @@ -36,7 +36,12 @@ serde = [ "dash-types/serde", ] full = ["std", "serde"] -portable = ["dash-pkc/portable", "dash-pow/portable", "dash-script/portable"] +portable = [ + "dash-params/portable", + "dash-pkc/portable", + "dash-pow/portable", + "dash-script/portable", +] [dependencies] bitcoin-consensus-encoding = { workspace = true, features = ["alloc"] } diff --git a/pkgs/primitives/src/block.rs b/pkgs/primitives/src/block.rs index f3100dcfa..580feffa9 100644 --- a/pkgs/primitives/src/block.rs +++ b/pkgs/primitives/src/block.rs @@ -14,7 +14,7 @@ use crate::{codec_base, codec_type, hash_impl}; use bitcoin_hashes::sha256d; use bitcoin_primitives::script::{ScriptPubKeyBuf, ScriptSigBuf}; use dash_num::{make_hash, Arith256, CompactTarget, Hash256}; -use dash_params::GenesisParams; +use dash_params::{DevnetGenesisParams, GenesisParams}; use dash_pow::__deps::digest::Digest; use dash_pow::X11; use dash_types::codec::{self, BaseCodec}; @@ -277,6 +277,40 @@ impl From<&GenesisParams> for Block { } } +impl From<&DevnetGenesisParams> for Block { + fn from(params: &DevnetGenesisParams) -> Self { + let coinbase = Transaction::new( + 1, + TxType::Spend, + vec![TxIn::new( + OutPoint::new(TxHash::default(), 0xFFFF_FFFF), + ScriptSigBuf::from_bytes(params.script_sig()), + 0xFFFF_FFFF, + )], + vec![TxOut::new( + DevnetGenesisParams::REWARD, + ScriptPubKeyBuf::from_bytes(DevnetGenesisParams::SCRIPT_PUBKEY.to_vec()), + )], + 0, + Vec::new(), + ); + + let mut block = Block { + header: BlockHeader { + version: DevnetGenesisParams::VERSION, + prev_hash: BlockHash::from(params.prev_hash), + merkle_root: MerkleRoot::default(), + time: params.time, + bits: params.bits, + nonce: params.nonce, + }, + transactions: vec![coinbase], + }; + block.header.merkle_root = block.merkle().0; + block + } +} + #[cfg(all(test, feature = "serde"))] #[expect(clippy::panic, clippy::unwrap_used, reason = "test code")] mod tests { diff --git a/pkgs/primitives/tests/genesis_valid.rs b/pkgs/primitives/tests/genesis_valid.rs index b88b38278..bfb6b3b3f 100644 --- a/pkgs/primitives/tests/genesis_valid.rs +++ b/pkgs/primitives/tests/genesis_valid.rs @@ -6,7 +6,9 @@ //! Genesis validation test. -use dash_params::{ChainParams, Network}; +#![expect(clippy::unwrap_used, reason = "test code")] + +use dash_params::{ChainParams, DevnetGenesisParams, Network}; use dash_primitives::{Block, BlockHash, MerkleRoot}; use dash_types::{Hashable, Numeric}; use hex_conservative::hex; @@ -45,3 +47,27 @@ fn genesis_block_hash_matches( let expected = BlockHash::from(params.consensus.hash_genesis_block); assert_eq!(genesis.header().hash(), expected); } + +/// The devnet genesis block primitives builds from the parameters hashes to +/// the hash and nonce the parameters' own search found. The names straddle +/// each push size of the coinbase input script, whose prefix is checked. +#[rstest] +#[case::one_byte(String::from("x"), &[0x51, 0x01])] +#[case::longest_direct_push("x".repeat(75), &[0x51, 0x4b])] +#[case::shortest_pushdata1("x".repeat(76), &[0x51, 0x4c, 0x4c])] +#[case::longest_pushdata1("x".repeat(255), &[0x51, 0x4c, 0xff])] +#[case::shortest_pushdata2("x".repeat(256), &[0x51, 0x4d, 0x00, 0x01])] +#[case::non_ascii(String::from("devnet-\u{fc}n\u{ef}c\u{f8}d\u{e9}"), &[0x51, 0x12])] +fn devnet_genesis_blocks_match_their_params(#[case] name: String, #[case] push: &[u8]) { + let chain = Network::Regtest.chain(); + let params = DevnetGenesisParams::find(&name, &chain.genesis).unwrap(); + let script_sig = params.script_sig(); + assert_eq!(script_sig[..push.len()], *push); + assert_eq!(script_sig[push.len()..], *name.as_bytes()); + let block = Block::from(¶ms); + let header = block.header(); + assert_eq!(header.hash(), BlockHash::from(params.hash)); + assert_eq!(header.nonce(), params.nonce); + assert_eq!(header.prev_hash(), BlockHash::from(chain.consensus.hash_genesis_block)); + assert_eq!(header.merkle_root(), block.merkle().0); +} diff --git a/pkgs/script/Cargo.toml b/pkgs/script/Cargo.toml index 9bc12f398..7741938ba 100644 --- a/pkgs/script/Cargo.toml +++ b/pkgs/script/Cargo.toml @@ -39,7 +39,7 @@ full = [ "serde", "std", ] -portable = ["dash-pkc?/portable"] +portable = ["dash-params?/portable", "dash-pkc?/portable"] serde = [ "dash-pkc?/serde", "dash-types/serde", From da9b17feb8952e3f7515a31dc7b56e2f389d983c Mon Sep 17 00:00:00 2001 From: pasta Date: Sun, 1 Nov 2026 00:21:04 +0000 Subject: [PATCH 3/5] params%test: add the chain-params dump tool contrib/params builds a reference implementation tag from git archive, links a dump of its chain parameters and masternode payments against the node's libraries, and gen.py writes the corpora from those dumps. --- contrib/params/README.md | 28 +++ contrib/params/build.sh | 59 +++++ contrib/params/chainparams_dump.cpp | 345 ++++++++++++++++++++++++++++ contrib/params/gen.py | 177 ++++++++++++++ 4 files changed, 609 insertions(+) create mode 100644 contrib/params/README.md create mode 100755 contrib/params/build.sh create mode 100644 contrib/params/chainparams_dump.cpp create mode 100644 contrib/params/gen.py diff --git a/contrib/params/README.md b/contrib/params/README.md new file mode 100644 index 000000000..488c972f7 --- /dev/null +++ b/contrib/params/README.md @@ -0,0 +1,28 @@ +`pkgs/params/corpus/chainparams_v23_1.json5` and `chainparams_v24_0.json5` record the chain parameters of the reference +implementation at v23.1.8 and v24.0.0-rc.5, and `brr_payments.json5` its masternode payments around each block reward +reallocation period. `dash-params` checks its chain setup and its period table against them, and `dash-primitives` +checks the genesis block bytes. Every value comes from a dump program linked against the release's own libraries. + +* [`chainparams_dump.cpp`](chainparams_dump.cpp) prints, as JSON, the release's parameters of a chain after the release + parses its options and selects the chain, or the masternode payment at a height. +* [`build.sh`](build.sh) builds a release from `git archive` of its tag in a fresh tree and links the dump program + against the libraries its node links. +* [`gen.py`](gen.py) runs the dump programs and writes the corpora. + +## Regenerating + +`build.sh` needs a checkout of [the reference implementation](https://github.com/dashpay/dash) and what its depends +build needs on Linux: autotools, `make`, `pkg-config`, a C++20 compiler and a network connection for the depends +sources. It builds depends without a GUI, wallet, ZMQ or port mapping, configures the release against them and builds +only the libraries its node links. `JOBS` sets the parallel jobs (default 4), and `SOURCES_PATH` a directory of +downloaded depends sources to reuse. Each output directory must be new. + +```bash +contrib/params/build.sh ~/dash v23.1.8 /tmp/params-v23 +contrib/params/build.sh ~/dash v24.0.0-rc.5 /tmp/params-v24 +python3 contrib/params/gen.py --dump /tmp/params-v23 --dump /tmp/params-v24 --out pkgs/params/corpus +``` + +Each dump program records its tag, the tag's commit and the sha256 of `chainparams_dump.cpp`. `gen.py` refuses a dump +built from another `chainparams_dump.cpp`, and each corpus header names the release and the source's sha256. A v24 +release before v24.0.0-rc.5 lacks the pruning depth the dump prints, so it does not build. diff --git a/contrib/params/build.sh b/contrib/params/build.sh new file mode 100755 index 000000000..d7e708137 --- /dev/null +++ b/contrib/params/build.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (c) 2026-present, The Dash Core developers +# SPDX-License-Identifier: MIT +# See the accompanying file LICENSE or https://opensource.org/license/MIT +# +# Builds a reference implementation release from `git archive` of its tag and +# links chainparams_dump.cpp against the libraries its node links. +# +# build.sh +# +# Writes /chainparams_dump and the release tree /tree. +# The output dir must not hold an earlier build, which make could reuse. JOBS +# sets the parallel jobs (default 4) and SOURCES_PATH the depends download +# cache. +set -eu +here=$(cd "$(dirname "$0")" && pwd) +repo=$1 tag=$2 out=$3 +mkdir -p "$out" +out=$(cd "$out" && pwd) +tree="$out/tree" +log="$out/build.log" +if [ -e "$tree" ]; then + echo "build.sh: $tree exists, use a new output dir" >&2 + exit 1 +fi +commit=$(git -C "$repo" rev-parse --verify "$tag^{commit}") +source_sha256=$(sha256sum "$here/chainparams_dump.cpp" | cut -d' ' -f1) +mkdir "$tree" +git -C "$repo" archive "$commit" | tar -x -C "$tree" +cp "$here/chainparams_dump.cpp" "$tree/src/chainparams_dump.cpp" +jobs=${JOBS:-4} +host=$("$tree/depends/config.guess") +trap 'echo "build.sh: failed, see $log" >&2' EXIT +# The node needs no GUI, wallet, ZMQ or port mapping. +( + cd "$tree" + make -C depends -j"$jobs" HOST="$host" NO_QT=1 NO_WALLET=1 NO_ZMQ=1 NO_UPNP=1 \ + NO_NATPMP=1 NO_USDT=1 + ./autogen.sh + CONFIG_SITE="$tree/depends/$host/share/config.site" ./configure --prefix=/ \ + --disable-wallet --without-gui --disable-zmq --without-miniupnpc \ + --without-natpmp --disable-bench --disable-tests --disable-fuzz-binary \ + --disable-man --disable-ccache +) >"$log" 2>&1 +# The dump compiles and links with the node's own flags and libraries, from +# the release's src/Makefile. Make runs in src, so its paths are relative. +make -C "$tree/src" -j"$jobs" -f Makefile -f - chainparams_dump \ + >>"$log" 2>&1 < [args...] +// the parameters of after the release parses [args...] and selects +// the chain, as "params" and "ext", or the release's error text ("error"). +// chainparams_dump payment +// the mainnet masternode payment at in the classic reward era. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if CLIENT_VERSION_MAJOR >= 24 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +const std::function G_TRANSLATION_FUN = nullptr; + +#if !defined(DUMP_TAG) || !defined(DUMP_COMMIT) || !defined(DUMP_SOURCE_SHA256) +#error "build.sh defines DUMP_TAG, DUMP_COMMIT and DUMP_SOURCE_SHA256" +#endif + +namespace { + +UniValue HashHex(const uint256& hash) { return UniValue{hash.GetHex()}; } + +UniValue LlmqJson(const Consensus::LLMQParams& q) +{ + UniValue llmq{UniValue::VOBJ}; + llmq.pushKV("type", static_cast(q.type)); + llmq.pushKV("name", std::string{q.name}); + llmq.pushKV("useRotation", q.useRotation); + llmq.pushKV("size", q.size); + llmq.pushKV("minSize", q.minSize); + llmq.pushKV("threshold", q.threshold); + llmq.pushKV("dkgInterval", q.dkgInterval); + llmq.pushKV("dkgPhaseBlocks", q.dkgPhaseBlocks); + llmq.pushKV("dkgMiningWindowStart", q.dkgMiningWindowStart); + llmq.pushKV("dkgMiningWindowEnd", q.dkgMiningWindowEnd); + llmq.pushKV("dkgBadVotesThreshold", q.dkgBadVotesThreshold); + llmq.pushKV("signingActiveQuorumCount", q.signingActiveQuorumCount); + llmq.pushKV("keepOldConnections", q.keepOldConnections); + llmq.pushKV("keepOldKeys", q.keepOldKeys); + llmq.pushKV("recoveryMembers", q.recoveryMembers); + return llmq; +} + +UniValue ParamsJson(const CChainParams& chain) +{ + const Consensus::Params& c = chain.GetConsensus(); + UniValue consensus{UniValue::VOBJ}; + consensus.pushKV("hashGenesisBlock", HashHex(c.hashGenesisBlock)); + consensus.pushKV("hashDevnetGenesisBlock", HashHex(c.hashDevnetGenesisBlock)); + consensus.pushKV("nSubsidyHalvingInterval", c.nSubsidyHalvingInterval); + consensus.pushKV("nMasternodePaymentsStartBlock", c.nMasternodePaymentsStartBlock); + consensus.pushKV("nMasternodePaymentsIncreaseBlock", c.nMasternodePaymentsIncreaseBlock); + consensus.pushKV("nMasternodePaymentsIncreasePeriod", c.nMasternodePaymentsIncreasePeriod); + consensus.pushKV("nInstantSendConfirmationsRequired", c.nInstantSendConfirmationsRequired); + consensus.pushKV("nInstantSendKeepLock", c.nInstantSendKeepLock); + consensus.pushKV("nBudgetPaymentsStartBlock", c.nBudgetPaymentsStartBlock); + consensus.pushKV("nBudgetPaymentsCycleBlocks", c.nBudgetPaymentsCycleBlocks); + consensus.pushKV("nBudgetPaymentsWindowBlocks", c.nBudgetPaymentsWindowBlocks); + consensus.pushKV("nSuperblockStartBlock", c.nSuperblockStartBlock); + consensus.pushKV("nSuperblockStartHash", HashHex(c.nSuperblockStartHash)); + consensus.pushKV("nSuperblockCycle", c.nSuperblockCycle); + consensus.pushKV("nSuperblockMaturityWindow", c.nSuperblockMaturityWindow); + consensus.pushKV("nGovernanceMinQuorum", c.nGovernanceMinQuorum); + consensus.pushKV("nGovernanceFilterElements", c.nGovernanceFilterElements); + consensus.pushKV("nMasternodeMinimumConfirmations", c.nMasternodeMinimumConfirmations); + consensus.pushKV("BIP34Height", c.BIP34Height); + consensus.pushKV("BIP34Hash", HashHex(c.BIP34Hash)); + consensus.pushKV("BIP65Height", c.BIP65Height); + consensus.pushKV("BIP66Height", c.BIP66Height); + consensus.pushKV("BIP147Height", c.BIP147Height); + consensus.pushKV("CSVHeight", c.CSVHeight); + consensus.pushKV("DIP0001Height", c.DIP0001Height); + consensus.pushKV("DIP0003Height", c.DIP0003Height); + consensus.pushKV("DIP0003EnforcementHeight", c.DIP0003EnforcementHeight); + consensus.pushKV("DIP0003EnforcementHash", HashHex(c.DIP0003EnforcementHash)); + consensus.pushKV("DIP0008Height", c.DIP0008Height); + consensus.pushKV("BRRHeight", c.BRRHeight); + consensus.pushKV("DIP0020Height", c.DIP0020Height); + consensus.pushKV("DIP0024Height", c.DIP0024Height); + consensus.pushKV("DIP0024QuorumsHeight", c.DIP0024QuorumsHeight); + consensus.pushKV("V19Height", c.V19Height); + consensus.pushKV("V20Height", c.V20Height); + consensus.pushKV("MN_RRHeight", c.MN_RRHeight); + consensus.pushKV("WithdrawalsHeight", c.WithdrawalsHeight); + consensus.pushKV("MinBIP9WarningHeight", c.MinBIP9WarningHeight); + consensus.pushKV("nRuleChangeActivationThreshold", uint64_t{c.nRuleChangeActivationThreshold}); + consensus.pushKV("nMinerConfirmationWindow", uint64_t{c.nMinerConfirmationWindow}); + UniValue deployments{UniValue::VARR}; + for (int i = 0; i < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) { + const Consensus::BIP9Deployment& d = c.vDeployments[i]; + UniValue dep{UniValue::VOBJ}; + dep.pushKV("name", VersionBitsDeploymentInfo[i].name); + dep.pushKV("bit", d.bit); + dep.pushKV("nStartTime", d.nStartTime); + dep.pushKV("nTimeout", d.nTimeout); + dep.pushKV("min_activation_height", d.min_activation_height); + dep.pushKV("nWindowSize", d.nWindowSize); + dep.pushKV("nThresholdStart", d.nThresholdStart); + dep.pushKV("nThresholdMin", d.nThresholdMin); + dep.pushKV("nFalloffCoeff", d.nFalloffCoeff); + dep.pushKV("useEHF", d.useEHF); + deployments.push_back(dep); + } + consensus.pushKV("vDeployments", deployments); + consensus.pushKV("powLimit", HashHex(c.powLimit)); + consensus.pushKV("fPowAllowMinDifficultyBlocks", c.fPowAllowMinDifficultyBlocks); + consensus.pushKV("fPowNoRetargeting", c.fPowNoRetargeting); + consensus.pushKV("nPowTargetSpacing", c.nPowTargetSpacing); + consensus.pushKV("nPowTargetTimespan", c.nPowTargetTimespan); + consensus.pushKV("nPowKGWHeight", c.nPowKGWHeight); + consensus.pushKV("nPowDGWHeight", c.nPowDGWHeight); + consensus.pushKV("nMinimumChainWork", HashHex(c.nMinimumChainWork)); + consensus.pushKV("defaultAssumeValid", HashHex(c.defaultAssumeValid)); + consensus.pushKV("nMinimumDifficultyBlocks", c.nMinimumDifficultyBlocks); + consensus.pushKV("nHighSubsidyBlocks", c.nHighSubsidyBlocks); + consensus.pushKV("nHighSubsidyFactor", c.nHighSubsidyFactor); + UniValue llmqs{UniValue::VARR}; + for (const auto& q : c.llmqs) llmqs.push_back(LlmqJson(q)); + consensus.pushKV("llmqs", llmqs); + consensus.pushKV("llmqTypeChainLocks", static_cast(c.llmqTypeChainLocks)); + consensus.pushKV("llmqTypeDIP0024InstantSend", static_cast(c.llmqTypeDIP0024InstantSend)); + consensus.pushKV("llmqTypePlatform", static_cast(c.llmqTypePlatform)); + consensus.pushKV("llmqTypeMnhf", static_cast(c.llmqTypeMnhf)); + + UniValue base58{UniValue::VOBJ}; + base58.pushKV("PUBKEY_ADDRESS", HexStr(chain.Base58Prefix(CChainParams::PUBKEY_ADDRESS))); + base58.pushKV("SCRIPT_ADDRESS", HexStr(chain.Base58Prefix(CChainParams::SCRIPT_ADDRESS))); + base58.pushKV("SECRET_KEY", HexStr(chain.Base58Prefix(CChainParams::SECRET_KEY))); + base58.pushKV("EXT_PUBLIC_KEY", HexStr(chain.Base58Prefix(CChainParams::EXT_PUBLIC_KEY))); + base58.pushKV("EXT_SECRET_KEY", HexStr(chain.Base58Prefix(CChainParams::EXT_SECRET_KEY))); + + UniValue checkpoints{UniValue::VOBJ}; + for (const auto& [height, hash] : chain.Checkpoints().mapCheckpoints) { + checkpoints.pushKV(strprintf("%d", height), hash.GetHex()); + } + + UniValue ret{UniValue::VOBJ}; + ret.pushKV("networkID", chain.NetworkIDString()); + ret.pushKV("messageStart", HexStr(chain.MessageStart())); + CDataStream genesis{SER_NETWORK, PROTOCOL_VERSION}; + genesis << chain.GenesisBlock(); + ret.pushKV("defaultPort", int{chain.GetDefaultPort()}); + ret.pushKV("pruneAfterHeight", chain.PruneAfterHeight()); + ret.pushKV("genesisHash", chain.GenesisBlock().GetHash().GetHex()); + ret.pushKV("genesisBlock", HexStr(MakeUCharSpan(genesis))); + ret.pushKV("devnetGenesisHash", chain.DevNetGenesisBlock().GetHash().GetHex()); + ret.pushKV("extCoinType", chain.ExtCoinType()); + ret.pushKV("base58Prefixes", base58); + ret.pushKV("checkpoints", checkpoints); + ret.pushKV("consensus", consensus); + return ret; +} + +UniValue ExtJson(const CChainParams& chain) +{ + UniValue ext{UniValue::VOBJ}; + const CBaseChainParams& base = BaseParams(); + ext.pushKV("dataDir", base.DataDir()); + ext.pushKV("rpcPort", int{base.RPCPort()}); + ext.pushKV("onionServiceTargetPort", int{base.OnionServiceTargetPort()}); + ext.pushKV("defaultPlatformP2PPort", int{chain.GetDefaultPlatformP2PPort()}); + ext.pushKV("defaultPlatformHTTPPort", int{chain.GetDefaultPlatformHTTPPort()}); +#if CLIENT_VERSION_MAJOR >= 24 + ext.pushKV("minBlocksToKeep", chain.MinBlocksToKeep()); +#else + ext.pushKV("minBlocksToKeep", uint64_t{MIN_BLOCKS_TO_KEEP}); +#endif + ext.pushKV("assumedBlockchainSize", chain.AssumedBlockchainSize()); + ext.pushKV("assumedChainStateSize", chain.AssumedChainStateSize()); + UniValue seeds{UniValue::VARR}; + for (const auto& s : chain.DNSSeeds()) seeds.push_back(s); + ext.pushKV("dnsSeeds", seeds); + ext.pushKV("fixedSeeds", HexStr(chain.FixedSeeds())); + UniValue spork{UniValue::VARR}; +#if CLIENT_VERSION_MAJOR >= 24 + ext.pushKV("bech32PlatformHRP", chain.Bech32PlatformHRP()); + spork.push_back(chain.SporkAddress()); +#else + ext.pushKV("requireStandard", chain.RequireStandard()); + for (const auto& a : chain.SporkAddresses()) spork.push_back(a); +#endif + ext.pushKV("sporkAddresses", spork); + ext.pushKV("defaultConsistencyChecks", chain.DefaultConsistencyChecks()); + ext.pushKV("requireRoutableExternalIP", chain.RequireRoutableExternalIP()); + ext.pushKV("isTestChain", chain.IsTestChain()); + ext.pushKV("isMockableChain", chain.IsMockableChain()); + ext.pushKV("mineBlocksOnDemand", chain.MineBlocksOnDemand()); + ext.pushKV("allowMultipleAddressesFromGroup", chain.AllowMultipleAddressesFromGroup()); + ext.pushKV("llmqConnectionRetryTimeout", chain.LLMQConnectionRetryTimeout()); + ext.pushKV("poolMinParticipants", chain.PoolMinParticipants()); + ext.pushKV("poolMaxParticipants", chain.PoolMaxParticipants()); + ext.pushKV("fulfilledRequestExpireTime", chain.FulfilledRequestExpireTime()); + ext.pushKV("creditPoolPeriodBlocks", chain.CreditPoolPeriodBlocks()); + + // The rate goes out as its IEEE 754 bits, which JSON numbers can round. + const ChainTxData& tx = chain.TxData(); + UniValue txdata{UniValue::VOBJ}; + txdata.pushKV("nTime", tx.nTime); + txdata.pushKV("nTxCount", tx.nTxCount); + uint64_t rate_bits; + static_assert(sizeof(rate_bits) == sizeof(tx.dTxRate)); + std::memcpy(&rate_bits, &tx.dTxRate, sizeof(rate_bits)); + txdata.pushKV("dTxRateBits", strprintf("%016x", rate_bits)); + ext.pushKV("chainTxData", txdata); + + CDataStream devnet_genesis{SER_NETWORK, PROTOCOL_VERSION}; + devnet_genesis << chain.DevNetGenesisBlock(); + ext.pushKV("devnetGenesisBlock", HexStr(MakeUCharSpan(devnet_genesis))); + + UniValue assumeutxo{UniValue::VARR}; + for (const auto& [height, data] : chain.Assumeutxo()) { + UniValue au{UniValue::VOBJ}; + au.pushKV("height", height); + au.pushKV("hash_serialized", data.hash_serialized.ToString()); +#if CLIENT_VERSION_MAJOR >= 24 + au.pushKV("evo_hash", data.evo_hash.ToString()); +#endif + au.pushKV("nChainTx", uint64_t{data.nChainTx}); + assumeutxo.push_back(au); + } + ext.pushKV("assumeutxo", assumeutxo); + + UniValue info{UniValue::VARR}; + for (int i = 0; i < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) { + UniValue d{UniValue::VOBJ}; + d.pushKV("name", VersionBitsDeploymentInfo[i].name); + d.pushKV("gbt_force", VersionBitsDeploymentInfo[i].gbt_force); + info.push_back(d); + } + ext.pushKV("deploymentInfo", info); + + UniValue buried{UniValue::VOBJ}; + for (int i = Consensus::DEPLOYMENT_HEIGHTINCB; i <= Consensus::DEPLOYMENT_WITHDRAWALS; ++i) { + const auto dep = static_cast(i); + buried.pushKV(DeploymentName(dep), chain.GetConsensus().DeploymentHeight(dep)); + } + ext.pushKV("buriedDeployments", buried); + + UniValue available{UniValue::VARR}; + for (const auto& q : Consensus::available_llmqs) available.push_back(LlmqJson(q)); + ext.pushKV("availableLlmqs", available); + return ext; +} + +int DumpInfo() +{ + UniValue out{UniValue::VOBJ}; + out.pushKV("tag", DUMP_TAG); + out.pushKV("commit", DUMP_COMMIT); + out.pushKV("source_sha256", DUMP_SOURCE_SHA256); + out.pushKV("version", FormatFullVersion()); + std::printf("%s\n", out.write().c_str()); + return 0; +} + +int DumpParams(int argc, char* argv[]) +{ + std::vector args{"chainparams_dump"}; + for (int i = 1; i < argc; ++i) args.push_back(argv[i]); + UniValue out{UniValue::VOBJ}; + gArgs.ClearArgs(); + SetupChainParamsOptions(gArgs); + std::string error; + if (!gArgs.ParseParameters(args.size(), args.data(), error)) { + out.pushKV("error", error); + } else { + try { + SelectParams(argv[0]); + out.pushKV("params", ParamsJson(Params())); + out.pushKV("ext", ExtJson(Params())); + } catch (const std::exception& e) { + out.pushKV("error", std::string{e.what()}); + } + } + std::printf("%s\n", out.write().c_str()); + return 0; +} + +int DumpPayment(const char* height_arg, const char* value_arg) +{ + int height; + int64_t value; + if (!ParseInt32(height_arg, &height) || !ParseInt64(value_arg, &value)) { + std::fprintf(stderr, "payment: bad height or block value\n"); + return 2; + } + SelectParams(CBaseChainParams::MAIN); +#if CLIENT_VERSION_MAJOR >= 24 + const CAmount payment{GetMasternodePayment(height, value, Params().GetConsensus(), MnRewardEra::Classic)}; +#else + const CAmount payment{GetMasternodePayment(height, value, /*fV20Active=*/false)}; +#endif + UniValue out{UniValue::VOBJ}; + out.pushKV("height", height); + out.pushKV("block_value", value); + out.pushKV("payment", payment); + std::printf("%s\n", out.write().c_str()); + return 0; +} + +} // namespace + +int main(int argc, char* argv[]) +{ + const std::string mode{argc > 1 ? argv[1] : ""}; + if (mode == "info" && argc == 2) return DumpInfo(); + if (mode == "params" && argc > 2) return DumpParams(argc - 2, argv + 2); + if (mode == "payment" && argc == 4) return DumpPayment(argv[2], argv[3]); + std::fprintf(stderr, + "usage: %s info\n" + " %s params [args...]\n" + " %s payment \n", + argv[0], argv[0], argv[0]); + return 2; +} diff --git a/contrib/params/gen.py b/contrib/params/gen.py new file mode 100644 index 000000000..ea3be7782 --- /dev/null +++ b/contrib/params/gen.py @@ -0,0 +1,177 @@ +# +# Copyright (c) 2026-present, The Dash Core developers +# SPDX-License-Identifier: MIT +# See the accompanying file LICENSE or https://opensource.org/license/MIT +# + +"""Builds the chain-params corpora of pkgs/params/corpus. + +Every value comes from a chainparams_dump that build.sh linked against a +reference implementation release. Each dump writes the corpus of its release +line, chainparams_v_.json5, and together they write +brr_payments.json5. + + gen.py --dump DIR [--dump DIR ...] --out pkgs/params/corpus +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import re +import subprocess +import sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +CHAINS = ("main", "test", "devnet", "regtest") +BLOCK_VALUE = 1_000_000_000 +PERIODS = 19 + +CHAINPARAMS_HEADER = """\ +// Chain parameters of the reference implementation at {tag} ({commit}), +// for dash-params' chain setup test. +// +// "bases" holds the parameters of each chain with no options, as +// contrib/params/chainparams_dump prints them. "params" holds the consensus +// and network parameters, "ext" the chain's other parameters. Each entry is +// the output of the command above it. dash-primitives checks the genesis +// block bytes, dash-params every other value. +// +// Dump source sha256 {source}. +// Regenerate as contrib/params/README.md describes. +""" + +PAYMENTS_HEADER = """\ +// Masternode payments of the reference implementation on mainnet in the +// classic reward era, for a block value of {value} duffs, around each block +// reward reallocation period, for dash-params' period table test. +// +// "realloc_start" is the first height of the first period and +// "period_blocks" the length of each. Each row is the output of the +// contrib/params/chainparams_dump command beside it, at the release it is +// under, {releases}. +// +// Dump source sha256 {source}. +// Regenerate as contrib/params/README.md describes. +""" + + +def run(dump: Path, *args: str) -> dict: + proc = subprocess.run( # noqa: S603 + [dump / "chainparams_dump", *args], + capture_output=True, + text=True, + check=True, + ) + return json.loads(proc.stdout) + + +def release_line(tag: str) -> str: + m = re.fullmatch(r"v(\d+)\.(\d+)\.\d+(-rc\.\d+)?", tag) + if m is None: + sys.exit(f"{tag}: not a release tag") + return f"v{m[1]}_{m[2]}" + + +def json_block(value: object, indent: int) -> str: + text = json.dumps(value, indent=2) + return text.replace("\n", "\n" + " " * indent) + + +def chainparams_corpus(dump: Path, info: dict) -> tuple[str, dict]: + bases = {} + entries = [] + for chain in CHAINS: + out = run(dump, "params", chain) + if "error" in out: + sys.exit(f"{dump} {chain}: {out['error']}") + bases[chain] = out + entries.append( + f" // chainparams_dump params {chain}\n" + f' "{chain}": {json_block(out, 4)}' + ) + header = CHAINPARAMS_HEADER.format( + tag=info["tag"], commit=info["commit"][:12], source=info["source_sha256"] + ) + body = ( + "{\n" + f' "version": {json.dumps(info["version"])},\n' + ' "bases": {\n' + ",\n".join(entries) + "\n }\n}\n" + ) + return header + body, bases["main"] + + +def payment_heights(main: dict) -> tuple[int, int, tuple[int, ...]]: + consensus = main["params"]["consensus"] + brr, cycle = consensus["BRRHeight"], consensus["nSuperblockCycle"] + start, period = brr - brr % cycle + cycle, 3 * cycle + heights = [start - 1] + for i in range(PERIODS): + heights += [start + i * period, start + (i + 1) * period - 1] + # One height well past the last period, whose share then holds. + heights.append(start + 40 * period) + return start, period, tuple(heights) + + +def payments_corpus(runs: list[tuple[Path, dict, dict]], source: str) -> str: + shapes = {payment_heights(main) for _, _, main in runs} + if len(shapes) != 1: + sys.exit("the releases disagree on the reallocation periods") + start, period, heights = shapes.pop() + sections = [] + for dump, info, _ in runs: + rows = [] + for height in heights: + args = ("payment", str(height), str(BLOCK_VALUE)) + out = run(dump, *args) + row = json.dumps({"height": height, "payment": out["payment"]}) + rows.append(f" {row}, // chainparams_dump {' '.join(args)}") + line = release_line(info["tag"]) + sections.append(f' "{line}": [\n' + "\n".join(rows) + "\n ]") + releases = ", ".join(f"{i['tag']} ({i['commit'][:12]})" for _, i, _ in runs) + header = PAYMENTS_HEADER.format( + value=BLOCK_VALUE, source=source, releases=releases + ) + return header + ( + "{\n" + f' "realloc_start": {start},\n' + f' "period_blocks": {period},\n' + f' "block_value": {BLOCK_VALUE},\n' + ' "payments": {\n' + ",\n".join(sections) + "\n }\n}\n" + ) + + +def build_corpora(dumps: list[Path]) -> dict[str, str]: + source = hashlib.sha256((HERE / "chainparams_dump.cpp").read_bytes()) + texts = {} + runs = [] + for dump in dumps: + info = run(dump, "info") + if info["source_sha256"] != source.hexdigest(): + sys.exit(f"{dump}: built from another chainparams_dump.cpp") + name = f"chainparams_{release_line(info['tag'])}.json5" + if name in texts: + sys.exit(f"{dump}: a second dump of {name}") + texts[name], main = chainparams_corpus(dump, info) + runs.append((dump, info, main)) + runs.sort(key=lambda r: release_line(r[1]["tag"])) + texts["brr_payments.json5"] = payments_corpus(runs, source.hexdigest()) + return texts + + +def main() -> int: + ap = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + ap.add_argument("--dump", type=Path, action="append", required=True) + ap.add_argument("--out", type=Path, required=True) + args = ap.parse_args() + for name, text in build_corpora(args.dump).items(): + (args.out / name).write_text(text) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From 7068596abe3ee628d39a7920ee1f6056381c006b Mon Sep 17 00:00:00 2001 From: pasta Date: Sun, 1 Nov 2026 00:21:10 +0000 Subject: [PATCH 4/5] params%test: check ChainSetup against the reference dumps Every chain with no options at v23.1.8 and v24.0.0-rc.5, from the public tags, and the payments around each reallocation period. Primitives checks the genesis and devnet genesis block bytes. --- pkgs/params/corpus/brr_payments.json5 | 102 + pkgs/params/corpus/chainparams_v23_1.json5 | 2138 ++++++++++++++++++ pkgs/params/corpus/chainparams_v24_0.json5 | 2206 +++++++++++++++++++ pkgs/params/tests/brr_payments.rs | 41 + pkgs/params/tests/reference_dumps.rs | 394 ++++ pkgs/primitives/tests/chainparams_blocks.rs | 50 + pkgs/primitives/tests/genesis_valid.rs | 31 +- 7 files changed, 4961 insertions(+), 1 deletion(-) create mode 100644 pkgs/params/corpus/brr_payments.json5 create mode 100644 pkgs/params/corpus/chainparams_v23_1.json5 create mode 100644 pkgs/params/corpus/chainparams_v24_0.json5 create mode 100644 pkgs/params/tests/brr_payments.rs create mode 100644 pkgs/params/tests/reference_dumps.rs create mode 100644 pkgs/primitives/tests/chainparams_blocks.rs diff --git a/pkgs/params/corpus/brr_payments.json5 b/pkgs/params/corpus/brr_payments.json5 new file mode 100644 index 000000000..b19c0b27f --- /dev/null +++ b/pkgs/params/corpus/brr_payments.json5 @@ -0,0 +1,102 @@ +// Masternode payments of the reference implementation on mainnet in the +// classic reward era, for a block value of 1000000000 duffs, around each block +// reward reallocation period, for dash-params' period table test. +// +// "realloc_start" is the first height of the first period and +// "period_blocks" the length of each. Each row is the output of the +// contrib/params/chainparams_dump command beside it, at the release it is +// under, v23.1.8 (728f5055836c), v24.0.0-rc.5 (8163290aa030). +// +// Dump source sha256 70ab0c6408c6b65224fbfd57fbedbd8772393816880ab05373a8a6696e674052. +// Regenerate as contrib/params/README.md describes. +{ + "realloc_start": 1379128, + "period_blocks": 49848, + "block_value": 1000000000, + "payments": { + "v23_1": [ + {"height": 1379127, "payment": 500000000}, // chainparams_dump payment 1379127 1000000000 + {"height": 1379128, "payment": 513000000}, // chainparams_dump payment 1379128 1000000000 + {"height": 1428975, "payment": 513000000}, // chainparams_dump payment 1428975 1000000000 + {"height": 1428976, "payment": 526000000}, // chainparams_dump payment 1428976 1000000000 + {"height": 1478823, "payment": 526000000}, // chainparams_dump payment 1478823 1000000000 + {"height": 1478824, "payment": 533000000}, // chainparams_dump payment 1478824 1000000000 + {"height": 1528671, "payment": 533000000}, // chainparams_dump payment 1528671 1000000000 + {"height": 1528672, "payment": 540000000}, // chainparams_dump payment 1528672 1000000000 + {"height": 1578519, "payment": 540000000}, // chainparams_dump payment 1578519 1000000000 + {"height": 1578520, "payment": 546000000}, // chainparams_dump payment 1578520 1000000000 + {"height": 1628367, "payment": 546000000}, // chainparams_dump payment 1628367 1000000000 + {"height": 1628368, "payment": 552000000}, // chainparams_dump payment 1628368 1000000000 + {"height": 1678215, "payment": 552000000}, // chainparams_dump payment 1678215 1000000000 + {"height": 1678216, "payment": 557000000}, // chainparams_dump payment 1678216 1000000000 + {"height": 1728063, "payment": 557000000}, // chainparams_dump payment 1728063 1000000000 + {"height": 1728064, "payment": 562000000}, // chainparams_dump payment 1728064 1000000000 + {"height": 1777911, "payment": 562000000}, // chainparams_dump payment 1777911 1000000000 + {"height": 1777912, "payment": 567000000}, // chainparams_dump payment 1777912 1000000000 + {"height": 1827759, "payment": 567000000}, // chainparams_dump payment 1827759 1000000000 + {"height": 1827760, "payment": 572000000}, // chainparams_dump payment 1827760 1000000000 + {"height": 1877607, "payment": 572000000}, // chainparams_dump payment 1877607 1000000000 + {"height": 1877608, "payment": 577000000}, // chainparams_dump payment 1877608 1000000000 + {"height": 1927455, "payment": 577000000}, // chainparams_dump payment 1927455 1000000000 + {"height": 1927456, "payment": 582000000}, // chainparams_dump payment 1927456 1000000000 + {"height": 1977303, "payment": 582000000}, // chainparams_dump payment 1977303 1000000000 + {"height": 1977304, "payment": 585000000}, // chainparams_dump payment 1977304 1000000000 + {"height": 2027151, "payment": 585000000}, // chainparams_dump payment 2027151 1000000000 + {"height": 2027152, "payment": 588000000}, // chainparams_dump payment 2027152 1000000000 + {"height": 2076999, "payment": 588000000}, // chainparams_dump payment 2076999 1000000000 + {"height": 2077000, "payment": 591000000}, // chainparams_dump payment 2077000 1000000000 + {"height": 2126847, "payment": 591000000}, // chainparams_dump payment 2126847 1000000000 + {"height": 2126848, "payment": 594000000}, // chainparams_dump payment 2126848 1000000000 + {"height": 2176695, "payment": 594000000}, // chainparams_dump payment 2176695 1000000000 + {"height": 2176696, "payment": 597000000}, // chainparams_dump payment 2176696 1000000000 + {"height": 2226543, "payment": 597000000}, // chainparams_dump payment 2226543 1000000000 + {"height": 2226544, "payment": 599000000}, // chainparams_dump payment 2226544 1000000000 + {"height": 2276391, "payment": 599000000}, // chainparams_dump payment 2276391 1000000000 + {"height": 2276392, "payment": 600000000}, // chainparams_dump payment 2276392 1000000000 + {"height": 2326239, "payment": 600000000}, // chainparams_dump payment 2326239 1000000000 + {"height": 3373048, "payment": 600000000}, // chainparams_dump payment 3373048 1000000000 + ], + "v24_0": [ + {"height": 1379127, "payment": 500000000}, // chainparams_dump payment 1379127 1000000000 + {"height": 1379128, "payment": 513000000}, // chainparams_dump payment 1379128 1000000000 + {"height": 1428975, "payment": 513000000}, // chainparams_dump payment 1428975 1000000000 + {"height": 1428976, "payment": 526000000}, // chainparams_dump payment 1428976 1000000000 + {"height": 1478823, "payment": 526000000}, // chainparams_dump payment 1478823 1000000000 + {"height": 1478824, "payment": 533000000}, // chainparams_dump payment 1478824 1000000000 + {"height": 1528671, "payment": 533000000}, // chainparams_dump payment 1528671 1000000000 + {"height": 1528672, "payment": 540000000}, // chainparams_dump payment 1528672 1000000000 + {"height": 1578519, "payment": 540000000}, // chainparams_dump payment 1578519 1000000000 + {"height": 1578520, "payment": 546000000}, // chainparams_dump payment 1578520 1000000000 + {"height": 1628367, "payment": 546000000}, // chainparams_dump payment 1628367 1000000000 + {"height": 1628368, "payment": 552000000}, // chainparams_dump payment 1628368 1000000000 + {"height": 1678215, "payment": 552000000}, // chainparams_dump payment 1678215 1000000000 + {"height": 1678216, "payment": 557000000}, // chainparams_dump payment 1678216 1000000000 + {"height": 1728063, "payment": 557000000}, // chainparams_dump payment 1728063 1000000000 + {"height": 1728064, "payment": 562000000}, // chainparams_dump payment 1728064 1000000000 + {"height": 1777911, "payment": 562000000}, // chainparams_dump payment 1777911 1000000000 + {"height": 1777912, "payment": 567000000}, // chainparams_dump payment 1777912 1000000000 + {"height": 1827759, "payment": 567000000}, // chainparams_dump payment 1827759 1000000000 + {"height": 1827760, "payment": 572000000}, // chainparams_dump payment 1827760 1000000000 + {"height": 1877607, "payment": 572000000}, // chainparams_dump payment 1877607 1000000000 + {"height": 1877608, "payment": 577000000}, // chainparams_dump payment 1877608 1000000000 + {"height": 1927455, "payment": 577000000}, // chainparams_dump payment 1927455 1000000000 + {"height": 1927456, "payment": 582000000}, // chainparams_dump payment 1927456 1000000000 + {"height": 1977303, "payment": 582000000}, // chainparams_dump payment 1977303 1000000000 + {"height": 1977304, "payment": 585000000}, // chainparams_dump payment 1977304 1000000000 + {"height": 2027151, "payment": 585000000}, // chainparams_dump payment 2027151 1000000000 + {"height": 2027152, "payment": 588000000}, // chainparams_dump payment 2027152 1000000000 + {"height": 2076999, "payment": 588000000}, // chainparams_dump payment 2076999 1000000000 + {"height": 2077000, "payment": 591000000}, // chainparams_dump payment 2077000 1000000000 + {"height": 2126847, "payment": 591000000}, // chainparams_dump payment 2126847 1000000000 + {"height": 2126848, "payment": 594000000}, // chainparams_dump payment 2126848 1000000000 + {"height": 2176695, "payment": 594000000}, // chainparams_dump payment 2176695 1000000000 + {"height": 2176696, "payment": 597000000}, // chainparams_dump payment 2176696 1000000000 + {"height": 2226543, "payment": 597000000}, // chainparams_dump payment 2226543 1000000000 + {"height": 2226544, "payment": 599000000}, // chainparams_dump payment 2226544 1000000000 + {"height": 2276391, "payment": 599000000}, // chainparams_dump payment 2276391 1000000000 + {"height": 2276392, "payment": 600000000}, // chainparams_dump payment 2276392 1000000000 + {"height": 2326239, "payment": 600000000}, // chainparams_dump payment 2326239 1000000000 + {"height": 3373048, "payment": 600000000}, // chainparams_dump payment 3373048 1000000000 + ] + } +} diff --git a/pkgs/params/corpus/chainparams_v23_1.json5 b/pkgs/params/corpus/chainparams_v23_1.json5 new file mode 100644 index 000000000..a8b5ec313 --- /dev/null +++ b/pkgs/params/corpus/chainparams_v23_1.json5 @@ -0,0 +1,2138 @@ +// Chain parameters of the reference implementation at v23.1.8 (728f5055836c), +// for dash-params' chain setup test. +// +// "bases" holds the parameters of each chain with no options, as +// contrib/params/chainparams_dump prints them. "params" holds the consensus +// and network parameters, "ext" the chain's other parameters. Each entry is +// the output of the command above it. dash-primitives checks the genesis +// block bytes, dash-params every other value. +// +// Dump source sha256 70ab0c6408c6b65224fbfd57fbedbd8772393816880ab05373a8a6696e674052. +// Regenerate as contrib/params/README.md describes. +{ + "version": "v23.1.8", + "bases": { + // chainparams_dump params main + "main": { + "params": { + "networkID": "main", + "messageStart": "bf0c6bbd", + "defaultPort": 9999, + "pruneAfterHeight": 100000, + "genesisHash": "00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0022ddb52f0ff0f1ec23fb9010101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "a33e7ae4978d4c851d725e5ed811a662f52ab65d011ef656ce5b968061842883", + "extCoinType": 5, + "base58Prefixes": { + "PUBKEY_ADDRESS": "4c", + "SCRIPT_ADDRESS": "10", + "SECRET_KEY": "cc", + "EXT_PUBLIC_KEY": "0488b21e", + "EXT_SECRET_KEY": "0488ade4" + }, + "checkpoints": { + "1500": "000000aaf0300f59f49bc3e970bad15c11f961fe2347accffff19d96ec9778e3", + "4991": "000000003b01809551952460744d5dbb8fcbd6cbae3c220267bf7fa43f837367", + "9918": "00000000213e229f332c0ffbe34defdaa9e74de87f2d8d1f01af8d121c3c170b", + "16912": "00000000075c0d10371d55a60634da70f197548dbbfa4123e12abfcbc5738af9", + "23912": "0000000000335eac6703f3b1732ec8b2f89c3ba3a7889e5767b090556bb9a276", + "35457": "0000000000b0ae211be59b048df14820475ad0dd53b9ff83b010f71a77342d9f", + "45479": "000000000063d411655d590590e16960f15ceea4257122ac430c6fbe39fbf02d", + "55895": "0000000000ae4c53a43639a4ca027282f69da9c67ba951768a20415b6439a2d7", + "68899": "0000000000194ab4d3d9eeb1f2f792f21bb39ff767cb547fe977640f969d77b7", + "74619": "000000000011d28f38f05d01650a502cc3f4d0e793fbc26e2a2ca71f07dc3842", + "75095": "0000000000193d12f6ad352a9996ee58ef8bdc4946818a5fec5ce99c11b87f0d", + "88805": "00000000001392f1652e9bf45cd8bc79dc60fe935277cd11538565b4a94fa85f", + "107996": "00000000000a23840ac16115407488267aa3da2b9bc843e301185b7d17e4dc40", + "137993": "00000000000cf69ce152b1bffdeddc59188d7a80879210d6e5c9503011929c3c", + "167996": "000000000009486020a80f7f2cc065342b0c2fb59af5e090cd813dba68ab0fed", + "207992": "00000000000d85c22be098f74576ef00b7aa00c05777e966aff68a270f1e01a5", + "312645": "0000000000059dcb71ad35a9e40526c44e7aae6c99169a9e7017b7d84b1c2daf", + "407452": "000000000003c6a87e73623b9d70af7cd908ae22fee466063e4ffc20be1d2dbc", + "523412": "000000000000e54f036576a10597e0e42cc22a5159ce572f999c33975e121d4d", + "523930": "0000000000000bccdb11c2b1cfb0ecab452abf267d89b7f46eaf2d54ce6e652c", + "750000": "00000000000000b4181bbbdddbae464ce11fede5d0292fb63fdede1e7c8ab21c", + "888900": "0000000000000026c29d576073ab51ebd1d3c938de02e9a44c7ee9e16f82db28", + "967800": "0000000000000024e26c7df7e46d673724d223cf4ca2b2adc21297cc095600f4", + "1067570": "000000000000001e09926bcf5fa4513d23e870a34f74e38200db99eb3f5b7a70", + "1167570": "000000000000000fb7b1e9b81700283dff0f7d87cf458e5edfdae00c669de661", + "1364585": "00000000000000022f355c52417fca9b73306958f7c0832b3a7bce006ca369ef", + "1450000": "00000000000000105cfae44a995332d8ec256850ea33a1f7b700474e3dad82bc", + "1796500": "000000000000001d531f36005159f19351bd49ca676398a561e55dcccb84eacd", + "1850400": "00000000000000261bdbe99c01fcba992e577efa6cc41aae564b8ca9f112b2a3", + "1889000": "00000000000000075300e852d5bf5380f905b2768241f8b442498442084807a7", + "1969000": "000000000000000c8b7a3bdcd8b9f516462122314529c8342244c685a4c899bf", + "2029000": "0000000000000020d5e38b6aef5bc8e430029444d7977b46f710c7d281ef1281", + "2109672": "000000000000001889bd33ef019065e250d32bd46911f4003d3fdd8128b5358d", + "2175051": "000000000000001cf26547602d982dcaa909231bbcd1e70c0eb3c65de25473ba", + "2216986": "0000000000000010b1135dc743f27f6fc8a138c6420a9d963fc676f96c2048f4", + "2361500": "0000000000000009ba1e8f47851d036bb618a4f6565eb3c32d1f647d450ff195", + "2421800": "000000000000000718ed026ebd644a8b70b42d4cbd7b25304c066c9bf15f85b7", + "2471728": "000000000000001a19ad7270422a00f86123ea94e0b295a3a796d6861bd7b032", + "2487500": "00000000000000119fe42827219e0686d3f7b494ae65f823194c740c5dbab492" + }, + "consensus": { + "hashGenesisBlock": "00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6", + "hashDevnetGenesisBlock": "0000000000000000000000000000000000000000000000000000000000000000", + "nSubsidyHalvingInterval": 210240, + "nMasternodePaymentsStartBlock": 100000, + "nMasternodePaymentsIncreaseBlock": 158000, + "nMasternodePaymentsIncreasePeriod": 17280, + "nInstantSendConfirmationsRequired": 6, + "nInstantSendKeepLock": 24, + "nBudgetPaymentsStartBlock": 328008, + "nBudgetPaymentsCycleBlocks": 16616, + "nBudgetPaymentsWindowBlocks": 100, + "nSuperblockStartBlock": 614820, + "nSuperblockStartHash": "0000000000020cb27c7ef164d21003d5d20cdca2f54dd9a9ca6d45f4d47f8aa3", + "nSuperblockCycle": 16616, + "nSuperblockMaturityWindow": 1662, + "nGovernanceMinQuorum": 10, + "nGovernanceFilterElements": 20000, + "nMasternodeMinimumConfirmations": 15, + "BIP34Height": 951, + "BIP34Hash": "000001f35e70f7c5705f64c6c5cc3dea9449e74d5b5c7cf74dad1bcca14a8012", + "BIP65Height": 619382, + "BIP66Height": 245817, + "BIP147Height": 939456, + "CSVHeight": 622944, + "DIP0001Height": 782208, + "DIP0003Height": 1028160, + "DIP0003EnforcementHeight": 1047200, + "DIP0003EnforcementHash": "000000000000002d1734087b4c5afc3133e4e1c3e1a89218f62bcd9bb3d17f81", + "DIP0008Height": 1088640, + "BRRHeight": 1374912, + "DIP0020Height": 1516032, + "DIP0024Height": 1737792, + "DIP0024QuorumsHeight": 1738698, + "V19Height": 1899072, + "V20Height": 1987776, + "MN_RRHeight": 2128896, + "WithdrawalsHeight": 2201472, + "MinBIP9WarningHeight": 2203488, + "nRuleChangeActivationThreshold": 1815, + "nMinerConfirmationWindow": 2016, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 12, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 4032, + "nThresholdStart": 3226, + "nThresholdMin": 2420, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": false, + "fPowNoRetargeting": false, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 15200, + "nPowDGWHeight": 34140, + "nMinimumChainWork": "00000000000000000000000000000000000000000000ba7225adc3153945d14d", + "defaultAssumeValid": "00000000000000119fe42827219e0686d3f7b494ae65f823194c740c5dbab492", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + } + ], + "llmqTypeChainLocks": 2, + "llmqTypeDIP0024InstantSend": 5, + "llmqTypePlatform": 4, + "llmqTypeMnhf": 3 + } + }, + "ext": { + "dataDir": "", + "rpcPort": 9998, + "onionServiceTargetPort": 9996, + "defaultPlatformP2PPort": 26656, + "defaultPlatformHTTPPort": 443, + "minBlocksToKeep": 288, + "assumedBlockchainSize": 57, + "assumedChainStateSize": 1, + "dnsSeeds": [ + "dnsseed.dash.org." + ], + "fixedSeeds": "0420ba5bab3a877c7498c27006d1350849b96b17d52621cca8c173319a4476cbd777270f0420b4c38d95481f090029a5ab00a37aae2d5e30728a3d082fabba6bbfe6fa59b8aa270f04209d329c4d1e352dbd4982b9a5664f455256ac5db3e7e3393eac8122102f23260d270f04207e87e89bd53f4bb62621ff57a7bef3085e90979dacc987ec5ca6db72b9b67932270f0420627b986dc470d769116ae85b7eace8a1ed4a67d733109bf1416bda703145ecfe270f04205c0de69424577850c8c3c0a1e8913f20e02371f2f320caca11f73a820833f8b3270f04205783984d479e719412674376a5625be6a2bc89905465d404123c04b1535b21e9270f0420574c369aa062ed8658fa037d05832f355675468a049de6d7be1efaf2366f29d0270f04204c2524e1b55c2c543a236d2faac27e32db1d970fc3cb604a28c85f63853a5d67270f04204a527b624ae4f68fb629c5f112f3094c18e5938373ac607dad561283ecec47e1270f0420463d6c95fee97af210f0a404783c91bf63c84b012b2b51a4e4d015b41bcf9ec1270f042044d4098b4679554a85892aee6881aa9a6327285fb0a8da6bac87df38325f2d89270f042047fb8b8727ca95e877ae41bd72206225e5679841850e9a5d4ab10f8f46a987a4270f04203f2381376b32e603dea5bcc9e8e698a6dce06cbb075e2364eaa9fa104088fcb7270f04203e84f83123dc6043c5ddd4a643a3956e1c5be18580e44b88e72fc6f0854e8298270f0420304dab0f94b0baafdba9ddb9ecc49e8f50e2668b3262851277af2045603936b3270f04202e5decf0624cca6e90df00651cca4acb66eea2a694278d6cec154be0a486e321270f04202109f10f0d0a69f782fce559b0bbe00651fd4030359537d55bf9dd737d2a8133270f0420060f6b3d30e44db0c9619cff8226183d058042410fe6de742b3f23fba7dab15c270f0420ed7ab30c6e589039cf5061d95c281a258f3e314c627fb996d443162519900f57270f0420ef3468e6b3c6c4d0cf22dc9209d02a634f6d6afd316ad4e9717306f046cb1713270f0420e0c1c978b5cead3f7f4abde0688388a45d39712dce5847ac239fc0145fdde952270f0420dd2a24e18845d1e6f99a7f8b23613755f42200921fc8e7a36ffa5bbf711dcfb9270f0420d89d506e4d6230388c108cb29eaa2da25f632a843e94970e8de1ea8bab78eafb270f0420d063bfe7a859b68dc416b2b2d61fcb38b217417dc8e2533140bb65c9bcb1bb29270f0104d99ae714270f0104d8ee4b2e270f0104d8e6e87d270f0104d48469be270f0104d41868e1270f0104d18d24ce270f0104d057665b270f0104cff4f728270f0104ca470e4f270f0104ca051021270f0104c3625fd2270f0104c31afee4270f0104c2ee19c7270f0104c2875464270f0104c2059dd6270f0104c0af7fc6270f0104c0a90657270f0104b9f373db270f0104b9e4539c270f0104b9e45384270f0104b9d8b305270f0104b9c113d6270f0104b9b92868270f0104b9a6d99a270f0104b9a5ab75270f0104b9a4a3da270f0104b9a4a355270f0104b970f935270f0104b970f931270f0104b91c6591270f0104b86bb6c6270f0104b2fdfd05270f0104b2d7ed87270f0104b2d7ed86270f0104b2d057e2270f0104b2d057d5270f0104b29d5bb1270f0104b23f7981270f0104b15d8d56270f0104b15d8d3c270f0104b0664191270f0104acee0719270f0104acecf451270f0104ac6891a6270f0104ac565b9e270f0104ac5649a0270f0104a87757c4270f0104a8775004270f0104a768d81c270f0104a758a910270f0104a516ea87270f0104a516dd61270f0104a3ac4229270f0104a161a573270f01049f4b79a3270f01049a103f70270f010498435fb8270f010497f455db270f010497f455c3270f010497f455b2270f010497f4557b270f010495686e77270f0104932d29d2270f0104901fbc2a270f01049018eeb2270f010488f46311270f0104851261e2270f010484f3c5f0270f010484f3c5b3270f010484f3c563270f010484f3c517270f010482ff9ba3270f010482a2e9ba270f01047bc140a6270f010473bef839270f01047284acd7270f01046deb43f6270f01046ca083c0270f01046bbd034a270f01046bb3ca4a270f01046baecce8270f01046baafea0270f01046a370916270f010468eaa773270f01045d73ac27270f01045d73ac25270f01045bc795b1270f01045bc66c28270f01045bc66c27270f01045bc66c25270f01045bc66c23270f01045bb8f9d1270f010459b34960270f0104597dd1c3270f0104597dd16e270f0104597dd145270f01045975391b270f0104597503f2270f0104592e2ada270f010459238395270f010457e41840270f010455d1f1f5270f010455d1f15d270f010455d1f157270f010455d1f156270f0104559bbc8a270f010454f7b4c9270f010454f2b3cc270f010454620cc4270f010454093211270f010453ef6328270f0104539564ba270f0104539564b9270f0104539564b8270f0104539564b7270f010452cae653270f010452b492c0270f010451e3fa33270f010450f99308270f010450f084e7270f010450d0e690270f01044e531300270f01044ddf6304270f01044ddd94cc270f01044a325a71270f0104483e3a6c270f0104483c26a0270f0104453d6bd7270f010442f5c434270f010442f4f346270f010442a37171270f010442a3715b270f010442a37107270f01043eab857d270f01043e3cf4ae270f01043424665b270f0104342109ac270f0104339ebc58270f0104339ea9ed270f0104339ea71f270f01042efafe0a270f01042e2428f2270f01042e1ebdbb270f01042e04a27f270f01042d99ba64270f01042d959ac2270f01042d809c1e270f01042d4f126a270f01042d3dba79270f01042d3a384f270f01042cf063d6270f01042be54d2e270f01042ba7f46d270f01042ba7ef91270f01042b86b471270f01042b85ab65270f010426667d6c270f010426360c6f270f01042561e315270f010422f6b019270f01041f946394270f01041f0a6124270f010417a300ae270f010405a16e4f270f010405236713270f01040502493a270f0104050243be270f010402e97823270f0104023bdb36270f010401754bdc270f", + "requireStandard": true, + "sporkAddresses": [ + "Xgtyuk76vhuFW2iT7UAiHgNdWXCf3J34wh" + ], + "defaultConsistencyChecks": false, + "requireRoutableExternalIP": true, + "isTestChain": false, + "isMockableChain": false, + "mineBlocksOnDemand": false, + "allowMultipleAddressesFromGroup": false, + "llmqConnectionRetryTimeout": 60, + "poolMinParticipants": 3, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 3600, + "creditPoolPeriodBlocks": 576, + "chainTxData": { + "nTime": 1781318234, + "nTxCount": 69770814, + "dTxRateBits": "3fc41701554ba334" + }, + "devnetGenesisBlock": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "assumeutxo": [], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 951, + "bip66": 245817, + "bip65": 619382, + "bip147": 939456, + "csv": 622944, + "dip0001": 782208, + "dip0003": 1028160, + "dip0008": 1088640, + "dip0020": 1516032, + "dip0024": 1737792, + "realloc": 1374912, + "v19": 1899072, + "v20": 1987776, + "mn_rr": 2128896, + "withdrawals": 2201472 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + }, + // chainparams_dump params test + "test": { + "params": { + "networkID": "test", + "messageStart": "cee2caff", + "defaultPort": 19999, + "pruneAfterHeight": 1000, + "genesisHash": "00000bafbc94add76cb75e2ec92894837288a481e5c005f6563d91623bf8bc2c", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0dee1e352f0ff0f1ec3c927e60101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "a33e7ae4978d4c851d725e5ed811a662f52ab65d011ef656ce5b968061842883", + "extCoinType": 1, + "base58Prefixes": { + "PUBKEY_ADDRESS": "8c", + "SCRIPT_ADDRESS": "13", + "SECRET_KEY": "ef", + "EXT_PUBLIC_KEY": "043587cf", + "EXT_SECRET_KEY": "04358394" + }, + "checkpoints": { + "255": "0000080b600e06f4c07880673f027210f9314575f5f875fafe51971e268b886a", + "261": "00000c26026d0815a7e2ce4fa270775f61403c040647ff2c3091f99e894a4618", + "1999": "00000052e538d27fa53693efe6fb6892a0c1d26c0235f599171c48a3cce553b1", + "2999": "0000024bc3f4f4cb30d29827c13d921ad77d2c6072e586c7f60d83c2722cdcc5", + "96090": "00000000033df4b94d17ab43e999caaf6c4735095cc77703685da81254d09bba", + "200000": "000000001015eb5ef86a8fe2b3074d947bc972c5befe32b28dd5ce915dc0d029", + "395750": "000008b78b6aef3fd05ab78db8b76c02163e885305545144420cb08704dce538", + "470000": "0000009303aeadf8cf3812f5c869691dbd4cb118ad20e9bf553be434bafe6a52", + "794950": "000001860e4c7248a9c5cc3bc7106041750560dc5cd9b3a2641b49494bcff5f2", + "808000": "00000104cb60a2b5e00a8a4259582756e5bf0dca201c0993c63f0e54971ea91a", + "840000": "000000cd7c3084499912ae893125c13e8c3c656abb6e511dcec6619c3d65a510", + "851000": "0000014d3b875540ff75517b7fbb1714e25d50ce92f65d7086cfce357928bb02", + "905100": "0000020c5e0f86f385cbf8e90210de9a9fd63633f01433bf47a6b3227a2851fd", + "960000": "0000000386cf5061ea16404c66deb83eb67892fa4f79b9e58e5eaab097ec2bd6", + "1069875": "00000034bfeb926662ba547c0b8dd4ba8cbb6e0c581f4e7d1bddce8f9ca3a608", + "1143608": "000000eef20eb0062abd4e799967e98bdebb165dd1c567ab4118c1c86c6e948f", + "1189000": "000001690314036dfbbecbdf382b230ead8e9c584241290a51f9f05a87a9cf7e", + "1295700": "00000107d42829a38e31c1a38c660d621e1ca376a880df1520e85e38af175d3a", + "1380000": "000000a98084beaf77ed26a905a7d59979009e23367a55b5d634962d7d65a1f9" + }, + "consensus": { + "hashGenesisBlock": "00000bafbc94add76cb75e2ec92894837288a481e5c005f6563d91623bf8bc2c", + "hashDevnetGenesisBlock": "0000000000000000000000000000000000000000000000000000000000000000", + "nSubsidyHalvingInterval": 210240, + "nMasternodePaymentsStartBlock": 4010, + "nMasternodePaymentsIncreaseBlock": 4030, + "nMasternodePaymentsIncreasePeriod": 10, + "nInstantSendConfirmationsRequired": 2, + "nInstantSendKeepLock": 6, + "nBudgetPaymentsStartBlock": 4100, + "nBudgetPaymentsCycleBlocks": 50, + "nBudgetPaymentsWindowBlocks": 10, + "nSuperblockStartBlock": 4200, + "nSuperblockStartHash": "0000000000000000000000000000000000000000000000000000000000000000", + "nSuperblockCycle": 24, + "nSuperblockMaturityWindow": 8, + "nGovernanceMinQuorum": 1, + "nGovernanceFilterElements": 500, + "nMasternodeMinimumConfirmations": 1, + "BIP34Height": 76, + "BIP34Hash": "000008ebb1db2598e897d17275285767717c6acfeac4c73def49fbea1ddcbcb6", + "BIP65Height": 2431, + "BIP66Height": 2075, + "BIP147Height": 4300, + "CSVHeight": 8064, + "DIP0001Height": 5500, + "DIP0003Height": 7000, + "DIP0003EnforcementHeight": 7300, + "DIP0003EnforcementHash": "00000055ebc0e974ba3a3fb785c5ad4365a39637d4df168169ee80d313612f8f", + "DIP0008Height": 78800, + "BRRHeight": 387500, + "DIP0020Height": 414100, + "DIP0024Height": 769700, + "DIP0024QuorumsHeight": 770730, + "V19Height": 850100, + "V20Height": 905100, + "MN_RRHeight": 1066900, + "WithdrawalsHeight": 1148500, + "MinBIP9WarningHeight": 1150516, + "nRuleChangeActivationThreshold": 1512, + "nMinerConfirmationWindow": 2016, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 12, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 100, + "nThresholdStart": 80, + "nThresholdMin": 60, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": true, + "fPowNoRetargeting": false, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 4002, + "nPowDGWHeight": 4002, + "nMinimumChainWork": "000000000000000000000000000000000000000000000000036c8f738da818d2", + "defaultAssumeValid": "000000541a23f9db7411cddbe50f9f1ebd4aa7108ebdcad62214753f648c0239", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ], + "llmqTypeChainLocks": 1, + "llmqTypeDIP0024InstantSend": 5, + "llmqTypePlatform": 6, + "llmqTypeMnhf": 1 + } + }, + "ext": { + "dataDir": "testnet3", + "rpcPort": 19998, + "onionServiceTargetPort": 19996, + "defaultPlatformP2PPort": 22000, + "defaultPlatformHTTPPort": 22001, + "minBlocksToKeep": 288, + "assumedBlockchainSize": 10, + "assumedChainStateSize": 1, + "dnsSeeds": [ + "testnet-seed.dashdot.io." + ], + "fixedSeeds": "0104d42f44c74e1f0104b9bba9c14e1f0104cef5a73f4e1f0104935d84094e1f010444437a484e1f010444437a2a4e1f010444437a214e1f010444437a174e1f01043e3cf4ae4e1f010436d55ed84e1f010436bf92894e1f010436bc45594e1f010434599a304e1f010423a212744e1f0104235c8f074e1f0104235bc5da4e1f0104235b86594e1f010422dc861e4e1f010422d21ac34e1f", + "requireStandard": false, + "sporkAddresses": [ + "yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55" + ], + "defaultConsistencyChecks": false, + "requireRoutableExternalIP": true, + "isTestChain": true, + "isMockableChain": false, + "mineBlocksOnDemand": false, + "allowMultipleAddressesFromGroup": false, + "llmqConnectionRetryTimeout": 60, + "poolMinParticipants": 2, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 300, + "creditPoolPeriodBlocks": 576, + "chainTxData": { + "nTime": 1765334452, + "nTxCount": 8182713, + "dTxRateBits": "3fc6ff7b30009c2c" + }, + "devnetGenesisBlock": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "assumeutxo": [], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 76, + "bip66": 2075, + "bip65": 2431, + "bip147": 4300, + "csv": 8064, + "dip0001": 5500, + "dip0003": 7000, + "dip0008": 78800, + "dip0020": 414100, + "dip0024": 769700, + "realloc": 387500, + "v19": 850100, + "v20": 905100, + "mn_rr": 1066900, + "withdrawals": 1148500 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + }, + // chainparams_dump params devnet + "devnet": { + "params": { + "networkID": "devnet", + "messageStart": "e2caffce", + "defaultPort": 19799, + "pruneAfterHeight": 1000, + "genesisHash": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0b9968054ffff7f20ffba10000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b", + "extCoinType": 1, + "base58Prefixes": { + "PUBKEY_ADDRESS": "8c", + "SCRIPT_ADDRESS": "13", + "SECRET_KEY": "ef", + "EXT_PUBLIC_KEY": "043587cf", + "EXT_SECRET_KEY": "04358394" + }, + "checkpoints": { + "0": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "1": "65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b" + }, + "consensus": { + "hashGenesisBlock": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "hashDevnetGenesisBlock": "65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b", + "nSubsidyHalvingInterval": 210240, + "nMasternodePaymentsStartBlock": 4010, + "nMasternodePaymentsIncreaseBlock": 4030, + "nMasternodePaymentsIncreasePeriod": 10, + "nInstantSendConfirmationsRequired": 2, + "nInstantSendKeepLock": 6, + "nBudgetPaymentsStartBlock": 4100, + "nBudgetPaymentsCycleBlocks": 50, + "nBudgetPaymentsWindowBlocks": 10, + "nSuperblockStartBlock": 4200, + "nSuperblockStartHash": "0000000000000000000000000000000000000000000000000000000000000000", + "nSuperblockCycle": 24, + "nSuperblockMaturityWindow": 8, + "nGovernanceMinQuorum": 1, + "nGovernanceFilterElements": 500, + "nMasternodeMinimumConfirmations": 1, + "BIP34Height": 1, + "BIP34Hash": "0000000000000000000000000000000000000000000000000000000000000000", + "BIP65Height": 1, + "BIP66Height": 1, + "BIP147Height": 1, + "CSVHeight": 1, + "DIP0001Height": 2, + "DIP0003Height": 2, + "DIP0003EnforcementHeight": 2, + "DIP0003EnforcementHash": "0000000000000000000000000000000000000000000000000000000000000000", + "DIP0008Height": 2, + "BRRHeight": 2, + "DIP0020Height": 2, + "DIP0024Height": 2, + "DIP0024QuorumsHeight": 2, + "V19Height": 2, + "V20Height": 2, + "MN_RRHeight": 2, + "WithdrawalsHeight": 2, + "MinBIP9WarningHeight": 2018, + "nRuleChangeActivationThreshold": 1512, + "nMinerConfirmationWindow": 2016, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 12, + "nStartTime": 1751328000, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 120, + "nThresholdStart": 96, + "nThresholdMin": 72, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": true, + "fPowNoRetargeting": false, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 4001, + "nPowDGWHeight": 4001, + "nMinimumChainWork": "0000000000000000000000000000000000000000000000000000000000000000", + "defaultAssumeValid": "0000000000000000000000000000000000000000000000000000000000000000", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + } + ], + "llmqTypeChainLocks": 101, + "llmqTypeDIP0024InstantSend": 105, + "llmqTypePlatform": 107, + "llmqTypeMnhf": 101 + } + }, + "ext": { + "dataDir": "devnet", + "rpcPort": 19798, + "onionServiceTargetPort": 19796, + "defaultPlatformP2PPort": 22100, + "defaultPlatformHTTPPort": 22101, + "minBlocksToKeep": 288, + "assumedBlockchainSize": 0, + "assumedChainStateSize": 0, + "dnsSeeds": [], + "fixedSeeds": "", + "requireStandard": false, + "sporkAddresses": [ + "yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55" + ], + "defaultConsistencyChecks": false, + "requireRoutableExternalIP": true, + "isTestChain": true, + "isMockableChain": false, + "mineBlocksOnDemand": false, + "allowMultipleAddressesFromGroup": true, + "llmqConnectionRetryTimeout": 60, + "poolMinParticipants": 2, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 300, + "creditPoolPeriodBlocks": 576, + "chainTxData": { + "nTime": 1417713338, + "nTxCount": 2, + "dTxRateBits": "3f847ae147ae147b" + }, + "devnetGenesisBlock": "040000002e3df23eec5cd6a86edd509539028e2c3a3dc05315eb28f2baa43218ca080000747a19c7b21b7bc837f190a9ff5af314df0517803e1c4f09b29aba37371754d8ba968054ffff7f20000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0851066465766e6574ffffffff0100f2052a01000000016a00000000", + "assumeutxo": [], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 1, + "bip66": 1, + "bip65": 1, + "bip147": 1, + "csv": 1, + "dip0001": 2, + "dip0003": 2, + "dip0008": 2, + "dip0020": 2, + "dip0024": 2, + "realloc": 2, + "v19": 2, + "v20": 2, + "mn_rr": 2, + "withdrawals": 2 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + }, + // chainparams_dump params regtest + "regtest": { + "params": { + "networkID": "regtest", + "messageStart": "fcc1b7dc", + "defaultPort": 19899, + "pruneAfterHeight": 1000, + "genesisHash": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0b9968054ffff7f20ffba10000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "a33e7ae4978d4c851d725e5ed811a662f52ab65d011ef656ce5b968061842883", + "extCoinType": 1, + "base58Prefixes": { + "PUBKEY_ADDRESS": "8c", + "SCRIPT_ADDRESS": "13", + "SECRET_KEY": "ef", + "EXT_PUBLIC_KEY": "043587cf", + "EXT_SECRET_KEY": "04358394" + }, + "checkpoints": { + "0": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e" + }, + "consensus": { + "hashGenesisBlock": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "hashDevnetGenesisBlock": "0000000000000000000000000000000000000000000000000000000000000000", + "nSubsidyHalvingInterval": 150, + "nMasternodePaymentsStartBlock": 240, + "nMasternodePaymentsIncreaseBlock": 350, + "nMasternodePaymentsIncreasePeriod": 10, + "nInstantSendConfirmationsRequired": 2, + "nInstantSendKeepLock": 6, + "nBudgetPaymentsStartBlock": 1000, + "nBudgetPaymentsCycleBlocks": 50, + "nBudgetPaymentsWindowBlocks": 10, + "nSuperblockStartBlock": 1500, + "nSuperblockStartHash": "0000000000000000000000000000000000000000000000000000000000000000", + "nSuperblockCycle": 20, + "nSuperblockMaturityWindow": 10, + "nGovernanceMinQuorum": 1, + "nGovernanceFilterElements": 100, + "nMasternodeMinimumConfirmations": 1, + "BIP34Height": 1, + "BIP34Hash": "0000000000000000000000000000000000000000000000000000000000000000", + "BIP65Height": 1, + "BIP66Height": 1, + "BIP147Height": 0, + "CSVHeight": 1, + "DIP0001Height": 1, + "DIP0003Height": 432, + "DIP0003EnforcementHeight": 500, + "DIP0003EnforcementHash": "0000000000000000000000000000000000000000000000000000000000000000", + "DIP0008Height": 1, + "BRRHeight": 1, + "DIP0020Height": 1, + "DIP0024Height": 1, + "DIP0024QuorumsHeight": 1, + "V19Height": 1, + "V20Height": 432, + "MN_RRHeight": 432, + "WithdrawalsHeight": 600, + "MinBIP9WarningHeight": 0, + "nRuleChangeActivationThreshold": 108, + "nMinerConfirmationWindow": 144, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": 0, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 12, + "nStartTime": 0, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 250, + "nThresholdStart": 200, + "nThresholdMin": 150, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": true, + "fPowNoRetargeting": true, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 15200, + "nPowDGWHeight": 34140, + "nMinimumChainWork": "0000000000000000000000000000000000000000000000000000000000000000", + "defaultAssumeValid": "0000000000000000000000000000000000000000000000000000000000000000", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + } + ], + "llmqTypeChainLocks": 100, + "llmqTypeDIP0024InstantSend": 103, + "llmqTypePlatform": 106, + "llmqTypeMnhf": 100 + } + }, + "ext": { + "dataDir": "regtest", + "rpcPort": 19898, + "onionServiceTargetPort": 19896, + "defaultPlatformP2PPort": 22200, + "defaultPlatformHTTPPort": 22201, + "minBlocksToKeep": 288, + "assumedBlockchainSize": 0, + "assumedChainStateSize": 0, + "dnsSeeds": [ + "dummySeed.invalid." + ], + "fixedSeeds": "", + "requireStandard": true, + "sporkAddresses": [ + "yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW" + ], + "defaultConsistencyChecks": true, + "requireRoutableExternalIP": false, + "isTestChain": true, + "isMockableChain": true, + "mineBlocksOnDemand": true, + "allowMultipleAddressesFromGroup": true, + "llmqConnectionRetryTimeout": 1, + "poolMinParticipants": 2, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 300, + "creditPoolPeriodBlocks": 100, + "chainTxData": { + "nTime": 0, + "nTxCount": 0, + "dTxRateBits": "0000000000000000" + }, + "devnetGenesisBlock": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "assumeutxo": [ + { + "height": 110, + "hash_serialized": "9b2a277a3e3b979f1a539d57e949495d7f8247312dbc32bce6619128c192b44b", + "nChainTx": 110 + }, + { + "height": 200, + "hash_serialized": "8a5bdd92252fc6b24663244bbe958c947bb036dc1f94ccd15439f48d8d1cb4e3", + "nChainTx": 200 + } + ], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 1, + "bip66": 1, + "bip65": 1, + "bip147": 0, + "csv": 1, + "dip0001": 1, + "dip0003": 432, + "dip0008": 1, + "dip0020": 1, + "dip0024": 1, + "realloc": 1, + "v19": 1, + "v20": 432, + "mn_rr": 432, + "withdrawals": 600 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + } + } +} diff --git a/pkgs/params/corpus/chainparams_v24_0.json5 b/pkgs/params/corpus/chainparams_v24_0.json5 new file mode 100644 index 000000000..366044ff3 --- /dev/null +++ b/pkgs/params/corpus/chainparams_v24_0.json5 @@ -0,0 +1,2206 @@ +// Chain parameters of the reference implementation at v24.0.0-rc.5 (8163290aa030), +// for dash-params' chain setup test. +// +// "bases" holds the parameters of each chain with no options, as +// contrib/params/chainparams_dump prints them. "params" holds the consensus +// and network parameters, "ext" the chain's other parameters. Each entry is +// the output of the command above it. dash-primitives checks the genesis +// block bytes, dash-params every other value. +// +// Dump source sha256 70ab0c6408c6b65224fbfd57fbedbd8772393816880ab05373a8a6696e674052. +// Regenerate as contrib/params/README.md describes. +{ + "version": "v24.0.0-rc.5", + "bases": { + // chainparams_dump params main + "main": { + "params": { + "networkID": "main", + "messageStart": "bf0c6bbd", + "defaultPort": 9999, + "pruneAfterHeight": 100000, + "genesisHash": "00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0022ddb52f0ff0f1ec23fb9010101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "a33e7ae4978d4c851d725e5ed811a662f52ab65d011ef656ce5b968061842883", + "extCoinType": 5, + "base58Prefixes": { + "PUBKEY_ADDRESS": "4c", + "SCRIPT_ADDRESS": "10", + "SECRET_KEY": "cc", + "EXT_PUBLIC_KEY": "0488b21e", + "EXT_SECRET_KEY": "0488ade4" + }, + "checkpoints": { + "1500": "000000aaf0300f59f49bc3e970bad15c11f961fe2347accffff19d96ec9778e3", + "4991": "000000003b01809551952460744d5dbb8fcbd6cbae3c220267bf7fa43f837367", + "9918": "00000000213e229f332c0ffbe34defdaa9e74de87f2d8d1f01af8d121c3c170b", + "16912": "00000000075c0d10371d55a60634da70f197548dbbfa4123e12abfcbc5738af9", + "23912": "0000000000335eac6703f3b1732ec8b2f89c3ba3a7889e5767b090556bb9a276", + "35457": "0000000000b0ae211be59b048df14820475ad0dd53b9ff83b010f71a77342d9f", + "45479": "000000000063d411655d590590e16960f15ceea4257122ac430c6fbe39fbf02d", + "55895": "0000000000ae4c53a43639a4ca027282f69da9c67ba951768a20415b6439a2d7", + "68899": "0000000000194ab4d3d9eeb1f2f792f21bb39ff767cb547fe977640f969d77b7", + "74619": "000000000011d28f38f05d01650a502cc3f4d0e793fbc26e2a2ca71f07dc3842", + "75095": "0000000000193d12f6ad352a9996ee58ef8bdc4946818a5fec5ce99c11b87f0d", + "88805": "00000000001392f1652e9bf45cd8bc79dc60fe935277cd11538565b4a94fa85f", + "107996": "00000000000a23840ac16115407488267aa3da2b9bc843e301185b7d17e4dc40", + "137993": "00000000000cf69ce152b1bffdeddc59188d7a80879210d6e5c9503011929c3c", + "167996": "000000000009486020a80f7f2cc065342b0c2fb59af5e090cd813dba68ab0fed", + "207992": "00000000000d85c22be098f74576ef00b7aa00c05777e966aff68a270f1e01a5", + "312645": "0000000000059dcb71ad35a9e40526c44e7aae6c99169a9e7017b7d84b1c2daf", + "407452": "000000000003c6a87e73623b9d70af7cd908ae22fee466063e4ffc20be1d2dbc", + "523412": "000000000000e54f036576a10597e0e42cc22a5159ce572f999c33975e121d4d", + "523930": "0000000000000bccdb11c2b1cfb0ecab452abf267d89b7f46eaf2d54ce6e652c", + "750000": "00000000000000b4181bbbdddbae464ce11fede5d0292fb63fdede1e7c8ab21c", + "888900": "0000000000000026c29d576073ab51ebd1d3c938de02e9a44c7ee9e16f82db28", + "967800": "0000000000000024e26c7df7e46d673724d223cf4ca2b2adc21297cc095600f4", + "1067570": "000000000000001e09926bcf5fa4513d23e870a34f74e38200db99eb3f5b7a70", + "1167570": "000000000000000fb7b1e9b81700283dff0f7d87cf458e5edfdae00c669de661", + "1364585": "00000000000000022f355c52417fca9b73306958f7c0832b3a7bce006ca369ef", + "1450000": "00000000000000105cfae44a995332d8ec256850ea33a1f7b700474e3dad82bc", + "1796500": "000000000000001d531f36005159f19351bd49ca676398a561e55dcccb84eacd", + "1850400": "00000000000000261bdbe99c01fcba992e577efa6cc41aae564b8ca9f112b2a3", + "1889000": "00000000000000075300e852d5bf5380f905b2768241f8b442498442084807a7", + "1969000": "000000000000000c8b7a3bdcd8b9f516462122314529c8342244c685a4c899bf", + "2029000": "0000000000000020d5e38b6aef5bc8e430029444d7977b46f710c7d281ef1281", + "2109672": "000000000000001889bd33ef019065e250d32bd46911f4003d3fdd8128b5358d", + "2175051": "000000000000001cf26547602d982dcaa909231bbcd1e70c0eb3c65de25473ba", + "2216986": "0000000000000010b1135dc743f27f6fc8a138c6420a9d963fc676f96c2048f4", + "2361500": "0000000000000009ba1e8f47851d036bb618a4f6565eb3c32d1f647d450ff195", + "2421800": "000000000000000718ed026ebd644a8b70b42d4cbd7b25304c066c9bf15f85b7", + "2471728": "000000000000001a19ad7270422a00f86123ea94e0b295a3a796d6861bd7b032", + "2487500": "00000000000000119fe42827219e0686d3f7b494ae65f823194c740c5dbab492", + "2563000": "000000000000000346a1804da4832b0b69dd9a7f96b14c7cb54585a9ac6ae98f" + }, + "consensus": { + "hashGenesisBlock": "00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6", + "hashDevnetGenesisBlock": "0000000000000000000000000000000000000000000000000000000000000000", + "nSubsidyHalvingInterval": 210240, + "nMasternodePaymentsStartBlock": 100000, + "nMasternodePaymentsIncreaseBlock": 158000, + "nMasternodePaymentsIncreasePeriod": 17280, + "nInstantSendConfirmationsRequired": 6, + "nInstantSendKeepLock": 24, + "nBudgetPaymentsStartBlock": 328008, + "nBudgetPaymentsCycleBlocks": 16616, + "nBudgetPaymentsWindowBlocks": 100, + "nSuperblockStartBlock": 614820, + "nSuperblockStartHash": "0000000000020cb27c7ef164d21003d5d20cdca2f54dd9a9ca6d45f4d47f8aa3", + "nSuperblockCycle": 16616, + "nSuperblockMaturityWindow": 1662, + "nGovernanceMinQuorum": 10, + "nGovernanceFilterElements": 20000, + "nMasternodeMinimumConfirmations": 15, + "BIP34Height": 951, + "BIP34Hash": "000001f35e70f7c5705f64c6c5cc3dea9449e74d5b5c7cf74dad1bcca14a8012", + "BIP65Height": 619382, + "BIP66Height": 245817, + "BIP147Height": 939456, + "CSVHeight": 622944, + "DIP0001Height": 782208, + "DIP0003Height": 1028160, + "DIP0003EnforcementHeight": 1047200, + "DIP0003EnforcementHash": "000000000000002d1734087b4c5afc3133e4e1c3e1a89218f62bcd9bb3d17f81", + "DIP0008Height": 1088640, + "BRRHeight": 1374912, + "DIP0020Height": 1516032, + "DIP0024Height": 1737792, + "DIP0024QuorumsHeight": 1738698, + "V19Height": 1899072, + "V20Height": 1987776, + "MN_RRHeight": 2128896, + "WithdrawalsHeight": 2201472, + "MinBIP9WarningHeight": 2203488, + "nRuleChangeActivationThreshold": 1815, + "nMinerConfirmationWindow": 2016, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 13, + "nStartTime": 1794182400, + "nTimeout": 1857340800, + "min_activation_height": 0, + "nWindowSize": 4032, + "nThresholdStart": 3226, + "nThresholdMin": 2420, + "nFalloffCoeff": 5, + "useEHF": true + }, + { + "name": "evo_shares", + "bit": 14, + "nStartTime": 1794182400, + "nTimeout": 1857340800, + "min_activation_height": 0, + "nWindowSize": 4032, + "nThresholdStart": 3226, + "nThresholdMin": 2420, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": false, + "fPowNoRetargeting": false, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 15200, + "nPowDGWHeight": 34140, + "nMinimumChainWork": "00000000000000000000000000000000000000000000c15981a81af44a6abe1a", + "defaultAssumeValid": "000000000000000346a1804da4832b0b69dd9a7f96b14c7cb54585a9ac6ae98f", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + } + ], + "llmqTypeChainLocks": 2, + "llmqTypeDIP0024InstantSend": 5, + "llmqTypePlatform": 4, + "llmqTypeMnhf": 3 + } + }, + "ext": { + "dataDir": "", + "rpcPort": 9998, + "onionServiceTargetPort": 9996, + "defaultPlatformP2PPort": 26656, + "defaultPlatformHTTPPort": 443, + "minBlocksToKeep": 2304, + "assumedBlockchainSize": 62, + "assumedChainStateSize": 1, + "dnsSeeds": [ + "dnsseed.dash.org." + ], + "fixedSeeds": "0420cfb5e558be0d672d55acca2a4fb818888fd21548a91f186c7999baa586cecbba270f0420c236fcafff7c46843e7526acea2ad4f1b121960194a81b0a1751cf5f521bc0db270f0420ba5bab3a877c7498c27006d1350849b96b17d52621cca8c173319a4476cbd777270f0420ae08410ddf89564f35fc2a45513e094181c7e3847d257f7122f895e47092a55b270f04209d329c4d1e352dbd4982b9a5664f455256ac5db3e7e3393eac8122102f23260d270f0420835025a93357385d60d29e7b7b2bfbb172951c65b8b59515204ea4627b1637ea270f042080c965bbe7dd120ec185df981c8d0ea4f17c17b1f72cfaff9922f2cc8491fe63270f04207dd03c5edb99248efadc32cd6748d219e858d547b576eeda9cd57cbc6cfe93ac270f04207e87e89bd53f4bb62621ff57a7bef3085e90979dacc987ec5ca6db72b9b67932270f04206d54e7bea858cd359980b2326c86a2a911623d3b67345dd1203141923f8e5726270f0420609b96e1cafd869083e3eb908e372c584cb77986b84b10b2929b7765466ccf84270f04205594a681ae3385fe02ec3dccc21e62230c1668eef868281e5c951fdf9ffe6d3d270f04205783984d479e719412674376a5625be6a2bc89905465d404123c04b1535b21e9270f0420574c369aa062ed8658fa037d05832f355675468a049de6d7be1efaf2366f29d0270f042049b9652324d9714256a068a15c734dc728ba96e6d69edd6afe00c9a40b325c19270f042045e9fa710ab15a05d18144165d62bfd8d24909b575e7979c3396504d1b440eae270f042044d4098b4679554a85892aee6881aa9a6327285fb0a8da6bac87df38325f2d89270f04204167eea8aef7d77c7a805aaf2dfd9bd193ab8ae992234ccad9035ef9d71aa0aa270f04203f2381376b32e603dea5bcc9e8e698a6dce06cbb075e2364eaa9fa104088fcb7270f04203e96f49d6bf8aedfcc0feb500899a0c17243c90f508f681f4b5a80110172203d270f04202e5decf0624cca6e90df00651cca4acb66eea2a694278d6cec154be0a486e321270f04201f3b77a4090552600bdcd424d04a50fa2d5c9cf1d0f24c2de9190dd2ff4491a3270f042015dd119818614281e2bfb88a4b70a31a93fc604053131379e8fca37cdc423b61270f0420060f6b3d30e44db0c9619cff8226183d058042410fe6de742b3f23fba7dab15c270f0420070f6abe825444394a0063aa7b30fc0461046db1928f2f129a724722164f67e1270f0420dd75b606bc355055df7eb0f9b26a6d2af16c348ccee8a41ee601f72fa917d14f270f0420d89d506e4d6230388c108cb29eaa2da25f632a843e94970e8de1ea8bab78eafb270f0104d99ae714270f0104d8ee4b2e270f0104d8e6e87d270f0104d18d24ce270f0104d14a5f42270f0104d14a42b0270f0104d057665b270f0104d0576659270f0104d0576656270f0104d0576215270f0104cff4f728270f0104cfb4e906270f0104ca051021270f0104c75508bf270f0104c75508be270f0104c7550808270f0104c3625fd2270f0104c31afee4270f0104c2ee19c7270f0104c2875464270f0104c2875021270f0104c0af7fc6270f0104c0a90657270f0104bc28b243270f0104b9f373db270f0104b9e4539c270f0104b9e45384270f0104b9d8b305270f0104b9c6ea0c270f0104b9c113d6270f0104b9b928ab270f0104b9b92868270f0104b9a5ab75270f0104b9a4a3da270f0104b9a4a355270f0104b98ed490270f0104b970f935270f0104b970f931270f0104b91c6591270f0104b86bb6c6270f0104b2fdfd05270f0104b2d057e2270f0104b2d057d5270f0104b29d5bb8270f0104b29d5bb2270f0104b29d5bb1270f0104b280e4c3270f0104b2689b05270f0104b23f7981270f0104b23eab10270f0104b15d8d56270f0104b15d8d3c270f0104b0664191270f0104acee0719270f0104acecf451270f0104ac6891a6270f0104ac5675d2270f0104ac565b9e270f0104ac5649a0270f0104a93ace3f270f0104a8775004270f0104a758a910270f0104a3ac4229270f0104a2d4236b270f0104a2d4236a270f0104a2d42368270f0104a2d42364270f0104a161a573270f01049f4b79a3270f01049db45b4e270f01049dad7a1a270f01049dad7a19270f01049dad7a15270f01049dad7a14270f01049c431d2d270f010498435fb8270f010497f455fd270f010497f455db270f010497f455b2270f010497f4557b270f010495686e77270f0104951c944d270f0104932d29d2270f0104901fbc2a270f01049018eeb2270f01048f14210a270f01048bb48f93270f01048ba2d7a9270f01048ba2d34c270f01048b54d85b270f01048b1c6102270f010486ffb6b9270f0104851261e2270f010484f3c5f0270f010484f3c5b3270f010484f3c563270f010484f3c517270f010482ff9ba3270f010482a2e9ba270f010473bef839270f01047284acd7270f01046deb43f6270f01046dadc643270f01046bbd034a270f01046bb3845d270f01046baecce8270f01046baafea0270f01046a370916270f010468cf4b90270f010468cf4b03270f010468cf49af270f01045bc795b1270f01045bc66c29270f01045bc66c28270f01045bc66c27270f01045bc66c23270f01045b63a9ba270f010459b34960270f0104597dffd3270f0104597dd1e2270f0104597d32ce270f0104597d320e270f0104597503f2270f0104592e2ada270f0104592e2ad8270f010459280fde270f0104592383db270f0104592383da270f01045923839e270f010459238395270f010457e51694270f010457e5161f270f010457e41840270f0104566ba862270f0104566ba828270f010455d1f1f5270f010455d1f15d270f010455d1f157270f010455d1f156270f010455bef303270f010454f7b4c9270f010454f2b3cc270f010454620cc4270f010454093211270f0104539564ba270f0104539564b8270f0104539564b7270f010452df517f270f010452cae653270f010452b492c0270f010451e3fa33270f010450f99308270f010450f084e7270f01044e531300270f01044e11d4f9270f01044e114728270f01044dedecd6270f01044dedec42270f01044dedeb00270f01044ddf6304270f01044ddd94cc270f01044d693d77270f01044d693d4f270f01044d2a5b48270f01044d2a4a44270f01044d2a102e270f01044a325a71270f0104483e3a6c270f0104483c26a0270f0104453d6bd7270f010442f4f346270f010442a37171270f010442a3715b270f010442a37107270f01043eee7f94270f01043e3cf4ae270f0104362526e2270f01043424665b270f0104342109ac270f010433a12286270f0104339ebc58270f0104339ea9ed270f0104339ea71f270f0104334f6db6270f01043344031d270f01042efafe0a270f01042ee17833270f01042ee03297270f01042e94e779270f01042e3efaf7270f01042e3e8490270f01042e2428f2270f01042e2423f4270f01042e1ebdfb270f01042e04a27f270f01042d99ba64270f01042d9746cb270f01042d9746ca270f01042d959ac2270f01042d87b44f270f01042d87b444270f01042d809c1e270f01042d4f126a270f01042d3dba79270f01042d3a384f270f01042cf063d6270f01042ba7f46d270f01042b9b87d0270f01042b86b471270f01042b85ab65270f010426667d6c270f010426360c6f270f01042561e315270f0104253cf4fd270f010422d2ee43270f01041f946394270f01041f4d6c88270f01041f3aaab5270f01041f3aaab4270f01041f3aaa8b270f01041f3aaa82270f01041f3826b9270f01041f382601270f01041f382600270f01041f0a6124270f010405afa2d7270f010405afa2bc270f010405afa2b9270f010405afa2b8270f010405357c78270f010405236719270f010405236713270f01040502493a270f0104050243be270f010402e97823270f0104023bdb36270f0104021ceae6270f010402195070270f010401754bdc270f", + "bech32PlatformHRP": "dash", + "sporkAddresses": [ + "Xgtyuk76vhuFW2iT7UAiHgNdWXCf3J34wh" + ], + "defaultConsistencyChecks": false, + "requireRoutableExternalIP": true, + "isTestChain": false, + "isMockableChain": false, + "mineBlocksOnDemand": false, + "allowMultipleAddressesFromGroup": false, + "llmqConnectionRetryTimeout": 60, + "poolMinParticipants": 3, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 3600, + "creditPoolPeriodBlocks": 576, + "chainTxData": { + "nTime": 1793218693, + "nTxCount": 71411418, + "dTxRateBits": "3fc0ba6bfb922cfe" + }, + "devnetGenesisBlock": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "assumeutxo": [], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + }, + { + "name": "evo_shares", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 951, + "bip66": 245817, + "bip65": 619382, + "bip147": 939456, + "csv": 622944, + "dip0001": 782208, + "dip0003": 1028160, + "dip0008": 1088640, + "dip0020": 1516032, + "dip0024": 1737792, + "realloc": 1374912, + "v19": 1899072, + "v20": 1987776, + "mn_rr": 2128896, + "withdrawals": 2201472 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + }, + // chainparams_dump params test + "test": { + "params": { + "networkID": "test", + "messageStart": "cee2caff", + "defaultPort": 19999, + "pruneAfterHeight": 3000, + "genesisHash": "00000bafbc94add76cb75e2ec92894837288a481e5c005f6563d91623bf8bc2c", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0dee1e352f0ff0f1ec3c927e60101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "a33e7ae4978d4c851d725e5ed811a662f52ab65d011ef656ce5b968061842883", + "extCoinType": 1, + "base58Prefixes": { + "PUBKEY_ADDRESS": "8c", + "SCRIPT_ADDRESS": "13", + "SECRET_KEY": "ef", + "EXT_PUBLIC_KEY": "043587cf", + "EXT_SECRET_KEY": "04358394" + }, + "checkpoints": { + "255": "0000080b600e06f4c07880673f027210f9314575f5f875fafe51971e268b886a", + "261": "00000c26026d0815a7e2ce4fa270775f61403c040647ff2c3091f99e894a4618", + "1999": "00000052e538d27fa53693efe6fb6892a0c1d26c0235f599171c48a3cce553b1", + "2999": "0000024bc3f4f4cb30d29827c13d921ad77d2c6072e586c7f60d83c2722cdcc5", + "96090": "00000000033df4b94d17ab43e999caaf6c4735095cc77703685da81254d09bba", + "200000": "000000001015eb5ef86a8fe2b3074d947bc972c5befe32b28dd5ce915dc0d029", + "395750": "000008b78b6aef3fd05ab78db8b76c02163e885305545144420cb08704dce538", + "470000": "0000009303aeadf8cf3812f5c869691dbd4cb118ad20e9bf553be434bafe6a52", + "794950": "000001860e4c7248a9c5cc3bc7106041750560dc5cd9b3a2641b49494bcff5f2", + "808000": "00000104cb60a2b5e00a8a4259582756e5bf0dca201c0993c63f0e54971ea91a", + "840000": "000000cd7c3084499912ae893125c13e8c3c656abb6e511dcec6619c3d65a510", + "851000": "0000014d3b875540ff75517b7fbb1714e25d50ce92f65d7086cfce357928bb02", + "905100": "0000020c5e0f86f385cbf8e90210de9a9fd63633f01433bf47a6b3227a2851fd", + "960000": "0000000386cf5061ea16404c66deb83eb67892fa4f79b9e58e5eaab097ec2bd6", + "1069875": "00000034bfeb926662ba547c0b8dd4ba8cbb6e0c581f4e7d1bddce8f9ca3a608", + "1143608": "000000eef20eb0062abd4e799967e98bdebb165dd1c567ab4118c1c86c6e948f", + "1189000": "000001690314036dfbbecbdf382b230ead8e9c584241290a51f9f05a87a9cf7e", + "1295700": "00000107d42829a38e31c1a38c660d621e1ca376a880df1520e85e38af175d3a", + "1380000": "000000a98084beaf77ed26a905a7d59979009e23367a55b5d634962d7d65a1f9", + "1550000": "000000116cd3c11d44c88cbc0a26804bd277a5d790f684ec3a8aaa820690318c" + }, + "consensus": { + "hashGenesisBlock": "00000bafbc94add76cb75e2ec92894837288a481e5c005f6563d91623bf8bc2c", + "hashDevnetGenesisBlock": "0000000000000000000000000000000000000000000000000000000000000000", + "nSubsidyHalvingInterval": 210240, + "nMasternodePaymentsStartBlock": 4010, + "nMasternodePaymentsIncreaseBlock": 4030, + "nMasternodePaymentsIncreasePeriod": 10, + "nInstantSendConfirmationsRequired": 2, + "nInstantSendKeepLock": 6, + "nBudgetPaymentsStartBlock": 4100, + "nBudgetPaymentsCycleBlocks": 50, + "nBudgetPaymentsWindowBlocks": 10, + "nSuperblockStartBlock": 4200, + "nSuperblockStartHash": "0000000000000000000000000000000000000000000000000000000000000000", + "nSuperblockCycle": 24, + "nSuperblockMaturityWindow": 8, + "nGovernanceMinQuorum": 1, + "nGovernanceFilterElements": 500, + "nMasternodeMinimumConfirmations": 1, + "BIP34Height": 76, + "BIP34Hash": "000008ebb1db2598e897d17275285767717c6acfeac4c73def49fbea1ddcbcb6", + "BIP65Height": 2431, + "BIP66Height": 2075, + "BIP147Height": 4300, + "CSVHeight": 8064, + "DIP0001Height": 5500, + "DIP0003Height": 7000, + "DIP0003EnforcementHeight": 7300, + "DIP0003EnforcementHash": "00000055ebc0e974ba3a3fb785c5ad4365a39637d4df168169ee80d313612f8f", + "DIP0008Height": 78800, + "BRRHeight": 387500, + "DIP0020Height": 414100, + "DIP0024Height": 769700, + "DIP0024QuorumsHeight": 770730, + "V19Height": 850100, + "V20Height": 905100, + "MN_RRHeight": 1066900, + "WithdrawalsHeight": 1148500, + "MinBIP9WarningHeight": 1150516, + "nRuleChangeActivationThreshold": 1512, + "nMinerConfirmationWindow": 2016, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 13, + "nStartTime": 1790208000, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 100, + "nThresholdStart": 80, + "nThresholdMin": 60, + "nFalloffCoeff": 5, + "useEHF": true + }, + { + "name": "evo_shares", + "bit": 14, + "nStartTime": 1790208000, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 100, + "nThresholdStart": 80, + "nThresholdMin": 60, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": true, + "fPowNoRetargeting": false, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 4002, + "nPowDGWHeight": 4002, + "nMinimumChainWork": "00000000000000000000000000000000000000000000000003ed573a939487fc", + "defaultAssumeValid": "000000116cd3c11d44c88cbc0a26804bd277a5d790f684ec3a8aaa820690318c", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ], + "llmqTypeChainLocks": 1, + "llmqTypeDIP0024InstantSend": 5, + "llmqTypePlatform": 6, + "llmqTypeMnhf": 1 + } + }, + "ext": { + "dataDir": "testnet3", + "rpcPort": 19998, + "onionServiceTargetPort": 19996, + "defaultPlatformP2PPort": 22000, + "defaultPlatformHTTPPort": 22001, + "minBlocksToKeep": 2304, + "assumedBlockchainSize": 10, + "assumedChainStateSize": 1, + "dnsSeeds": [ + "testnet-seed.dashdot.io." + ], + "fixedSeeds": "0104cef5a73f4e1f0104a223f3554e1d010457e5167e4e1f010455d1f3294e1f010455d1f30a4e1f010455d1f3094e1f010455d1f3084e1f010455d1f3074e1f010455d1f3064e1f010455d1f3054e1f010455d1f3044e1f010455d1f3034e1f010455d1f3024e1f010444437a514e1f010444437a484e1f010444437a464e1f010444437a424e1f010444437a3e4e1f010444437a334e1f010444437a2a4e1f010444437a214e1f010444437a1e4e1f010444437a174e1f01043e3cf4ae4e1f010422b266904e1f", + "bech32PlatformHRP": "tdash", + "sporkAddresses": [ + "yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55" + ], + "defaultConsistencyChecks": false, + "requireRoutableExternalIP": true, + "isTestChain": true, + "isMockableChain": false, + "mineBlocksOnDemand": false, + "allowMultipleAddressesFromGroup": false, + "llmqConnectionRetryTimeout": 60, + "poolMinParticipants": 2, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 300, + "creditPoolPeriodBlocks": 576, + "chainTxData": { + "nTime": 1788899589, + "nTxCount": 8494561, + "dTxRateBits": "3f8c8fe7d80073d8" + }, + "devnetGenesisBlock": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "assumeutxo": [], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + }, + { + "name": "evo_shares", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 76, + "bip66": 2075, + "bip65": 2431, + "bip147": 4300, + "csv": 8064, + "dip0001": 5500, + "dip0003": 7000, + "dip0008": 78800, + "dip0020": 414100, + "dip0024": 769700, + "realloc": 387500, + "v19": 850100, + "v20": 905100, + "mn_rr": 1066900, + "withdrawals": 1148500 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + }, + // chainparams_dump params devnet + "devnet": { + "params": { + "networkID": "devnet", + "messageStart": "e2caffce", + "defaultPort": 19799, + "pruneAfterHeight": 3000, + "genesisHash": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0b9968054ffff7f20ffba10000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b", + "extCoinType": 1, + "base58Prefixes": { + "PUBKEY_ADDRESS": "8c", + "SCRIPT_ADDRESS": "13", + "SECRET_KEY": "ef", + "EXT_PUBLIC_KEY": "043587cf", + "EXT_SECRET_KEY": "04358394" + }, + "checkpoints": { + "0": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "1": "65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b" + }, + "consensus": { + "hashGenesisBlock": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "hashDevnetGenesisBlock": "65aeaff7fc5bae2bdf1604f5498108317a79ac56624cffe78e77adc206fe1c8b", + "nSubsidyHalvingInterval": 210240, + "nMasternodePaymentsStartBlock": 4010, + "nMasternodePaymentsIncreaseBlock": 4030, + "nMasternodePaymentsIncreasePeriod": 10, + "nInstantSendConfirmationsRequired": 2, + "nInstantSendKeepLock": 6, + "nBudgetPaymentsStartBlock": 4100, + "nBudgetPaymentsCycleBlocks": 50, + "nBudgetPaymentsWindowBlocks": 10, + "nSuperblockStartBlock": 4200, + "nSuperblockStartHash": "0000000000000000000000000000000000000000000000000000000000000000", + "nSuperblockCycle": 24, + "nSuperblockMaturityWindow": 8, + "nGovernanceMinQuorum": 1, + "nGovernanceFilterElements": 500, + "nMasternodeMinimumConfirmations": 1, + "BIP34Height": 1, + "BIP34Hash": "0000000000000000000000000000000000000000000000000000000000000000", + "BIP65Height": 1, + "BIP66Height": 1, + "BIP147Height": 1, + "CSVHeight": 1, + "DIP0001Height": 2, + "DIP0003Height": 2, + "DIP0003EnforcementHeight": 2, + "DIP0003EnforcementHash": "0000000000000000000000000000000000000000000000000000000000000000", + "DIP0008Height": 2, + "BRRHeight": 2, + "DIP0020Height": 2, + "DIP0024Height": 2, + "DIP0024QuorumsHeight": 2, + "V19Height": 2, + "V20Height": 2, + "MN_RRHeight": 2, + "WithdrawalsHeight": 2, + "MinBIP9WarningHeight": 2018, + "nRuleChangeActivationThreshold": 1512, + "nMinerConfirmationWindow": 2016, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": -2, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 13, + "nStartTime": 1751328000, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 120, + "nThresholdStart": 96, + "nThresholdMin": 72, + "nFalloffCoeff": 5, + "useEHF": true + }, + { + "name": "evo_shares", + "bit": 14, + "nStartTime": 1751328000, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 120, + "nThresholdStart": 96, + "nThresholdMin": 72, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": true, + "fPowNoRetargeting": false, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 4001, + "nPowDGWHeight": 4001, + "nMinimumChainWork": "0000000000000000000000000000000000000000000000000000000000000000", + "defaultAssumeValid": "0000000000000000000000000000000000000000000000000000000000000000", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + } + ], + "llmqTypeChainLocks": 101, + "llmqTypeDIP0024InstantSend": 105, + "llmqTypePlatform": 107, + "llmqTypeMnhf": 101 + } + }, + "ext": { + "dataDir": "devnet", + "rpcPort": 19798, + "onionServiceTargetPort": 19796, + "defaultPlatformP2PPort": 22100, + "defaultPlatformHTTPPort": 22101, + "minBlocksToKeep": 2304, + "assumedBlockchainSize": 0, + "assumedChainStateSize": 0, + "dnsSeeds": [], + "fixedSeeds": "", + "bech32PlatformHRP": "tdash", + "sporkAddresses": [ + "yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55" + ], + "defaultConsistencyChecks": false, + "requireRoutableExternalIP": true, + "isTestChain": true, + "isMockableChain": false, + "mineBlocksOnDemand": false, + "allowMultipleAddressesFromGroup": true, + "llmqConnectionRetryTimeout": 60, + "poolMinParticipants": 2, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 300, + "creditPoolPeriodBlocks": 576, + "chainTxData": { + "nTime": 1417713338, + "nTxCount": 2, + "dTxRateBits": "3f847ae147ae147b" + }, + "devnetGenesisBlock": "040000002e3df23eec5cd6a86edd509539028e2c3a3dc05315eb28f2baa43218ca080000747a19c7b21b7bc837f190a9ff5af314df0517803e1c4f09b29aba37371754d8ba968054ffff7f20000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0851066465766e6574ffffffff0100f2052a01000000016a00000000", + "assumeutxo": [], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + }, + { + "name": "evo_shares", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 1, + "bip66": 1, + "bip65": 1, + "bip147": 1, + "csv": 1, + "dip0001": 2, + "dip0003": 2, + "dip0008": 2, + "dip0020": 2, + "dip0024": 2, + "realloc": 2, + "v19": 2, + "v20": 2, + "mn_rr": 2, + "withdrawals": 2 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + }, + // chainparams_dump params regtest + "regtest": { + "params": { + "networkID": "regtest", + "messageStart": "fcc1b7dc", + "defaultPort": 19899, + "pruneAfterHeight": 1000, + "genesisHash": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "genesisBlock": "010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0b9968054ffff7f20ffba10000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + "devnetGenesisHash": "a33e7ae4978d4c851d725e5ed811a662f52ab65d011ef656ce5b968061842883", + "extCoinType": 1, + "base58Prefixes": { + "PUBKEY_ADDRESS": "8c", + "SCRIPT_ADDRESS": "13", + "SECRET_KEY": "ef", + "EXT_PUBLIC_KEY": "043587cf", + "EXT_SECRET_KEY": "04358394" + }, + "checkpoints": { + "0": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e" + }, + "consensus": { + "hashGenesisBlock": "000008ca1832a4baf228eb1553c03d3a2c8e02399550dd6ea8d65cec3ef23d2e", + "hashDevnetGenesisBlock": "0000000000000000000000000000000000000000000000000000000000000000", + "nSubsidyHalvingInterval": 150, + "nMasternodePaymentsStartBlock": 240, + "nMasternodePaymentsIncreaseBlock": 350, + "nMasternodePaymentsIncreasePeriod": 10, + "nInstantSendConfirmationsRequired": 2, + "nInstantSendKeepLock": 6, + "nBudgetPaymentsStartBlock": 1000, + "nBudgetPaymentsCycleBlocks": 50, + "nBudgetPaymentsWindowBlocks": 10, + "nSuperblockStartBlock": 1500, + "nSuperblockStartHash": "0000000000000000000000000000000000000000000000000000000000000000", + "nSuperblockCycle": 20, + "nSuperblockMaturityWindow": 10, + "nGovernanceMinQuorum": 1, + "nGovernanceFilterElements": 100, + "nMasternodeMinimumConfirmations": 1, + "BIP34Height": 1, + "BIP34Hash": "0000000000000000000000000000000000000000000000000000000000000000", + "BIP65Height": 1, + "BIP66Height": 1, + "BIP147Height": 0, + "CSVHeight": 1, + "DIP0001Height": 1, + "DIP0003Height": 432, + "DIP0003EnforcementHeight": 500, + "DIP0003EnforcementHash": "0000000000000000000000000000000000000000000000000000000000000000", + "DIP0008Height": 1, + "BRRHeight": 1, + "DIP0020Height": 1, + "DIP0024Height": 1, + "DIP0024QuorumsHeight": 1, + "V19Height": 1, + "V20Height": 432, + "MN_RRHeight": 432, + "WithdrawalsHeight": 600, + "MinBIP9WarningHeight": 0, + "nRuleChangeActivationThreshold": 108, + "nMinerConfirmationWindow": 144, + "vDeployments": [ + { + "name": "testdummy", + "bit": 28, + "nStartTime": 0, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 0, + "nThresholdStart": 0, + "nThresholdMin": 0, + "nFalloffCoeff": 0, + "useEHF": false + }, + { + "name": "v24", + "bit": 13, + "nStartTime": 0, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 250, + "nThresholdStart": 200, + "nThresholdMin": 150, + "nFalloffCoeff": 5, + "useEHF": true + }, + { + "name": "evo_shares", + "bit": 14, + "nStartTime": 0, + "nTimeout": 9223372036854775807, + "min_activation_height": 0, + "nWindowSize": 250, + "nThresholdStart": 200, + "nThresholdMin": 150, + "nFalloffCoeff": 5, + "useEHF": true + } + ], + "powLimit": "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fPowAllowMinDifficultyBlocks": true, + "fPowNoRetargeting": true, + "nPowTargetSpacing": 150, + "nPowTargetTimespan": 86400, + "nPowKGWHeight": 15200, + "nPowDGWHeight": 34140, + "nMinimumChainWork": "0000000000000000000000000000000000000000000000000000000000000000", + "defaultAssumeValid": "0000000000000000000000000000000000000000000000000000000000000000", + "nMinimumDifficultyBlocks": 0, + "nHighSubsidyBlocks": 0, + "nHighSubsidyFactor": 1, + "llmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + } + ], + "llmqTypeChainLocks": 100, + "llmqTypeDIP0024InstantSend": 103, + "llmqTypePlatform": 106, + "llmqTypeMnhf": 100 + } + }, + "ext": { + "dataDir": "regtest", + "rpcPort": 19898, + "onionServiceTargetPort": 19896, + "defaultPlatformP2PPort": 22200, + "defaultPlatformHTTPPort": 22201, + "minBlocksToKeep": 288, + "assumedBlockchainSize": 0, + "assumedChainStateSize": 0, + "dnsSeeds": [ + "dummySeed.invalid." + ], + "fixedSeeds": "", + "bech32PlatformHRP": "tdash", + "sporkAddresses": [ + "yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW" + ], + "defaultConsistencyChecks": true, + "requireRoutableExternalIP": false, + "isTestChain": true, + "isMockableChain": true, + "mineBlocksOnDemand": true, + "allowMultipleAddressesFromGroup": true, + "llmqConnectionRetryTimeout": 1, + "poolMinParticipants": 2, + "poolMaxParticipants": 20, + "fulfilledRequestExpireTime": 300, + "creditPoolPeriodBlocks": 100, + "chainTxData": { + "nTime": 0, + "nTxCount": 0, + "dTxRateBits": "0000000000000000" + }, + "devnetGenesisBlock": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "assumeutxo": [ + { + "height": 110, + "hash_serialized": "9b2a277a3e3b979f1a539d57e949495d7f8247312dbc32bce6619128c192b44b", + "evo_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "nChainTx": 110 + }, + { + "height": 200, + "hash_serialized": "8a5bdd92252fc6b24663244bbe958c947bb036dc1f94ccd15439f48d8d1cb4e3", + "evo_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "nChainTx": 200 + } + ], + "deploymentInfo": [ + { + "name": "testdummy", + "gbt_force": true + }, + { + "name": "v24", + "gbt_force": true + }, + { + "name": "evo_shares", + "gbt_force": true + } + ], + "buriedDeployments": { + "bip34": 1, + "bip66": 1, + "bip65": 1, + "bip147": 0, + "csv": 1, + "dip0001": 1, + "dip0003": 432, + "dip0008": 1, + "dip0020": 1, + "dip0024": 1, + "realloc": 1, + "v19": 1, + "v20": 432, + "mn_rr": 432, + "withdrawals": 600 + }, + "availableLlmqs": [ + { + "type": 100, + "name": "llmq_test", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 104, + "name": "llmq_test_instantsend", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 102, + "name": "llmq_test_v17", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 3, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 103, + "name": "llmq_test_dip0024", + "useRotation": true, + "size": 4, + "minSize": 4, + "threshold": 3, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 3 + }, + { + "type": 106, + "name": "llmq_test_platform", + "useRotation": false, + "size": 3, + "minSize": 2, + "threshold": 2, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 2, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 1440, + "recoveryMembers": 3 + }, + { + "type": 101, + "name": "llmq_devnet", + "useRotation": false, + "size": 12, + "minSize": 7, + "threshold": 6, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 6 + }, + { + "type": 105, + "name": "llmq_devnet_dip0024", + "useRotation": true, + "size": 8, + "minSize": 6, + "threshold": 4, + "dkgInterval": 48, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 12, + "dkgMiningWindowEnd": 20, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 2, + "keepOldConnections": 4, + "keepOldKeys": 4, + "recoveryMembers": 4 + }, + { + "type": 107, + "name": "llmq_devnet_platform", + "useRotation": false, + "size": 12, + "minSize": 9, + "threshold": 8, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 7, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 1440, + "recoveryMembers": 6 + }, + { + "type": 1, + "name": "llmq_50_60", + "useRotation": false, + "size": 50, + "minSize": 40, + "threshold": 30, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 40, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 48, + "recoveryMembers": 25 + }, + { + "type": 5, + "name": "llmq_60_75", + "useRotation": true, + "size": 60, + "minSize": 50, + "threshold": 45, + "dkgInterval": 288, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 42, + "dkgMiningWindowEnd": 50, + "dkgBadVotesThreshold": 48, + "signingActiveQuorumCount": 32, + "keepOldConnections": 64, + "keepOldKeys": 64, + "recoveryMembers": 25 + }, + { + "type": 2, + "name": "llmq_400_60", + "useRotation": false, + "size": 400, + "minSize": 300, + "threshold": 240, + "dkgInterval": 288, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 28, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 3, + "name": "llmq_400_85", + "useRotation": false, + "size": 400, + "minSize": 350, + "threshold": 340, + "dkgInterval": 576, + "dkgPhaseBlocks": 4, + "dkgMiningWindowStart": 20, + "dkgMiningWindowEnd": 48, + "dkgBadVotesThreshold": 300, + "signingActiveQuorumCount": 4, + "keepOldConnections": 5, + "keepOldKeys": 8, + "recoveryMembers": 100 + }, + { + "type": 4, + "name": "llmq_100_67", + "useRotation": false, + "size": 100, + "minSize": 80, + "threshold": 67, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 80, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 50 + }, + { + "type": 6, + "name": "llmq_25_67", + "useRotation": false, + "size": 25, + "minSize": 22, + "threshold": 17, + "dkgInterval": 24, + "dkgPhaseBlocks": 2, + "dkgMiningWindowStart": 10, + "dkgMiningWindowEnd": 18, + "dkgBadVotesThreshold": 22, + "signingActiveQuorumCount": 24, + "keepOldConnections": 25, + "keepOldKeys": 1440, + "recoveryMembers": 12 + } + ] + } + } + } +} diff --git a/pkgs/params/tests/brr_payments.rs b/pkgs/params/tests/brr_payments.rs new file mode 100644 index 000000000..d762a0501 --- /dev/null +++ b/pkgs/params/tests/brr_payments.rs @@ -0,0 +1,41 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! The block reward reallocation table reproduces the reference +//! implementation's masternode payments in every period. + +#![expect(clippy::unwrap_used, reason = "test code")] + +use dash_dev::{Corpus, Value}; +use dash_params::{ChainParamsBuilder, Network, Release, BRR_PERIODS_PERMILLE}; +use rstest::rstest; + +#[rstest] +#[case::v23_1(Release::V23_1, "v23_1")] +#[case::v24_0(Release::V24_0, "v24_0")] +fn brr_table_equals_the_references_payments(#[case] release: Release, #[case] key: &str) { + let root = Corpus::open(env!("CARGO_MANIFEST_DIR"), "brr_payments").into_value(); + let int = |v: &Value, key: &str| v[key].as_i64().unwrap(); + let (start, period) = (int(&root, "realloc_start"), int(&root, "period_blocks")); + let block_value = int(&root, "block_value"); + let p = ChainParamsBuilder::new(Network::Main, release).build(); + let c = &p.consensus; + // Reallocation starts with the first superblock cycle after its + // activation, and a period is three superblock cycles. + let (brr, cycle) = (i64::from(c.brr_height.to_u32()), i64::from(c.superblock_cycle)); + assert_eq!((start, period), (brr - brr % cycle + cycle, 3 * cycle)); + let mut periods_seen = [false; BRR_PERIODS_PERMILLE.len()]; + let rows = root["payments"][key].as_array().unwrap(); + for row in rows.iter().filter(|r| int(r, "height") >= start) { + let height = int(row, "height"); + let last = BRR_PERIODS_PERMILLE.len() - 1; + let index = usize::try_from((height - start) / period).unwrap().min(last); + periods_seen[index] = true; + let share = i64::from(BRR_PERIODS_PERMILLE[index]); + assert_eq!(block_value * share / 1000, int(row, "payment"), "height {height}"); + } + assert!(periods_seen.iter().all(|seen| *seen), "every period has a payment"); +} diff --git a/pkgs/params/tests/reference_dumps.rs b/pkgs/params/tests/reference_dumps.rs new file mode 100644 index 000000000..2517d0204 --- /dev/null +++ b/pkgs/params/tests/reference_dumps.rs @@ -0,0 +1,394 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Built chain parameters equal the reference implementation's dumps, chain +//! by chain, at each release. +//! +//! dash-primitives checks the genesis block bytes, since it builds blocks. + +#![expect(clippy::unwrap_used, clippy::expect_used, reason = "test code")] + +use dash_dev::{Corpus, Value}; +use dash_num::Hash256; +use dash_params::{BuriedDeployment, ChainParamsBuilder, ChainSetup, LlmqParams, LlmqType, Network, Release}; +use dash_pow::__deps::digest::Digest; +use dash_pow::X11; +use dash_types::Numeric; +use hex_conservative::DisplayHex; +use rstest::rstest; + +use std::collections::{BTreeMap, BTreeSet}; + +/// Corpus keys holding block bytes, which dash-primitives checks. +const BLOCK_KEYS: [&str; 2] = ["params.genesisBlock", "ext.devnetGenesisBlock"]; + +/// Corpus key of the static LLMQ table, which [`available_llmqs`] checks. +const AVAILABLE: &str = "ext.availableLlmqs"; + +/// The hex of `hash` as the reference implementation prints it, big-endian. +fn hash_hex(hash: Hash256) -> String { + hash.to_bendian().to_lower_hex_string() +} + +/// The hash of an all-zero header, the devnet genesis hash off devnets. +fn null_block_hash() -> Hash256 { + Hash256::from_lendian(X11::digest([0; 80]).into()) +} + +/// Leaf values keyed by dotted path; `#` is an array's length. +#[derive(Default)] +struct Flat(BTreeMap); + +impl Flat { + fn put(&mut self, path: &str, value: impl Into) { + self.0.insert(path.into(), value.into()); + } + + fn put_all>(&mut self, prefix: &str, fields: impl IntoIterator) { + for (name, value) in fields { + self.put(&format!("{prefix}.{name}"), value); + } + } + + fn list(&mut self, path: &str, items: &[T], mut each: impl FnMut(&mut Self, &str, &T)) { + self.put(&format!("{path}.#"), items.len()); + for (i, item) in items.iter().enumerate() { + each(self, &format!("{path}.{i}"), item); + } + } +} + +fn llmq(out: &mut Flat, path: &str, llmq_type: LlmqType, q: &LlmqParams) { + out.put(&format!("{path}.type"), llmq_type.to_base()); + out.put(&format!("{path}.name"), llmq_type.to_string()); + out.put(&format!("{path}.useRotation"), q.use_rotation); + let fields = [ + ("size", q.size), + ("minSize", q.min_size), + ("threshold", q.threshold), + ("dkgInterval", q.dkg_interval), + ("dkgPhaseBlocks", q.dkg_phase_blocks), + ("dkgMiningWindowStart", q.dkg_mining_window_start), + ("dkgMiningWindowEnd", q.dkg_mining_window_end), + ("dkgBadVotesThreshold", q.dkg_bad_votes_threshold), + ("signingActiveQuorumCount", q.signing_active_quorum_count), + ("keepOldConnections", q.keep_old_connections), + ("keepOldKeys", q.keep_old_keys), + ("recoveryMembers", q.recovery_members), + ]; + out.put_all(path, fields); +} + +/// `p` in the shape of the corpus, flattened, without the [`BLOCK_KEYS`] and +/// the static LLMQ table. +fn dump(p: &ChainSetup) -> BTreeMap { + let mut out = Flat::default(); + let c = &p.consensus; + let a = &p.addr_params; + let devnet_genesis_hash = p.devnet_genesis().map_or_else(null_block_hash, |g| g.hash); + out.put("params.networkID", p.network_id); + out.put("params.messageStart", p.message_start.to_lower_hex_string()); + out.put("params.defaultPort", p.default_port); + out.put("params.pruneAfterHeight", p.prune_after_height); + out.put("params.genesisHash", hash_hex(c.hash_genesis_block)); + out.put("params.devnetGenesisHash", hash_hex(devnet_genesis_hash)); + out.put("params.extCoinType", a.bip44_idx); + out.put("params.base58Prefixes.PUBKEY_ADDRESS", format!("{:02x}", a.pubkey_addr)); + out.put("params.base58Prefixes.SCRIPT_ADDRESS", format!("{:02x}", a.script_addr)); + out.put("params.base58Prefixes.SECRET_KEY", format!("{:02x}", a.secret_key)); + out.put( + "params.base58Prefixes.EXT_PUBLIC_KEY", + a.ext_pubkey.to_lower_hex_string(), + ); + out.put( + "params.base58Prefixes.EXT_SECRET_KEY", + a.ext_secret.to_lower_hex_string(), + ); + for (h, hash) in p.checkpoints { + out.put(&format!("params.checkpoints.{}", h.to_u32()), hash_hex(*hash)); + } + + let hashes = [ + ("hashGenesisBlock", c.hash_genesis_block), + ("hashDevnetGenesisBlock", c.hash_devnet_genesis_block), + ("nSuperblockStartHash", c.superblock_start.1), + ("BIP34Hash", c.bip34.1), + ("DIP0003EnforcementHash", c.dip0003_enforcement.1), + ("defaultAssumeValid", c.default_assume_valid), + ]; + out.put_all("params.consensus", hashes.map(|(n, h)| (n, hash_hex(h)))); + let heights = [ + ("nMasternodePaymentsStartBlock", c.masternode_payments_start_block), + ("nMasternodePaymentsIncreaseBlock", c.masternode_payments_increase_block), + ("nBudgetPaymentsStartBlock", c.budget_payments_start_block), + ("nSuperblockStartBlock", c.superblock_start.0), + ("BIP34Height", c.bip34.0), + ("BIP65Height", c.bip65_height), + ("BIP66Height", c.bip66_height), + ("BIP147Height", c.bip147_height), + ("CSVHeight", c.csv_height), + ("DIP0001Height", c.dip0001_height), + ("DIP0003Height", c.dip0003_height), + ("DIP0003EnforcementHeight", c.dip0003_enforcement.0), + ("DIP0008Height", c.dip0008_height), + ("BRRHeight", c.brr_height), + ("DIP0020Height", c.dip0020_height), + ("DIP0024Height", c.dip0024_height), + ("DIP0024QuorumsHeight", c.dip0024_quorums_height), + ("V19Height", c.v19_height), + ("V20Height", c.v20_height), + ("MN_RRHeight", c.mn_rr_height), + ("WithdrawalsHeight", c.withdrawals_height), + ("MinBIP9WarningHeight", c.min_bip9_warning_height), + ("nPowKGWHeight", c.pow_kgw_height), + ("nPowDGWHeight", c.pow_dgw_height), + ]; + out.put_all("params.consensus", heights.map(|(n, h)| (n, h.to_u32()))); + let ints = [ + ("nSubsidyHalvingInterval", c.subsidy_halving_interval), + ( + "nMasternodePaymentsIncreasePeriod", + c.masternode_payments_increase_period, + ), + ( + "nInstantSendConfirmationsRequired", + c.instant_send_confirmations_required, + ), + ("nInstantSendKeepLock", c.instant_send_keep_lock), + ("nBudgetPaymentsCycleBlocks", c.budget_payments_cycle_blocks), + ("nBudgetPaymentsWindowBlocks", c.budget_payments_window_blocks), + ("nSuperblockCycle", c.superblock_cycle), + ("nSuperblockMaturityWindow", c.superblock_maturity_window), + ("nGovernanceMinQuorum", c.governance_min_quorum), + ("nGovernanceFilterElements", c.governance_filter_elements), + ("nMasternodeMinimumConfirmations", c.masternode_minimum_confirmations), + ("nMinimumDifficultyBlocks", c.minimum_difficulty_blocks), + ("nHighSubsidyBlocks", c.high_subsidy_blocks), + ("nHighSubsidyFactor", c.high_subsidy_factor), + ]; + out.put_all("params.consensus", ints); + out.put( + "params.consensus.nRuleChangeActivationThreshold", + c.rule_change_activation_threshold, + ); + out.put("params.consensus.nMinerConfirmationWindow", c.miner_confirmation_window); + let deployments: Vec<_> = p.deployments().collect(); + out.list("params.consensus.vDeployments", &deployments, |out, path, (pos, d)| { + out.put(&format!("{path}.name"), pos.name()); + out.put(&format!("{path}.bit"), d.bit); + out.put( + &format!("{path}.min_activation_height"), + d.min_activation_height.to_u32(), + ); + let fields = [ + ("nStartTime", d.start_time), + ("nTimeout", d.timeout), + ("nWindowSize", d.window_size), + ("nThresholdStart", d.threshold_start), + ("nThresholdMin", d.threshold_min), + ("nFalloffCoeff", d.falloff_coeff), + ]; + out.put_all(path, fields); + out.put(&format!("{path}.useEHF"), d.use_ehf); + }); + out.put( + "params.consensus.powLimit", + c.pow_limit.to_bendian().to_lower_hex_string(), + ); + out.put( + "params.consensus.fPowAllowMinDifficultyBlocks", + c.pow_allow_min_difficulty_blocks, + ); + out.put("params.consensus.fPowNoRetargeting", c.pow_no_retargeting); + out.put("params.consensus.nPowTargetSpacing", c.pow_target_spacing); + out.put("params.consensus.nPowTargetTimespan", c.pow_target_timespan); + out.put( + "params.consensus.nMinimumChainWork", + c.minimum_chain_work.to_bendian().to_lower_hex_string(), + ); + let llmqs: Vec<_> = c + .llmqs + .iter() + .map(|&t| (t, t.params().expect("a table entry"))) + .collect(); + out.list("params.consensus.llmqs", &llmqs, |out, path, (t, q)| { + llmq(out, path, *t, q) + }); + out.put("params.consensus.llmqTypeChainLocks", c.llmq_type_chain_locks.to_base()); + out.put( + "params.consensus.llmqTypeDIP0024InstantSend", + c.llmq_type_dip0024_instant_send.to_base(), + ); + out.put("params.consensus.llmqTypePlatform", c.llmq_type_platform.to_base()); + out.put("params.consensus.llmqTypeMnhf", c.llmq_type_mnhf.to_base()); + + out.put("ext.dataDir", p.data_dir()); + out.put("ext.rpcPort", p.rpc_port); + out.put("ext.onionServiceTargetPort", p.onion_service_target_port); + out.put("ext.defaultPlatformP2PPort", p.default_platform_p2p_port); + out.put("ext.defaultPlatformHTTPPort", p.default_platform_http_port); + out.put("ext.minBlocksToKeep", p.min_blocks_to_keep); + out.put("ext.assumedBlockchainSize", p.assumed_blockchain_size_gb); + out.put("ext.assumedChainStateSize", p.assumed_chain_state_size_gb); + out.list("ext.dnsSeeds", p.dns_seeds, |out, path, s| out.put(path, *s)); + out.put("ext.fixedSeeds", p.fixed_seeds.to_lower_hex_string()); + out.list("ext.sporkAddresses", &[p.spork_address], |out, path, s| { + out.put(path, *s) + }); + let flags = [ + ("defaultConsistencyChecks", p.default_consistency_checks), + ("requireRoutableExternalIP", p.require_routable_external_ip), + ("isTestChain", p.is_test_chain), + ("isMockableChain", p.is_mockable_chain), + ("mineBlocksOnDemand", c.pow_no_retargeting), + ("allowMultipleAddressesFromGroup", p.allow_multiple_addresses_from_group), + ]; + out.put_all("ext", flags); + let ints = [ + ("llmqConnectionRetryTimeout", p.llmq_connection_retry_timeout), + ("poolMinParticipants", p.pool_min_participants), + ("poolMaxParticipants", p.pool_max_participants), + ("fulfilledRequestExpireTime", p.fulfilled_request_expire_time), + ("creditPoolPeriodBlocks", p.credit_pool_period_blocks), + ]; + out.put_all("ext", ints); + out.put("ext.chainTxData.nTime", p.chain_tx_data.timestamp); + out.put("ext.chainTxData.nTxCount", p.chain_tx_data.tx_count); + out.put( + "ext.chainTxData.dTxRateBits", + format!("{:016x}", p.chain_tx_data.tx_rate.to_bits()), + ); + out.list("ext.assumeutxo", p.assumeutxo, |out, path, au| { + out.put(&format!("{path}.height"), au.height.to_u32()); + out.put(&format!("{path}.hash_serialized"), hash_hex(au.hash_serialized)); + out.put(&format!("{path}.nChainTx"), au.chain_tx); + if let Some(evo) = au.evo_hash { + out.put(&format!("{path}.evo_hash"), hash_hex(evo)); + } + }); + out.list("ext.deploymentInfo", p.release().deployments(), |out, path, d| { + out.put(&format!("{path}.name"), d.name()); + out.put(&format!("{path}.gbt_force"), d.gbt_force()); + }); + for d in BuriedDeployment::ALL { + out.put( + &format!("ext.buriedDeployments.{}", d.name()), + c.deployment_height(d).to_u32(), + ); + } + match p.release() { + Release::V23_1 => out.put( + "ext.requireStandard", + p.require_standard.expect("v23 has a standard policy"), + ), + Release::V24_0 => out.put( + "ext.bech32PlatformHRP", + p.platform_hrp().expect("v24 has a Platform HRP"), + ), + } + out.0 +} + +/// Leaf values of a corpus value keyed by dotted path, as [`Flat`] keys them. +fn flatten(value: &Value, prefix: &str, out: &mut BTreeMap) { + match value { + Value::Object(map) => { + for (k, v) in map { + flatten(v, &format!("{prefix}{k}."), out); + } + } + Value::Array(items) => { + out.insert(format!("{prefix}#"), items.len().into()); + for (i, v) in items.iter().enumerate() { + flatten(v, &format!("{prefix}{i}."), out); + } + } + leaf => { + out.insert(prefix.trim_end_matches('.').into(), leaf.clone()); + } + } +} + +/// Each chain's corpus base, flattened. +fn bases(corpus: &str) -> BTreeMap> { + let root = Corpus::open(env!("CARGO_MANIFEST_DIR"), corpus).into_value(); + let bases = root["bases"].as_object().unwrap(); + bases + .iter() + .map(|(chain, v)| { + let mut out = BTreeMap::new(); + flatten(v, "", &mut out); + (chain.clone(), out) + }) + .collect() +} + +fn corpus(release: Release) -> &'static str { + match release { + Release::V23_1 => "chainparams_v23_1", + Release::V24_0 => "chainparams_v24_0", + } +} + +#[rstest] +fn chain_setup_equals_the_reference( + #[values(Release::V23_1, Release::V24_0)] release: Release, + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, +) { + let corpus = corpus(release); + let chain = network.network_id(); + let mut want = bases(corpus).remove(chain).expect("a base per chain"); + want.retain(|path, _| !BLOCK_KEYS.contains(&path.as_str()) && !path.starts_with(AVAILABLE)); + let got = dump(&ChainParamsBuilder::new(network, release).build()); + for (path, v) in &want { + assert_eq!(got.get(path), Some(v), "{corpus} {chain}: {path}"); + } + assert_eq!(got.len(), want.len(), "{corpus} {chain}: extra keys"); +} + +/// The corpora hold the four chains and nothing else. +#[rstest] +fn corpora_hold_every_chain(#[values(Release::V23_1, Release::V24_0)] release: Release) { + let chains: Vec = bases(corpus(release)).into_keys().collect(); + let mut want: Vec<_> = Network::ALL.map(|n| n.network_id().to_owned()).into(); + want.sort(); + assert_eq!(chains, want); +} + +/// The static LLMQ table, which every chain dumps, equals the reference +/// implementation's, type by type. +#[rstest] +fn available_llmqs(#[values(Release::V23_1, Release::V24_0)] release: Release) { + let corpus = corpus(release); + for (chain, base) in bases(corpus) { + let count = base[&format!("{AVAILABLE}.#")].as_u64().unwrap(); + let mut types = BTreeSet::new(); + for i in 0..count { + let path = format!("{AVAILABLE}.{i}"); + let want: BTreeMap = base + .iter() + .filter_map(|(k, v)| Some((k.strip_prefix(&format!("{path}."))?.to_owned(), v.clone()))) + .collect(); + let base_type = u8::try_from(want["type"].as_u64().unwrap()).unwrap(); + let llmq_type = LlmqType::new(base_type); + let mut got = Flat::default(); + llmq(&mut got, "q", llmq_type, &llmq_type.params().expect("a table entry")); + let got: BTreeMap = got + .0 + .into_iter() + .map(|(k, v)| (k.strip_prefix("q.").unwrap().to_owned(), v)) + .collect(); + assert_eq!(got, want, "{corpus} {chain}: {llmq_type}"); + types.insert(base_type); + } + let table: BTreeSet = LlmqType::variants() + .iter() + .filter(|t| t.params().is_some()) + .map(|t| t.to_base()) + .collect(); + assert_eq!(types, table, "{corpus} {chain}"); + } +} diff --git a/pkgs/primitives/tests/chainparams_blocks.rs b/pkgs/primitives/tests/chainparams_blocks.rs new file mode 100644 index 000000000..0333da5be --- /dev/null +++ b/pkgs/primitives/tests/chainparams_blocks.rs @@ -0,0 +1,50 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! The genesis and devnet genesis blocks built from the chain setup equal +//! the reference implementation's bytes in dash-params' chain-params +//! corpora. dash-params checks every other value of those corpora itself. + +#![expect(clippy::unwrap_used, reason = "test code")] + +use dash_dev::Corpus; +use dash_params::{ChainParamsBuilder, ChainSetup, Network, Release}; +use dash_primitives::{Block, BlockHeader}; +use dash_types::codec::BaseCodec; +use hex_conservative::DisplayHex; +use rstest::rstest; + +fn serialize(block: &Block) -> String { + let mut buf = Vec::new(); + block.encode(&mut buf); + buf.to_lower_hex_string() +} + +/// The devnet genesis block on a devnet, and a null block elsewhere, as the +/// reference implementation keeps it. +fn devnet_genesis(setup: &ChainSetup) -> Block { + setup + .devnet_genesis() + .map_or_else(|| Block::new(BlockHeader::default(), Vec::new()), Block::from) +} + +#[rstest] +fn chain_params_blocks_equal_the_reference( + #[values((Release::V23_1, "chainparams_v23_1"), (Release::V24_0, "chainparams_v24_0"))] corpus: (Release, &str), + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, +) { + let (release, corpus) = corpus; + let params_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/../params"); + let root = Corpus::open(params_dir, corpus).into_value(); + let chain = network.network_id(); + let base = &root["bases"][chain]; + let setup = ChainParamsBuilder::new(network, release).build(); + let genesis = Block::from(&setup.genesis); + let want = base["params"]["genesisBlock"].as_str().unwrap(); + assert_eq!(serialize(&genesis), want, "{corpus} {chain}"); + let want = base["ext"]["devnetGenesisBlock"].as_str().unwrap(); + assert_eq!(serialize(&devnet_genesis(&setup)), want, "{corpus} {chain}"); +} diff --git a/pkgs/primitives/tests/genesis_valid.rs b/pkgs/primitives/tests/genesis_valid.rs index bfb6b3b3f..0587fbf91 100644 --- a/pkgs/primitives/tests/genesis_valid.rs +++ b/pkgs/primitives/tests/genesis_valid.rs @@ -8,7 +8,7 @@ #![expect(clippy::unwrap_used, reason = "test code")] -use dash_params::{ChainParams, DevnetGenesisParams, Network}; +use dash_params::{ChainParams, ChainParamsBuilder, DevnetGenesisParams, Network, Release}; use dash_primitives::{Block, BlockHash, MerkleRoot}; use dash_types::{Hashable, Numeric}; use hex_conservative::hex; @@ -25,6 +25,11 @@ use rstest::rstest; Network::Testnet3.chain(), MerkleRoot::from_bendian(hex!("e0028eb9648db56b1ac77cf090b99048a8007e2bb64b68f092c03c7f56a662c7")), )] +#[case::devnet( + Block::from(&Network::Devnet.chain().genesis), + Network::Devnet.chain(), + MerkleRoot::from_bendian(hex!("e0028eb9648db56b1ac77cf090b99048a8007e2bb64b68f092c03c7f56a662c7")), +)] #[case::regtest( Block::from(&Network::Regtest.chain().genesis), Network::Regtest.chain(), @@ -71,3 +76,27 @@ fn devnet_genesis_blocks_match_their_params(#[case] name: String, #[case] push: assert_eq!(header.prev_hash(), BlockHash::from(chain.consensus.hash_genesis_block)); assert_eq!(header.merkle_root(), block.merkle().0); } + +/// At each release, the setup's genesis block hashes to its genesis hash. +/// On a devnet, its devnet genesis block hashes to the devnet genesis hash, +/// which the setup's height-1 checkpoint holds. +#[rstest] +fn setup_genesis_blocks_match_their_hashes( + #[values(Network::Main, Network::Testnet3, Network::Devnet, Network::Regtest)] network: Network, + #[values(Release::V23_1, Release::V24_0)] release: Release, +) { + let setup = ChainParamsBuilder::new(network, release).build(); + let genesis = Block::from(&setup.genesis); + let genesis_hash = genesis.header().hash(); + assert_eq!(genesis_hash, BlockHash::from(setup.consensus.hash_genesis_block)); + let Some(params) = setup.devnet_genesis() else { + assert_ne!(network, Network::Devnet); + return; + }; + let block = Block::from(params); + let hash = BlockHash::from(setup.consensus.hash_devnet_genesis_block); + assert_eq!(block.header().hash(), hash); + assert_eq!(block.header().prev_hash(), genesis_hash); + let (height, checkpoint) = setup.checkpoints[1]; + assert_eq!((height.to_u32(), BlockHash::from(checkpoint)), (1, hash)); +} From b93d4bb421aa97f8bcb1f4ac20ee8cad88bdf474 Mon Sep 17 00:00:00 2001 From: pasta Date: Sun, 1 Nov 2026 00:21:22 +0000 Subject: [PATCH 5/5] sdk%doc: record the chain setup in the changelog and README dash-params now covers the devnet and both known releases. --- README.md | 2 +- pkgs/params/CHANGELOG.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6890cd00f..9e7debc81 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ | --- | --- | --- | --- | --- | | [dash-num](./pkgs/num) | Hash blobs, 256-bit arithmetic, compact target encoding | [![dash-num](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_num.yml?style=flat&logo=github&logoColor=white&label=num)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_num.yml) | [![dash-num](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-num&style=flat&logo=codecov&logoColor=white&label=num)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fnum) | [![dash-num](https://img.shields.io/crates/v/dash-num?style=flat&logo=hackthebox&logoColor=white&label=num&color=teal)](https://crates.io/crates/dash-num) | | [dash-p2p-core](./pkgs/p2p_core) | P2P message types and wire format | [![dash-p2p-core](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_p2p_core.yml?style=flat&logo=github&logoColor=white&label=p2p-core)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_p2p_core.yml) | [![dash-p2p-core](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-p2p-core&style=flat&logo=codecov&logoColor=white&label=p2p-core)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fp2p_core) | _Unreleased._ | -| [dash-params](./pkgs/params) | Chain parameters for `mainnet`, `testnet3`, and `regtest` | [![dash-params](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_params.yml?style=flat&logo=github&logoColor=white&label=params)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_params.yml) | [![dash-params](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-params&style=flat&logo=codecov&logoColor=white&label=params)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fparams) | _Unreleased._ | +| [dash-params](./pkgs/params) | Chain parameters for `mainnet`, `testnet3`, devnets and `regtest`, by release | [![dash-params](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_params.yml?style=flat&logo=github&logoColor=white&label=params)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_params.yml) | [![dash-params](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-params&style=flat&logo=codecov&logoColor=white&label=params)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fparams) | _Unreleased._ | | [dash-pkc](./pkgs/pkc) | BLS (legacy + IETF) and secp256k1 operations | [![dash-pkc](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_pkc.yml?style=flat&logo=github&logoColor=white&label=pkc)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_pkc.yml) | [![dash-pkc](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-pkc&style=flat&logo=codecov&logoColor=white&label=pkc)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fpkc) | [![dash-pkc](https://img.shields.io/crates/v/dash-pkc?style=flat&logo=hackthebox&logoColor=white&label=pkc&color=teal)](https://crates.io/crates/dash-pkc) | | [dash-pow](./pkgs/pow) | Proof of work scheme | [![dash-pow](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_pow.yml?style=flat&logo=github&logoColor=white&label=pow)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_pow.yml) | [![dash-pow](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-pow&style=flat&logo=codecov&logoColor=white&label=pow)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fpow) | [![dash-pow](https://img.shields.io/crates/v/dash-pow?style=flat&logo=hackthebox&logoColor=white&label=pow&color=teal)](https://crates.io/crates/dash-pow) | | [dash-primitives](./pkgs/primitives) | Blocks, transactions, payloads, governance objects | [![dash-primitives](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_primitives.yml?style=flat&logo=github&logoColor=white&label=primitives)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_primitives.yml) | [![dash-primitives](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-primitives&style=flat&logo=codecov&logoColor=white&label=primitives)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fprimitives) | _Unreleased._ | diff --git a/pkgs/params/CHANGELOG.md b/pkgs/params/CHANGELOG.md index 89ee5bcf0..980a97c42 100644 --- a/pkgs/params/CHANGELOG.md +++ b/pkgs/params/CHANGELOG.md @@ -8,3 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] - Initial release. +- `ChainSetup`, built by `ChainParamsBuilder` from a `Network` and a `Release`, holds the chain parameters of the + reference implementation at v23.1.8 or v24.0.0-rc.5. It adds the devnet (`Network::Devnet` and its devnet genesis + block), v23.1's parameters and each release's version-bits deployments to the network tables, which stay as they are. + `contrib/params` regenerates the corpora that check it from the release tags. +- `dash-params` now depends on `dash-pow`, which "requires x86-64-v3 and AES", "NEON and AES" on AArch64 and "128-bit + SIMD" on WebAssembly. Builds without those target features need the new `portable` feature. +- `Network::Devnet` sits before `Network::Regtest`, so the discriminant of `Regtest` is now 3.