Skip to content

Commit 8b0038d

Browse files
authored
Merge pull request #1136 from mintlayer/alfie/genesis-ongoing
Return initial difficulty for when the previous block is Genesis
2 parents 4ee887b + b7073e1 commit 8b0038d

File tree

9 files changed

+91
-47
lines changed

9 files changed

+91
-47
lines changed

blockprod/src/detail/tests.rs

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -883,21 +883,15 @@ mod produce_block {
883883
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
884884
async fn cancel_received(#[case] seed: Seed) {
885885
let override_chain_config = {
886-
let net_upgrades = NetUpgrades::initialize(vec![
887-
(
888-
BlockHeight::new(0),
889-
UpgradeVersion::ConsensusUpgrade(ConsensusUpgrade::IgnoreConsensus),
890-
),
891-
(
892-
BlockHeight::new(1),
893-
UpgradeVersion::ConsensusUpgrade(ConsensusUpgrade::PoW {
894-
// Make difficulty impossible so the cancel from
895-
// the mock job manager is always seen before
896-
// solving the block
897-
initial_difficulty: Uint256::ZERO.into(),
898-
}),
899-
),
900-
])
886+
let net_upgrades = NetUpgrades::initialize(vec![(
887+
BlockHeight::new(0),
888+
UpgradeVersion::ConsensusUpgrade(ConsensusUpgrade::PoW {
889+
// Make difficulty impossible so the cancel from
890+
// the mock job manager is always seen before
891+
// solving the block
892+
initial_difficulty: Uint256::ZERO.into(),
893+
}),
894+
)])
901895
.expect("Net upgrade is valid");
902896

903897
Builder::new(ChainType::Regtest).net_upgrades(net_upgrades).build()
@@ -1014,18 +1008,12 @@ mod produce_block {
10141008
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
10151009
async fn solved_pow_consensus() {
10161010
let override_chain_config = {
1017-
let net_upgrades = NetUpgrades::initialize(vec![
1018-
(
1019-
BlockHeight::new(0),
1020-
UpgradeVersion::ConsensusUpgrade(ConsensusUpgrade::IgnoreConsensus),
1021-
),
1022-
(
1023-
BlockHeight::new(1),
1024-
UpgradeVersion::ConsensusUpgrade(ConsensusUpgrade::PoW {
1025-
initial_difficulty: Uint256::MAX.into(),
1026-
}),
1027-
),
1028-
])
1011+
let net_upgrades = NetUpgrades::initialize(vec![(
1012+
BlockHeight::new(0),
1013+
UpgradeVersion::ConsensusUpgrade(ConsensusUpgrade::PoW {
1014+
initial_difficulty: Uint256::MAX.into(),
1015+
}),
1016+
)])
10291017
.expect("Net upgrade is valid");
10301018

10311019
Builder::new(ChainType::Regtest).net_upgrades(net_upgrades).build()

chainstate/src/detail/ban_score.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ impl BanScore for ConsensusPoWError {
323323
ConsensusPoWError::DecodingBitsFailed(_) => 100,
324324
ConsensusPoWError::PreviousBitsDecodingFailed(_) => 0,
325325
ConsensusPoWError::InvalidTargetBits(_, _) => 100,
326-
ConsensusPoWError::GenesisCannotHaveOngoingDifficulty => 100,
327326
ConsensusPoWError::InvalidBlockRewardMaturityDistance(_) => 0,
328327
}
329328
}

common/src/chain/config/builder.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::{
2323
EmissionScheduleTabular,
2424
},
2525
pos::get_initial_randomness,
26+
pow::PoWChainConfigBuilder,
2627
ConsensusUpgrade, Destination, GenBlock, Genesis, Mlt, NetUpgrades, PoWChainConfig,
2728
UpgradeVersion,
2829
},
@@ -249,6 +250,27 @@ impl Builder {
249250
.collect::<BTreeMap<BlockHeight, Id<GenBlock>>>()
250251
.into();
251252

253+
let pow_chain_config = {
254+
let (_, genesis_upgrade_version) = net_upgrades
255+
.version_at_height(BlockHeight::new(0))
256+
.expect("Genesis must have an upgrade version");
257+
258+
let limit = match genesis_upgrade_version {
259+
UpgradeVersion::SomeUpgrade => None,
260+
UpgradeVersion::ConsensusUpgrade(consensus_upgrade) => match consensus_upgrade {
261+
ConsensusUpgrade::IgnoreConsensus | ConsensusUpgrade::PoS { .. } => None,
262+
ConsensusUpgrade::PoW { initial_difficulty } => {
263+
let limit = (*initial_difficulty)
264+
.try_into()
265+
.expect("Genesis initial difficulty to be valid");
266+
Some(limit)
267+
}
268+
},
269+
};
270+
271+
PoWChainConfigBuilder::new(chain_type).limit(limit).build()
272+
};
273+
252274
ChainConfig {
253275
chain_type,
254276
bip44_coin_type,
@@ -263,6 +285,7 @@ impl Builder {
263285
max_future_block_time_offset,
264286
max_no_signature_data_size,
265287
max_depth_for_reorg,
288+
pow_chain_config,
266289
epoch_length,
267290
sealed_epoch_distance_from_tip,
268291
initial_randomness,

common/src/chain/config/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ pub struct ChainConfig {
162162
max_block_size_with_smart_contracts: usize,
163163
max_no_signature_data_size: usize,
164164
max_depth_for_reorg: BlockDistance,
165+
pow_chain_config: PoWChainConfig,
165166
epoch_length: NonZeroU64,
166167
sealed_epoch_distance_from_tip: usize,
167168
initial_randomness: H256,
@@ -456,8 +457,8 @@ impl ChainConfig {
456457

457458
// TODO: this should be part of net-upgrades. There should be no canonical definition of PoW for any chain config
458459
#[must_use]
459-
pub const fn get_proof_of_work_config(&self) -> PoWChainConfig {
460-
PoWChainConfig::new(self.chain_type)
460+
pub fn get_proof_of_work_config(&self) -> &PoWChainConfig {
461+
&self.pow_chain_config
461462
}
462463

463464
/// The minimum number of blocks required to be able to spend a utxo coming from a decommissioned pool

common/src/chain/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,5 @@ pub use pos::{
3838
create_regtest_pos_config, create_testnet_pos_config, create_unittest_pos_config,
3939
get_initial_randomness, initial_difficulty, DelegationId, PoSChainConfig, PoolId,
4040
};
41-
pub use pow::PoWChainConfig;
41+
pub use pow::{PoWChainConfig, PoWChainConfigBuilder};
4242
pub use upgrades::*;

common/src/chain/pow.rs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::time::Duration;
2121
/// Chain Parameters for Proof of Work.
2222
///
2323
/// See in Bitcoin's [chainparams.cpp](https://github.com/bitcoin/bitcoin/blob/eca694a4e78d54ce4e29b388b3e81b06e55c2293/src/chainparams.cpp)
24-
#[derive(Debug)]
24+
#[derive(Debug, Clone)]
2525
pub struct PoWChainConfig {
2626
no_retargeting: bool,
2727
/// Checks whether minimum difficulty can be used for the block
@@ -33,14 +33,8 @@ pub struct PoWChainConfig {
3333
}
3434

3535
impl PoWChainConfig {
36-
pub(crate) const fn new(chain_type: ChainType) -> Self {
37-
PoWChainConfig {
38-
no_retargeting: no_retargeting(chain_type),
39-
allow_min_difficulty_blocks: allow_min_difficulty_blocks(chain_type),
40-
limit: limit(chain_type),
41-
// If block time is 2 minutes (which is my goal eventually), then 500 is equivalent to 100 in bitcoin's 10 minutes.
42-
reward_maturity_distance: BlockDistance::new(500),
43-
}
36+
pub(crate) fn new(chain_type: ChainType) -> Self {
37+
PoWChainConfigBuilder::new(chain_type).build()
4438
}
4539

4640
pub const fn no_retargeting(&self) -> bool {
@@ -77,6 +71,49 @@ impl PoWChainConfig {
7771
}
7872
}
7973

74+
#[derive(Copy, Clone)]
75+
pub struct PoWChainConfigBuilder {
76+
chain_type: ChainType,
77+
no_retargeting: Option<bool>,
78+
allow_min_difficulty_blocks: Option<bool>,
79+
limit: Option<Uint256>,
80+
reward_maturity_distance: Option<BlockDistance>,
81+
}
82+
83+
impl PoWChainConfigBuilder {
84+
pub fn new(chain_type: ChainType) -> Self {
85+
Self {
86+
chain_type,
87+
no_retargeting: None,
88+
allow_min_difficulty_blocks: None,
89+
limit: None,
90+
reward_maturity_distance: None,
91+
}
92+
}
93+
94+
pub fn limit(mut self, value: Option<Uint256>) -> Self {
95+
self.limit = value;
96+
self
97+
}
98+
99+
pub fn build(self) -> PoWChainConfig {
100+
PoWChainConfig {
101+
no_retargeting: self.no_retargeting.unwrap_or_else(|| no_retargeting(self.chain_type)),
102+
allow_min_difficulty_blocks: self
103+
.allow_min_difficulty_blocks
104+
.unwrap_or_else(|| allow_min_difficulty_blocks(self.chain_type)),
105+
limit: self.limit.unwrap_or_else(|| limit(self.chain_type)),
106+
107+
// If block time is 2 minutes (which is my goal
108+
// eventually), then 500 is equivalent to 100 in bitcoin's
109+
// 10 minutes.
110+
reward_maturity_distance: self
111+
.reward_maturity_distance
112+
.unwrap_or_else(|| BlockDistance::new(500)),
113+
}
114+
}
115+
}
116+
80117
const fn no_retargeting(chain_type: ChainType) -> bool {
81118
match chain_type {
82119
ChainType::Mainnet | ChainType::Testnet | ChainType::Signet => false,

consensus/src/pow/error.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ pub enum ConsensusPoWError {
4444
PoSInputDataProvided,
4545
#[error("No input data was provided for PoW block generation")]
4646
NoInputDataProvided,
47-
#[error("Genesis block cannot have an ongoing difficulty")]
48-
GenesisCannotHaveOngoingDifficulty,
4947
#[error("Block reward maturity value {0} is invalid")]
5048
InvalidBlockRewardMaturityDistance(BlockDistance),
5149
}

consensus/src/pow/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct PoW(PoWChainConfig);
3434

3535
impl PoW {
3636
pub fn new(chain_config: &ChainConfig) -> Self {
37-
PoW(chain_config.get_proof_of_work_config())
37+
PoW(chain_config.get_proof_of_work_config().clone())
3838
}
3939

4040
pub fn difficulty_limit(&self) -> Uint256 {

consensus/src/pow/work.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub fn check_pow_consensus<H: BlockIndexHandle>(
6363
let work_required = match pow_status {
6464
PoWStatus::Threshold { initial_difficulty } => *initial_difficulty,
6565
PoWStatus::Ongoing => match header.prev_block_id().classify(chain_config) {
66-
GenBlockId::Genesis(_) => Err(ConsensusPoWError::GenesisCannotHaveOngoingDifficulty)?,
66+
GenBlockId::Genesis(_) => PoW::new(chain_config).difficulty_limit().into(),
6767
GenBlockId::Block(prev_id) => {
6868
let prev_block_index = block_index_handle
6969
.get_block_index(&prev_id)
@@ -119,9 +119,7 @@ where
119119
match pow_status {
120120
PoWStatus::Threshold { initial_difficulty } => Ok(*initial_difficulty),
121121
PoWStatus::Ongoing => match prev_gen_block_index {
122-
GenBlockIndex::Genesis(_) => {
123-
Err(ConsensusPoWError::GenesisCannotHaveOngoingDifficulty)?
124-
}
122+
GenBlockIndex::Genesis(_) => Ok(PoW::new(chain_config).difficulty_limit().into()),
125123
GenBlockIndex::Block(prev_block_index) => PoW::new(chain_config).get_work_required(
126124
prev_block_index,
127125
block_timestamp,

0 commit comments

Comments
 (0)