mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-11-17 00:07:53 +00:00
add references to monero protocol docs
+ skip genesis block in DifficultyCalculator
This commit is contained in:
parent
ab3c496bbd
commit
b4711c7118
4 changed files with 36 additions and 18 deletions
|
@ -39,7 +39,7 @@ impl<Req: Clone, Res, E> tower::retry::Policy<Req, Res, E> for Attempts {
|
||||||
type Future = futures::future::Ready<Self>;
|
type Future = futures::future::Ready<Self>;
|
||||||
fn retry(&self, _: &Req, result: Result<&Res, &E>) -> Option<Self::Future> {
|
fn retry(&self, _: &Req, result: Result<&Res, &E>) -> Option<Self::Future> {
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
Some(futures::future::ready(Attempts(self.0 - 1)))
|
Some(futures::future::ready(Attempts(self.0 )))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -92,11 +92,13 @@ async fn main() {
|
||||||
|
|
||||||
println!("{pow_info:?}");
|
println!("{pow_info:?}");
|
||||||
|
|
||||||
let difficulty = DifficultyCalculator::init_from_chain_height(2968227, rpc.clone())
|
let difficulty = DifficultyCalculator::init_from_chain_height(578656, rpc.clone())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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())
|
//let _hfs = HardForks::init_at_chain_height(HardForkConfig::default(), 1009827, rpc.clone())
|
||||||
// .await
|
// .await
|
||||||
|
|
|
@ -25,7 +25,7 @@ fn genesis_miner_tx(network: &Network) -> Transaction {
|
||||||
|
|
||||||
/// Generates the Monero genesis block.
|
/// 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 {
|
pub fn generate_genesis_block(network: &Network) -> Block {
|
||||||
Block {
|
Block {
|
||||||
header: BlockHeader {
|
header: BlockHeader {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use cuprate_common::{BlockID, Network};
|
||||||
|
|
||||||
use crate::{Database, DatabaseRequest, DatabaseResponse, Error};
|
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
|
const DEFAULT_WINDOW_SIZE: u64 = 10080; // supermajority window check length - a week
|
||||||
|
|
||||||
/// An identifier for every hard-fork Monero has had.
|
/// An identifier for every hard-fork Monero has had.
|
||||||
|
@ -33,13 +33,14 @@ pub enum HardFork {
|
||||||
V13,
|
V13,
|
||||||
V14,
|
V14,
|
||||||
V15,
|
V15,
|
||||||
|
// remember to update from_vote!
|
||||||
V16,
|
V16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HardFork {
|
impl HardFork {
|
||||||
/// Returns the hard-fork for a blocks `major_version` field.
|
/// 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> {
|
pub fn from_version(version: &u8) -> Result<HardFork, Error> {
|
||||||
Ok(match version {
|
Ok(match version {
|
||||||
1 => HardFork::V1,
|
1 => HardFork::V1,
|
||||||
|
@ -68,7 +69,7 @@ impl HardFork {
|
||||||
|
|
||||||
/// Returns the hard-fork for a blocks `minor_version` (vote) field.
|
/// 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 {
|
pub fn from_vote(vote: &u8) -> HardFork {
|
||||||
if *vote == 0 {
|
if *vote == 0 {
|
||||||
// A vote of 0 is interpreted as 1 as that's what Monero used to default to.
|
// 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.
|
/// Returns the threshold of this fork.
|
||||||
pub fn fork_threshold(&self, _: &Network) -> u64 {
|
pub fn fork_threshold(&self, _: &Network) -> u64 {
|
||||||
|
// No Monero hard forks actually use voting
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the votes needed for this fork.
|
/// 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 {
|
pub fn votes_needed(&self, network: &Network, window: u64) -> u64 {
|
||||||
(self.fork_threshold(network) * window + 99) / 100
|
(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 {
|
fn stagenet_fork_height(&self) -> u64 {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#Testnet-Hard-Forks
|
||||||
fn testnet_fork_height(&self) -> u64 {
|
fn testnet_fork_height(&self) -> u64 {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://cuprate.github.io/monero-docs/consensus_rules/hardforks.html#Mainnet-Hard-Forks
|
||||||
fn mainnet_fork_height(&self) -> u64 {
|
fn mainnet_fork_height(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
HardFork::V1 => 0, // Monero core has this as 1, which is strange
|
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.
|
/// 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 {
|
pub fn votes_for_hf(&self, hf: &HardFork) -> u64 {
|
||||||
self.votes[*hf as usize - 1..].iter().sum()
|
self.votes[*hf as usize - 1..].iter().sum()
|
||||||
}
|
}
|
||||||
|
@ -402,6 +409,9 @@ impl HardForks {
|
||||||
self.check_set_new_hf()
|
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) {
|
fn check_set_new_hf(&mut self) {
|
||||||
while let Some(new_hf) = self.next_hardfork {
|
while let Some(new_hf) = self.next_hardfork {
|
||||||
if self.last_height + 1 >= new_hf.fork_height(&self.config.network)
|
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) {
|
fn set_hf(&mut self, new_hf: HardFork) {
|
||||||
self.next_hardfork = new_hf.next_fork();
|
self.next_hardfork = new_hf.next_fork();
|
||||||
self.current_hardfork = new_hf;
|
self.current_hardfork = new_hf;
|
||||||
|
@ -460,10 +471,3 @@ async fn get_block_header<D: Database>(
|
||||||
};
|
};
|
||||||
Ok(header)
|
Ok(header)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn to_from_hf() {
|
|
||||||
let hf = HardFork::V1 as u8;
|
|
||||||
|
|
||||||
assert_eq!(hf, 1)
|
|
||||||
}
|
|
||||||
|
|
|
@ -51,7 +51,11 @@ impl DifficultyCalculator {
|
||||||
chain_height: u64,
|
chain_height: u64,
|
||||||
mut database: D,
|
mut database: D,
|
||||||
) -> Result<Self, Error> {
|
) -> 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 =
|
let timestamps =
|
||||||
get_blocks_in_range_timestamps(database.clone(), block_start..chain_height).await?;
|
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> {
|
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());
|
let (start, end) = get_window_start_and_end(self.timestamps.len());
|
||||||
|
|
||||||
|
@ -137,7 +146,9 @@ impl DifficultyCalculator {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sorted_timestamps = self.timestamps.clone();
|
let mut sorted_timestamps = self.timestamps.clone();
|
||||||
|
if sorted_timestamps.len() > DIFFICULTY_WINDOW {
|
||||||
sorted_timestamps.drain(DIFFICULTY_WINDOW..);
|
sorted_timestamps.drain(DIFFICULTY_WINDOW..);
|
||||||
|
};
|
||||||
sorted_timestamps.sort_unstable();
|
sorted_timestamps.sort_unstable();
|
||||||
|
|
||||||
let (window_start, window_end) = get_window_start_and_end(sorted_timestamps.len());
|
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> {
|
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
|
let DatabaseResponse::BlockPOWInfo(pow) = database
|
||||||
.oneshot(DatabaseRequest::BlockPOWInfo(height.into()))
|
.oneshot(DatabaseRequest::BlockPOWInfo(height.into()))
|
||||||
.await?
|
.await?
|
||||||
|
|
Loading…
Reference in a new issue