mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 11:39:26 +00:00
consensus: add more difficulty tests
This commit is contained in:
parent
29e2c4b2db
commit
81eec5cbbb
7 changed files with 67 additions and 18 deletions
|
@ -44,7 +44,7 @@ dalek-ff-group = { workspace = true }
|
|||
|
||||
rayon = { workspace = true }
|
||||
thread_local = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt"] }
|
||||
tokio-util = { workspace = true }
|
||||
|
||||
hex = "0.4"
|
||||
|
|
|
@ -17,7 +17,7 @@ multiexp = { workspace = true, features = ["std", "batch"] }
|
|||
dalek-ff-group = { workspace = true, features = ["std"] }
|
||||
curve25519-dalek = { workspace = true, features = ["alloc", "zeroize", "precomputed-tables"] }
|
||||
|
||||
rand = { workspace = true, features = ["std"] }
|
||||
rand = { workspace = true, features = ["std", "std_rng"] }
|
||||
|
||||
hex = { workspace = true, features = ["std"] }
|
||||
hex-literal = { workspace = true }
|
||||
|
|
|
@ -19,7 +19,7 @@ mod bin {
|
|||
use tower::{Service, ServiceExt};
|
||||
use tracing::level_filters::LevelFilter;
|
||||
|
||||
use cuprate_helper::network::Network;
|
||||
use cuprate_helper::{asynch::rayon_spawn_async, network::Network};
|
||||
|
||||
use cuprate_consensus::{
|
||||
block::PrePreparedBlockExPOW,
|
||||
|
@ -336,18 +336,6 @@ mod bin {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn rayon_spawn_async<F, R>(f: F) -> R
|
||||
where
|
||||
F: FnOnce() -> R + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
rayon::spawn(|| {
|
||||
let _ = tx.send(f());
|
||||
});
|
||||
rx.await.expect("The sender must not be dropped")
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
/// The log level, valid values:
|
||||
|
@ -515,4 +503,6 @@ async fn main() {
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "binaries"))]
|
||||
fn main() {}
|
||||
fn main() {
|
||||
panic!("must run with feature `binaries`")
|
||||
}
|
||||
|
|
|
@ -7,3 +7,5 @@ pub static HFS_2678808_2688888: [(HardFork, HardFork); 10080] =
|
|||
include!("./data/hfs_2678808_2688888");
|
||||
|
||||
pub static BW_2850000_3050000: [(usize, usize); 200_000] = include!("./data/bw_2850000_3050000");
|
||||
|
||||
pub static DIF_3000000_3002000: [(u128, u64); 2000] = include!("./data/dif_3000000_3002000");
|
||||
|
|
1
consensus/src/tests/context/data/dif_3000000_3002000
Normal file
1
consensus/src/tests/context/data/dif_3000000_3002000
Normal file
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,11 @@ use proptest::{arbitrary::any, prop_assert_eq, prop_compose, proptest};
|
|||
|
||||
use cuprate_helper::num::median;
|
||||
|
||||
use crate::{context::difficulty::*, tests::mock_db::*, HardFork};
|
||||
use crate::{
|
||||
context::difficulty::*,
|
||||
tests::{context::data::DIF_3000000_3002000, mock_db::*},
|
||||
HardFork,
|
||||
};
|
||||
|
||||
const TEST_WINDOW: usize = 72;
|
||||
const TEST_CUT: usize = 6;
|
||||
|
@ -45,6 +49,42 @@ async fn genesis_block_skipped() -> Result<(), tower::BoxError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn calculate_diff_3000000_3002000() -> Result<(), tower::BoxError> {
|
||||
let cfg = DifficultyCacheConfig::main_net();
|
||||
|
||||
let mut db_builder = DummyDatabaseBuilder::default();
|
||||
for (cum_dif, timestamp) in DIF_3000000_3002000
|
||||
.iter()
|
||||
.take(cfg.total_block_count() as usize)
|
||||
{
|
||||
db_builder.add_block(
|
||||
DummyBlockExtendedHeader::default().with_difficulty_info(*timestamp, *cum_dif),
|
||||
)
|
||||
}
|
||||
|
||||
let mut diff_cache = DifficultyCache::init_from_chain_height(
|
||||
3_000_720,
|
||||
cfg.clone(),
|
||||
db_builder.finish(Some(3_000_720)),
|
||||
)
|
||||
.await?;
|
||||
|
||||
for (i, diff_info) in DIF_3000000_3002000
|
||||
.windows(2)
|
||||
.skip(cfg.total_block_count() as usize - 1)
|
||||
.enumerate()
|
||||
{
|
||||
let diff = diff_info[1].0 - diff_info[0].0;
|
||||
|
||||
assert_eq!(diff_cache.next_difficulty(&HardFork::V16), diff);
|
||||
|
||||
diff_cache.new_block(3_000_720 + i as u64, diff_info[1].1, diff_info[1].0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
prop_compose! {
|
||||
/// Generates an arbitrary full difficulty cache.
|
||||
fn arb_full_difficulty_cache()
|
||||
|
|
|
@ -87,11 +87,27 @@ where
|
|||
/// If not sorted the output will be invalid.
|
||||
pub fn median<T>(array: impl AsRef<[T]>) -> T
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + Div<Output = T> + Mul<Output = T> + Copy + From<u8>,
|
||||
T: Add<Output = T>
|
||||
+ Sub<Output = T>
|
||||
+ Div<Output = T>
|
||||
+ Mul<Output = T>
|
||||
+ PartialOrd
|
||||
+ Copy
|
||||
+ From<u8>,
|
||||
{
|
||||
let array = array.as_ref();
|
||||
let len = array.len();
|
||||
|
||||
// TODO: use `is_sorted` when stable.
|
||||
debug_assert!(array
|
||||
.windows(2)
|
||||
.try_for_each(|window| if window[0] <= window[1] {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
})
|
||||
.is_ok());
|
||||
|
||||
let mid = len / 2;
|
||||
|
||||
if len == 1 {
|
||||
|
|
Loading…
Reference in a new issue