consensus: add more difficulty tests

This commit is contained in:
Boog900 2024-01-22 18:17:34 +00:00
parent 29e2c4b2db
commit 81eec5cbbb
No known key found for this signature in database
GPG key ID: 5401367FB7302004
7 changed files with 67 additions and 18 deletions

View file

@ -44,7 +44,7 @@ dalek-ff-group = { workspace = true }
rayon = { workspace = true } rayon = { workspace = true }
thread_local = { workspace = true } thread_local = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true, features = ["rt"] }
tokio-util = { workspace = true } tokio-util = { workspace = true }
hex = "0.4" hex = "0.4"

View file

@ -17,7 +17,7 @@ multiexp = { workspace = true, features = ["std", "batch"] }
dalek-ff-group = { workspace = true, features = ["std"] } dalek-ff-group = { workspace = true, features = ["std"] }
curve25519-dalek = { workspace = true, features = ["alloc", "zeroize", "precomputed-tables"] } 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 = { workspace = true, features = ["std"] }
hex-literal = { workspace = true } hex-literal = { workspace = true }

View file

@ -19,7 +19,7 @@ mod bin {
use tower::{Service, ServiceExt}; use tower::{Service, ServiceExt};
use tracing::level_filters::LevelFilter; use tracing::level_filters::LevelFilter;
use cuprate_helper::network::Network; use cuprate_helper::{asynch::rayon_spawn_async, network::Network};
use cuprate_consensus::{ use cuprate_consensus::{
block::PrePreparedBlockExPOW, block::PrePreparedBlockExPOW,
@ -336,18 +336,6 @@ mod bin {
Ok(()) 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)] #[derive(Parser)]
struct Args { struct Args {
/// The log level, valid values: /// The log level, valid values:
@ -515,4 +503,6 @@ async fn main() {
} }
#[cfg(not(feature = "binaries"))] #[cfg(not(feature = "binaries"))]
fn main() {} fn main() {
panic!("must run with feature `binaries`")
}

View file

@ -7,3 +7,5 @@ pub static HFS_2678808_2688888: [(HardFork, HardFork); 10080] =
include!("./data/hfs_2678808_2688888"); include!("./data/hfs_2678808_2688888");
pub static BW_2850000_3050000: [(usize, usize); 200_000] = include!("./data/bw_2850000_3050000"); 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");

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,11 @@ use proptest::{arbitrary::any, prop_assert_eq, prop_compose, proptest};
use cuprate_helper::num::median; 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_WINDOW: usize = 72;
const TEST_CUT: usize = 6; const TEST_CUT: usize = 6;
@ -45,6 +49,42 @@ async fn genesis_block_skipped() -> Result<(), tower::BoxError> {
Ok(()) 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! { prop_compose! {
/// Generates an arbitrary full difficulty cache. /// Generates an arbitrary full difficulty cache.
fn arb_full_difficulty_cache() fn arb_full_difficulty_cache()

View file

@ -87,11 +87,27 @@ where
/// If not sorted the output will be invalid. /// If not sorted the output will be invalid.
pub fn median<T>(array: impl AsRef<[T]>) -> T pub fn median<T>(array: impl AsRef<[T]>) -> T
where 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 array = array.as_ref();
let len = array.len(); 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; let mid = len / 2;
if len == 1 { if len == 1 {