From b4711c7118d2a79b5441f508dbf368b2cbae8eca Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Wed, 6 Sep 2023 19:50:49 +0100 Subject: [PATCH] add references to monero protocol docs + skip genesis block in DifficultyCalculator --- consensus/src/bin/scan_chain.rs | 8 +++++--- consensus/src/genesis.rs | 2 +- consensus/src/hardforks.rs | 26 +++++++++++++++----------- consensus/src/pow/difficulty.rs | 18 +++++++++++++++--- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/consensus/src/bin/scan_chain.rs b/consensus/src/bin/scan_chain.rs index c26b9610..7fcb6d8f 100644 --- a/consensus/src/bin/scan_chain.rs +++ b/consensus/src/bin/scan_chain.rs @@ -39,7 +39,7 @@ impl tower::retry::Policy for Attempts { type Future = futures::future::Ready; fn retry(&self, _: &Req, result: Result<&Res, &E>) -> Option { if result.is_err() { - Some(futures::future::ready(Attempts(self.0 - 1))) + Some(futures::future::ready(Attempts(self.0 ))) } else { None } @@ -92,11 +92,13 @@ async fn main() { println!("{pow_info:?}"); - let difficulty = DifficultyCalculator::init_from_chain_height(2968227, rpc.clone()) + let difficulty = DifficultyCalculator::init_from_chain_height(578656, rpc.clone()) .await .unwrap(); - println!("{:?}", difficulty.next_difficulty(&HardFork::V16)); //257344482654 + println!("{:?}", difficulty); + + println!("{:?}", difficulty.next_difficulty(&HardFork::V1)); //774466376 //let _hfs = HardForks::init_at_chain_height(HardForkConfig::default(), 1009827, rpc.clone()) // .await diff --git a/consensus/src/genesis.rs b/consensus/src/genesis.rs index 7b7bd7ca..731eb03c 100644 --- a/consensus/src/genesis.rs +++ b/consensus/src/genesis.rs @@ -25,7 +25,7 @@ fn genesis_miner_tx(network: &Network) -> Transaction { /// Generates the Monero genesis block. /// -/// ref: consensus-doc#Genesis +/// ref: https://cuprate.github.io/monero-docs/consensus_rules/genesis_block.html pub fn generate_genesis_block(network: &Network) -> Block { Block { header: BlockHeader { diff --git a/consensus/src/hardforks.rs b/consensus/src/hardforks.rs index 923e14d3..d976c0ae 100644 --- a/consensus/src/hardforks.rs +++ b/consensus/src/hardforks.rs @@ -11,7 +11,7 @@ use cuprate_common::{BlockID, Network}; use crate::{Database, DatabaseRequest, DatabaseResponse, Error}; -//http://localhost:3000/consensus_rules/hardforks.html#window-size +// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#accepting-a-fork const DEFAULT_WINDOW_SIZE: u64 = 10080; // supermajority window check length - a week /// An identifier for every hard-fork Monero has had. @@ -33,13 +33,14 @@ pub enum HardFork { V13, V14, V15, + // remember to update from_vote! V16, } impl HardFork { /// Returns the hard-fork for a blocks `major_version` field. /// - /// http://**/consensus_rules/hardforks.html#blocks-version-and-vote + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#blocks-version-and-vote pub fn from_version(version: &u8) -> Result { Ok(match version { 1 => HardFork::V1, @@ -68,7 +69,7 @@ impl HardFork { /// Returns the hard-fork for a blocks `minor_version` (vote) field. /// - /// http://**/consensus_rules/hardforks.html#blocks-version-and-vote + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#blocks-version-and-vote pub fn from_vote(vote: &u8) -> HardFork { if *vote == 0 { // A vote of 0 is interpreted as 1 as that's what Monero used to default to. @@ -102,10 +103,13 @@ impl HardFork { /// Returns the threshold of this fork. pub fn fork_threshold(&self, _: &Network) -> u64 { + // No Monero hard forks actually use voting 0 } /// Returns the votes needed for this fork. + /// + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#accepting-a-fork pub fn votes_needed(&self, network: &Network, window: u64) -> u64 { (self.fork_threshold(network) * window + 99) / 100 } @@ -119,14 +123,17 @@ impl HardFork { } } + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#Stagenet-Hard-Forks fn stagenet_fork_height(&self) -> u64 { todo!() } + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#Testnet-Hard-Forks fn testnet_fork_height(&self) -> u64 { todo!() } + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#Mainnet-Hard-Forks fn mainnet_fork_height(&self) -> u64 { match self { HardFork::V1 => 0, // Monero core has this as 1, which is strange @@ -197,7 +204,7 @@ impl HFVotes { /// Returns the total votes for a hard-fork. /// - /// http://localhost:3000/consensus_rules/hardforks.html#accepting-a-fork + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#accepting-a-fork pub fn votes_for_hf(&self, hf: &HardFork) -> u64 { self.votes[*hf as usize - 1..].iter().sum() } @@ -402,6 +409,9 @@ impl HardForks { self.check_set_new_hf() } + /// Checks if the next hard-fork should be activated and sets it it it should. + /// + /// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#accepting-a-fork fn check_set_new_hf(&mut self) { while let Some(new_hf) = self.next_hardfork { if self.last_height + 1 >= new_hf.fork_height(&self.config.network) @@ -415,6 +425,7 @@ impl HardForks { } } + /// Sets a new hard-fork. fn set_hf(&mut self, new_hf: HardFork) { self.next_hardfork = new_hf.next_fork(); self.current_hardfork = new_hf; @@ -460,10 +471,3 @@ async fn get_block_header( }; Ok(header) } - -#[test] -fn to_from_hf() { - let hf = HardFork::V1 as u8; - - assert_eq!(hf, 1) -} diff --git a/consensus/src/pow/difficulty.rs b/consensus/src/pow/difficulty.rs index 24e12551..77e19436 100644 --- a/consensus/src/pow/difficulty.rs +++ b/consensus/src/pow/difficulty.rs @@ -51,7 +51,11 @@ impl DifficultyCalculator { chain_height: u64, mut database: D, ) -> Result { - let block_start = chain_height.saturating_sub(DIFFICULTY_BLOCKS_COUNT); + let mut block_start = chain_height.saturating_sub(DIFFICULTY_BLOCKS_COUNT); + + if block_start == 0 { + block_start = 1; + } let timestamps = get_blocks_in_range_timestamps(database.clone(), block_start..chain_height).await?; @@ -111,7 +115,12 @@ impl DifficultyCalculator { } async fn update_windowed_work(&mut self, mut database: D) -> Result<(), Error> { - let block_start = (self.last_accounted_height + 1).saturating_sub(DIFFICULTY_BLOCKS_COUNT); + let mut block_start = + (self.last_accounted_height + 1).saturating_sub(DIFFICULTY_BLOCKS_COUNT); + + if block_start == 0 { + block_start = 1; + } let (start, end) = get_window_start_and_end(self.timestamps.len()); @@ -137,7 +146,9 @@ impl DifficultyCalculator { } let mut sorted_timestamps = self.timestamps.clone(); - sorted_timestamps.drain(DIFFICULTY_WINDOW..); + if sorted_timestamps.len() > DIFFICULTY_WINDOW { + sorted_timestamps.drain(DIFFICULTY_WINDOW..); + }; sorted_timestamps.sort_unstable(); let (window_start, window_end) = get_window_start_and_end(sorted_timestamps.len()); @@ -194,6 +205,7 @@ async fn get_blocks_in_range_timestamps( } async fn get_block_timestamp(database: D, height: u64) -> Result { + tracing::debug!("Getting block timestamp: {}", height); let DatabaseResponse::BlockPOWInfo(pow) = database .oneshot(DatabaseRequest::BlockPOWInfo(height.into())) .await?