add references to monero protocol docs

+ skip genesis block in DifficultyCalculator
This commit is contained in:
Boog900 2023-09-06 19:50:49 +01:00
parent ab3c496bbd
commit b4711c7118
No known key found for this signature in database
GPG key ID: 5401367FB7302004
4 changed files with 36 additions and 18 deletions

View file

@ -39,7 +39,7 @@ impl<Req: Clone, Res, E> tower::retry::Policy<Req, Res, E> for Attempts {
type Future = futures::future::Ready<Self>;
fn retry(&self, _: &Req, result: Result<&Res, &E>) -> Option<Self::Future> {
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

View file

@ -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 {

View file

@ -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<HardFork, Error> {
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<D: Database>(
};
Ok(header)
}
#[test]
fn to_from_hf() {
let hf = HardFork::V1 as u8;
assert_eq!(hf, 1)
}

View file

@ -51,7 +51,11 @@ impl DifficultyCalculator {
chain_height: u64,
mut database: D,
) -> Result<Self, Error> {
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<D: Database>(&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<D: Database + Clone>(
}
async fn get_block_timestamp<D: Database>(database: D, height: u64) -> Result<u64, Error> {
tracing::debug!("Getting block timestamp: {}", height);
let DatabaseResponse::BlockPOWInfo(pow) = database
.oneshot(DatabaseRequest::BlockPOWInfo(height.into()))
.await?