From b4797fa31f831aa250e3591577d11181bd8b5eac Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 16 Dec 2024 16:12:18 -0500 Subject: [PATCH] relative progress, show buffer --- tests/compat/Cargo.toml | 2 +- tests/compat/src/cli.rs | 4 ++- tests/compat/src/main.rs | 45 +++++++++++++++++++++++++++++++++ tests/compat/src/rpc.rs | 9 +++++++ tests/compat/src/types.rs | 3 +++ tests/compat/src/verify.rs | 52 +++++++++++++++++++++++++------------- 6 files changed, 96 insertions(+), 19 deletions(-) diff --git a/tests/compat/Cargo.toml b/tests/compat/Cargo.toml index 9678cfb..1592cb2 100644 --- a/tests/compat/Cargo.toml +++ b/tests/compat/Cargo.toml @@ -2,7 +2,7 @@ name = "cuprate-tests-compat" version = "0.0.0" edition = "2021" -description = "Compatability tests between `cuprated` and `monerod`" +description = "Compatibility tests between `cuprated` and `monerod`" license = "MIT" authors = ["hinto-janai"] repository = "https://github.com/Cuprate/cuprate/tree/main/tests/compat" diff --git a/tests/compat/src/cli.rs b/tests/compat/src/cli.rs index ed9dda9..b176323 100644 --- a/tests/compat/src/cli.rs +++ b/tests/compat/src/cli.rs @@ -14,7 +14,9 @@ use clap::Parser; ), )] pub struct Args { - /// Name of the person to greet + /// Base URL to use for `monerod` RPC. + /// + /// This must be a non-restricted RPC. #[arg(short, long, default_value_t = String::from("http://127.0.0.1:18081"))] pub rpc_url: String, diff --git a/tests/compat/src/main.rs b/tests/compat/src/main.rs index c6923e5..a0953f4 100644 --- a/tests/compat/src/main.rs +++ b/tests/compat/src/main.rs @@ -47,3 +47,48 @@ async fn main() { std::thread::sleep(Duration::from_secs(1)); } } + +// some draft code for `monerod` <-> `cuprated` RPC compat testing + +// /// represents a `monerod/cuprated` RPC request type. +// trait RpcRequest { +// /// the expected response type, potentially only being a subset of the fields. +// type SubsetOfResponse: PartialEq; + +// /// create a 'base' request. +// fn base() -> Self; + +// /// permutate the base request into all (or practically) possible requests. +// // e.g. `{"height":0}`, `{"height":1}`, etc +// fn all_possible_inputs_for_rpc_request(self) -> Vec; + +// /// send the request, get the response. +// /// +// /// `monerod` and `cuprated` are both expected to be fully synced. +// fn get(self, node: Node) -> Self::SubsetOfResponse; +// } + +// enum Node { +// Monerod, +// Cuprated, +// } + +// // all RPC requests. +// let all_rpc_requests: Vec = todo!(); + +// // for each request... +// for base in all_rpc_requests { +// // create all possible inputs... +// let requests = all_possible_inputs_for_rpc_request(base); + +// // for each input permutation... +// for r in requests { +// // assert (a potential subset of) `monerod` and `cuprated`'s response fields match in value. +// let monerod_response = r.get(Node::Monerod); +// let cuprated_response = r.get(Node::Cuprated); +// assert_eq!( +// monerod_response.subset_of_response(), +// cuprated_response.subset_of_response(), +// ); +// } +// } diff --git a/tests/compat/src/rpc.rs b/tests/compat/src/rpc.rs index 3315317..9fd1b1d 100644 --- a/tests/compat/src/rpc.rs +++ b/tests/compat/src/rpc.rs @@ -1,3 +1,5 @@ +use std::time::Instant; + use crossbeam::channel::Sender; use monero_serai::{block::Block, transaction::Transaction}; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; @@ -144,9 +146,12 @@ impl RpcClient { .collect() } + #[expect(clippy::cast_precision_loss)] pub async fn test(self, top_height: u64, tx: Sender) { use futures::StreamExt; + let now = Instant::now(); + let iter = (0..top_height).map(|height| { let this = self.clone(); let tx = tx.clone(); @@ -185,12 +190,16 @@ impl RpcClient { (seed_height, seed_hash) }; + let elapsed = now.elapsed().as_secs_f64(); + let blocks_per_sec = height as f64 / elapsed; + let data = RpcBlockData { get_block_response, block, seed_height, seed_hash, txs, + blocks_per_sec, }; tx.send(data).unwrap(); diff --git a/tests/compat/src/types.rs b/tests/compat/src/types.rs index 1c9aac2..f164ba7 100644 --- a/tests/compat/src/types.rs +++ b/tests/compat/src/types.rs @@ -20,6 +20,9 @@ pub struct RpcBlockData { /// This vec is: /// - the original transaction blobs pub txs: Vec, + + // Amount of blocks downloaded from RPC per second. + pub blocks_per_sec: f64, } /// Data of a transaction. diff --git a/tests/compat/src/verify.rs b/tests/compat/src/verify.rs index 309fb66..8f1bb37 100644 --- a/tests/compat/src/verify.rs +++ b/tests/compat/src/verify.rs @@ -23,7 +23,6 @@ struct Verifier { top_height: u64, rx: Receiver, seed_hash: [u8; 32], - timestamp: u64, randomx_vm: Option, } @@ -47,7 +46,6 @@ pub fn spawn_verify_pool( top_height, rx, seed_hash: [0; 32], - timestamp: 0, randomx_vm: None, } .loop_listen_verify(); @@ -78,6 +76,7 @@ impl Verifier { seed_height, seed_hash, txs, + blocks_per_sec, } = data; let GetBlockResponse { blob, block_header } = get_block_response; @@ -101,7 +100,7 @@ impl Verifier { Self::verify_all_transactions_are_unique(&txs, &p); Self::verify_transaction_properties(txs, &p); - self.verify_block_fields( + Self::verify_block_fields( calculated_block_weight, calculated_block_reward, &block, @@ -118,7 +117,13 @@ impl Verifier { ); //----------------------------------------------- Print progress. - self.print_progress(algo, seed_height, miner_tx_weight, block_header); + self.print_progress( + algo, + seed_height, + miner_tx_weight, + blocks_per_sec, + block_header, + ); } fn verify_block_properties( @@ -171,7 +176,6 @@ impl Verifier { } fn verify_block_fields( - &mut self, calculated_block_weight: usize, calculated_block_reward: u64, block: &Block, @@ -208,11 +212,6 @@ impl Verifier { assert_eq!(prev_hash, block.header.previous, "{p}"); assert_eq!(reward, calculated_block_reward, "{p}"); assert_eq!(timestamp, block.header.timestamp, "{p}"); - - if timestamp != 0 { - assert!(timestamp > self.timestamp, "{p}"); - self.timestamp = timestamp; - } } fn verify_pow( @@ -245,7 +244,7 @@ impl Verifier { ("randomx", pow_hash) }; - assert_eq!(calculated_pow_hash, pow_hash, "{p}",); + assert_eq!(calculated_pow_hash, pow_hash, "{p}"); algo } @@ -260,6 +259,7 @@ impl Verifier { algo: &'static str, seed_height: u64, miner_tx_weight: usize, + download_bps: f64, BlockHeader { block_weight, hash, @@ -282,14 +282,29 @@ impl Verifier { return; } - let top_height = self.top_height; + const fn find_count_relative_to_pow_activation(height: u64) -> u64 { + if height <= 1546000 { + height + } else if height <= 1685555 { + height - 1546000 + } else if height <= 1788000 { + height - 1685555 + } else if height <= 1978433 { + height - 1788000 + } else { + height - 1978433 + } + } + let top_height = self.top_height; let percent = (count as f64 / top_height as f64) * 100.0; + let relative_count = find_count_relative_to_pow_activation(height); + let block_buffer = self.rx.len(); let elapsed = self.now.elapsed().as_secs_f64(); - let secs_per_hash = elapsed / count as f64; - let bps = count as f64 / elapsed; - let remaining_secs = (top_height as f64 - count as f64) * secs_per_hash; + let secs_per_hash = elapsed / relative_count as f64; + let verify_bps = relative_count as f64 / elapsed; + let remaining_secs = (top_height as f64 - relative_count as f64) * secs_per_hash; let h = (remaining_secs / 60.0 / 60.0) as u64; let m = (remaining_secs / 60.0 % 60.0) as u64; let s = (remaining_secs % 60.0) as u64; @@ -300,7 +315,10 @@ impl Verifier { let miner_tx_hash = hex::encode(miner_tx_hash); let prev_hash = hex::encode(prev_hash); - println!("progress | {count}/{top_height} ({percent:.2}%, {algo}, {bps:.2} blocks/sec, {h}h {m}m {s}s left) + println!( + "progress | {count}/{top_height} ({percent:.2}%) +remaining | [{h}h {m}m {s}s] left for [{algo}] +block_pipeline | [download {download_bps:.2}/sec] -> [buffer {block_buffer}] -> [verify {verify_bps:.2}/sec] seed_hash | {seed_hash} pow_hash | {pow_hash} block_hash | {block_hash} @@ -317,6 +335,6 @@ miner_tx_weight | {miner_tx_weight} major_version | {major_version} minor_version | {minor_version} num_txes | {num_txes}\n", - ); + ); } }