mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
test: add support for seeded rng (#3270)
This commit is contained in:
1
.github/workflows/integration.yml
vendored
1
.github/workflows/integration.yml
vendored
@ -9,6 +9,7 @@ env:
|
||||
RUSTFLAGS: -D warnings
|
||||
CARGO_TERM_COLOR: always
|
||||
GETH_BUILD: 1.12.0-e501b3b0
|
||||
SEED: rustethereumethereumrust
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
||||
1
.github/workflows/unit.yml
vendored
1
.github/workflows/unit.yml
vendored
@ -8,6 +8,7 @@ on:
|
||||
env:
|
||||
RUSTFLAGS: -D warnings
|
||||
CARGO_TERM_COLOR: always
|
||||
SEED: rustethereumethereumrust
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
|
||||
11
README.md
11
README.md
@ -94,10 +94,21 @@ cargo test --workspace
|
||||
|
||||
# With Geth
|
||||
cargo test --workspace --features geth-tests
|
||||
|
||||
# With Ethereum Foundation tests
|
||||
#
|
||||
# Note: Requires cloning https://github.com/ethereum/tests
|
||||
#
|
||||
# cd testing/ef-tests && git clone https://github.com/ethereum/tests ethereum-tests
|
||||
cargo test --workspace --features ef-tests
|
||||
```
|
||||
|
||||
We recommend using [`cargo nextest`](https://nexte.st/) to speed up testing. With nextest installed, simply substitute `cargo test` with `cargo nextest run`.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Some tests use random number generators to generate test data. If you want to use a deterministic seed, you can set the `SEED` environment variable.
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you have any questions, first see if the answer to your question can be found in the [book][book].
|
||||
|
||||
@ -215,21 +215,23 @@ impl BlockBuffer {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use reth_interfaces::test_utils::generators;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use reth_interfaces::test_utils::generators::random_block;
|
||||
use reth_interfaces::test_utils::generators::{random_block, Rng};
|
||||
use reth_primitives::{BlockHash, BlockNumHash, SealedBlockWithSenders};
|
||||
|
||||
use crate::BlockBuffer;
|
||||
|
||||
fn create_block(number: u64, parent: BlockHash) -> SealedBlockWithSenders {
|
||||
let block = random_block(number, Some(parent), None, None);
|
||||
fn create_block<R: Rng>(rng: &mut R, number: u64, parent: BlockHash) -> SealedBlockWithSenders {
|
||||
let block = random_block(rng, number, Some(parent), None, None);
|
||||
block.seal_with_senders().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_insertion() {
|
||||
let block1 = create_block(10, BlockHash::random());
|
||||
let mut rng = generators::rng();
|
||||
let block1 = create_block(&mut rng, 10, BlockHash::random());
|
||||
let mut buffer = BlockBuffer::new(3);
|
||||
|
||||
buffer.insert_block(block1.clone());
|
||||
@ -240,11 +242,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn take_all_chain_of_childrens() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(12, block2.hash);
|
||||
let block4 = create_block(14, BlockHash::random());
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 12, block2.hash);
|
||||
let block4 = create_block(&mut rng, 14, BlockHash::random());
|
||||
|
||||
let mut buffer = BlockBuffer::new(5);
|
||||
|
||||
@ -267,11 +271,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn take_all_multi_level_childrens() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(11, block1.hash);
|
||||
let block4 = create_block(12, block2.hash);
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 11, block1.hash);
|
||||
let block4 = create_block(&mut rng, 12, block2.hash);
|
||||
|
||||
let mut buffer = BlockBuffer::new(5);
|
||||
|
||||
@ -299,11 +305,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn take_self_with_childs() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(11, block1.hash);
|
||||
let block4 = create_block(12, block2.hash);
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 11, block1.hash);
|
||||
let block4 = create_block(&mut rng, 12, block2.hash);
|
||||
|
||||
let mut buffer = BlockBuffer::new(5);
|
||||
|
||||
@ -331,11 +339,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn clean_chain_of_children() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(12, block2.hash);
|
||||
let block4 = create_block(14, BlockHash::random());
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 12, block2.hash);
|
||||
let block4 = create_block(&mut rng, 14, BlockHash::random());
|
||||
|
||||
let mut buffer = BlockBuffer::new(5);
|
||||
|
||||
@ -351,11 +361,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn clean_all_multi_level_childrens() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(11, block1.hash);
|
||||
let block4 = create_block(12, block2.hash);
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 11, block1.hash);
|
||||
let block4 = create_block(&mut rng, 12, block2.hash);
|
||||
|
||||
let mut buffer = BlockBuffer::new(5);
|
||||
|
||||
@ -371,14 +383,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn clean_multi_chains() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block1a = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block2a = create_block(11, block1.hash);
|
||||
let random_block1 = create_block(10, BlockHash::random());
|
||||
let random_block2 = create_block(11, BlockHash::random());
|
||||
let random_block3 = create_block(12, BlockHash::random());
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block1a = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block2a = create_block(&mut rng, 11, block1.hash);
|
||||
let random_block1 = create_block(&mut rng, 10, BlockHash::random());
|
||||
let random_block2 = create_block(&mut rng, 11, BlockHash::random());
|
||||
let random_block3 = create_block(&mut rng, 12, BlockHash::random());
|
||||
|
||||
let mut buffer = BlockBuffer::new(10);
|
||||
|
||||
@ -420,11 +434,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn evict_with_gap() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(12, block2.hash);
|
||||
let block4 = create_block(13, BlockHash::random());
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 12, block2.hash);
|
||||
let block4 = create_block(&mut rng, 13, BlockHash::random());
|
||||
|
||||
let mut buffer = BlockBuffer::new(3);
|
||||
|
||||
@ -454,11 +470,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn simple_eviction() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let main_parent = BlockNumHash::new(9, BlockHash::random());
|
||||
let block1 = create_block(10, main_parent.hash);
|
||||
let block2 = create_block(11, block1.hash);
|
||||
let block3 = create_block(12, block2.hash);
|
||||
let block4 = create_block(13, BlockHash::random());
|
||||
let block1 = create_block(&mut rng, 10, main_parent.hash);
|
||||
let block2 = create_block(&mut rng, 11, block1.hash);
|
||||
let block3 = create_block(&mut rng, 12, block2.hash);
|
||||
let block4 = create_block(&mut rng, 13, BlockHash::random());
|
||||
|
||||
let mut buffer = BlockBuffer::new(3);
|
||||
|
||||
|
||||
@ -1751,7 +1751,7 @@ mod tests {
|
||||
mod fork_choice_updated {
|
||||
use super::*;
|
||||
use reth_db::{tables, transaction::DbTxMut};
|
||||
use reth_interfaces::test_utils::generators::random_block;
|
||||
use reth_interfaces::test_utils::{generators, generators::random_block};
|
||||
use reth_rpc_types::engine::ForkchoiceUpdateError;
|
||||
|
||||
#[tokio::test]
|
||||
@ -1786,6 +1786,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn valid_forkchoice() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -1801,8 +1802,8 @@ mod tests {
|
||||
})]))
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let block1 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
let block1 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
insert_blocks(env.db.as_ref(), chain_spec.clone(), [&genesis, &block1].into_iter());
|
||||
env.db
|
||||
.update(|tx| {
|
||||
@ -1833,6 +1834,8 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn unknown_head_hash() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -1849,13 +1852,13 @@ mod tests {
|
||||
.disable_blockchain_tree_sync()
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let block1 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
let block1 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
insert_blocks(env.db.as_ref(), chain_spec.clone(), [&genesis, &block1].into_iter());
|
||||
|
||||
let mut engine_rx = spawn_consensus_engine(consensus_engine);
|
||||
|
||||
let next_head = random_block(2, Some(block1.hash), None, Some(0));
|
||||
let next_head = random_block(&mut rng, 2, Some(block1.hash), None, Some(0));
|
||||
let next_forkchoice_state = ForkchoiceState {
|
||||
head_block_hash: next_head.hash,
|
||||
finalized_block_hash: block1.hash,
|
||||
@ -1882,6 +1885,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn unknown_finalized_hash() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -1898,8 +1902,8 @@ mod tests {
|
||||
.disable_blockchain_tree_sync()
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let block1 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
let block1 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
insert_blocks(env.db.as_ref(), chain_spec.clone(), [&genesis, &block1].into_iter());
|
||||
|
||||
let engine = spawn_consensus_engine(consensus_engine);
|
||||
@ -1918,6 +1922,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn forkchoice_updated_pre_merge() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -1934,16 +1939,16 @@ mod tests {
|
||||
]))
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let mut block1 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
let mut block1 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
block1.header.difficulty = U256::from(1);
|
||||
|
||||
// a second pre-merge block
|
||||
let mut block2 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let mut block2 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
block2.header.difficulty = U256::from(1);
|
||||
|
||||
// a transition block
|
||||
let mut block3 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let mut block3 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
block3.header.difficulty = U256::from(1);
|
||||
|
||||
insert_blocks(
|
||||
@ -1971,6 +1976,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn forkchoice_updated_invalid_pow() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -1986,8 +1992,8 @@ mod tests {
|
||||
]))
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let block1 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
let block1 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
|
||||
insert_blocks(env.db.as_ref(), chain_spec.clone(), [&genesis, &block1].into_iter());
|
||||
|
||||
@ -2011,12 +2017,13 @@ mod tests {
|
||||
|
||||
mod new_payload {
|
||||
use super::*;
|
||||
use reth_interfaces::test_utils::generators::random_block;
|
||||
use reth_interfaces::test_utils::{generators, generators::random_block};
|
||||
use reth_primitives::{Hardfork, U256};
|
||||
use reth_provider::test_utils::blocks::BlockChainTestData;
|
||||
|
||||
#[tokio::test]
|
||||
async fn new_payload_before_forkchoice() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -2035,12 +2042,14 @@ mod tests {
|
||||
let mut engine_rx = spawn_consensus_engine(consensus_engine);
|
||||
|
||||
// Send new payload
|
||||
let res = env.send_new_payload(random_block(0, None, None, Some(0)).into()).await;
|
||||
let res =
|
||||
env.send_new_payload(random_block(&mut rng, 0, None, None, Some(0)).into()).await;
|
||||
// Invalid, because this is a genesis block
|
||||
assert_matches!(res, Ok(result) => assert_matches!(result.status, PayloadStatusEnum::Invalid { .. }));
|
||||
|
||||
// Send new payload
|
||||
let res = env.send_new_payload(random_block(1, None, None, Some(0)).into()).await;
|
||||
let res =
|
||||
env.send_new_payload(random_block(&mut rng, 1, None, None, Some(0)).into()).await;
|
||||
let expected_result = PayloadStatus::from_status(PayloadStatusEnum::Syncing);
|
||||
assert_matches!(res, Ok(result) => assert_eq!(result, expected_result));
|
||||
|
||||
@ -2049,6 +2058,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn payload_known() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -2064,9 +2074,9 @@ mod tests {
|
||||
})]))
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let block1 = random_block(1, Some(genesis.hash), None, Some(0));
|
||||
let block2 = random_block(2, Some(block1.hash), None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
let block1 = random_block(&mut rng, 1, Some(genesis.hash), None, Some(0));
|
||||
let block2 = random_block(&mut rng, 2, Some(block1.hash), None, Some(0));
|
||||
insert_blocks(
|
||||
env.db.as_ref(),
|
||||
chain_spec.clone(),
|
||||
@ -2098,6 +2108,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn payload_parent_unknown() {
|
||||
let mut rng = generators::rng();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default()
|
||||
.chain(MAINNET.chain)
|
||||
@ -2113,7 +2124,7 @@ mod tests {
|
||||
})]))
|
||||
.build();
|
||||
|
||||
let genesis = random_block(0, None, None, Some(0));
|
||||
let genesis = random_block(&mut rng, 0, None, None, Some(0));
|
||||
|
||||
insert_blocks(env.db.as_ref(), chain_spec.clone(), [&genesis].into_iter());
|
||||
|
||||
@ -2132,7 +2143,7 @@ mod tests {
|
||||
assert_matches!(res, Ok(ForkchoiceUpdated { payload_status, .. }) => assert_eq!(payload_status, expected_result));
|
||||
|
||||
// Send new payload
|
||||
let block = random_block(2, Some(H256::random()), None, Some(0));
|
||||
let block = random_block(&mut rng, 2, Some(H256::random()), None, Some(0));
|
||||
let res = env.send_new_payload(block.into()).await;
|
||||
let expected_result = PayloadStatus::from_status(PayloadStatusEnum::Syncing);
|
||||
assert_matches!(res, Ok(result) => assert_eq!(result, expected_result));
|
||||
|
||||
@ -52,4 +52,4 @@ secp256k1 = { workspace = true, features = [
|
||||
] }
|
||||
|
||||
[features]
|
||||
test-utils = ["tokio-stream/sync", "secp256k1"]
|
||||
test-utils = ["tokio-stream/sync", "secp256k1", "rand/std_rng"]
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
use rand::{distributions::uniform::SampleRange, seq::SliceRandom, thread_rng, Rng};
|
||||
pub use rand::Rng;
|
||||
use rand::{
|
||||
distributions::uniform::SampleRange, rngs::StdRng, seq::SliceRandom, thread_rng, SeedableRng,
|
||||
};
|
||||
use reth_primitives::{
|
||||
proofs, sign_message, Account, Address, BlockNumber, Bytes, Header, SealedBlock, SealedHeader,
|
||||
Signature, StorageEntry, Transaction, TransactionKind, TransactionSigned, TxLegacy, H160, H256,
|
||||
@ -7,23 +10,42 @@ use reth_primitives::{
|
||||
use secp256k1::{KeyPair, Message as SecpMessage, Secp256k1, SecretKey, SECP256K1};
|
||||
use std::{
|
||||
cmp::{max, min},
|
||||
collections::BTreeMap,
|
||||
collections::{hash_map::DefaultHasher, BTreeMap},
|
||||
hash::Hasher,
|
||||
ops::{Range, RangeInclusive, Sub},
|
||||
};
|
||||
|
||||
// TODO(onbjerg): Maybe we should split this off to its own crate, or move the helpers to the
|
||||
// relevant crates?
|
||||
|
||||
/// Returns a random number generator that can be seeded using the `SEED` environment variable.
|
||||
///
|
||||
/// If `SEED` is not set, a random seed is used.
|
||||
pub fn rng() -> StdRng {
|
||||
if let Ok(seed) = std::env::var("SEED") {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
hasher.write(seed.as_bytes());
|
||||
StdRng::seed_from_u64(hasher.finish())
|
||||
} else {
|
||||
StdRng::from_rng(thread_rng()).expect("could not build rng")
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a range of random [SealedHeader]s.
|
||||
///
|
||||
/// The parent hash of the first header
|
||||
/// in the result will be equal to `head`.
|
||||
///
|
||||
/// The headers are assumed to not be correct if validated.
|
||||
pub fn random_header_range(rng: std::ops::Range<u64>, head: H256) -> Vec<SealedHeader> {
|
||||
let mut headers = Vec::with_capacity(rng.end.saturating_sub(rng.start) as usize);
|
||||
for idx in rng {
|
||||
pub fn random_header_range<R: Rng>(
|
||||
rng: &mut R,
|
||||
range: std::ops::Range<u64>,
|
||||
head: H256,
|
||||
) -> Vec<SealedHeader> {
|
||||
let mut headers = Vec::with_capacity(range.end.saturating_sub(range.start) as usize);
|
||||
for idx in range {
|
||||
headers.push(random_header(
|
||||
rng,
|
||||
idx,
|
||||
Some(headers.last().map(|h: &SealedHeader| h.hash()).unwrap_or(head)),
|
||||
));
|
||||
@ -34,11 +56,11 @@ pub fn random_header_range(rng: std::ops::Range<u64>, head: H256) -> Vec<SealedH
|
||||
/// Generate a random [SealedHeader].
|
||||
///
|
||||
/// The header is assumed to not be correct if validated.
|
||||
pub fn random_header(number: u64, parent: Option<H256>) -> SealedHeader {
|
||||
pub fn random_header<R: Rng>(rng: &mut R, number: u64, parent: Option<H256>) -> SealedHeader {
|
||||
let header = reth_primitives::Header {
|
||||
number,
|
||||
nonce: rand::random(),
|
||||
difficulty: U256::from(rand::random::<u32>()),
|
||||
nonce: rng.gen(),
|
||||
difficulty: U256::from(rng.gen::<u32>()),
|
||||
parent_hash: parent.unwrap_or_default(),
|
||||
..Default::default()
|
||||
};
|
||||
@ -51,14 +73,14 @@ pub fn random_header(number: u64, parent: Option<H256>) -> SealedHeader {
|
||||
///
|
||||
/// - The chain ID, which is always 1
|
||||
/// - The input, which is always nothing
|
||||
pub fn random_tx() -> Transaction {
|
||||
pub fn random_tx<R: Rng>(rng: &mut R) -> Transaction {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(1),
|
||||
nonce: rand::random::<u16>().into(),
|
||||
gas_price: rand::random::<u16>().into(),
|
||||
gas_limit: rand::random::<u16>().into(),
|
||||
nonce: rng.gen::<u16>().into(),
|
||||
gas_price: rng.gen::<u16>().into(),
|
||||
gas_limit: rng.gen::<u16>().into(),
|
||||
to: TransactionKind::Call(Address::random()),
|
||||
value: rand::random::<u16>().into(),
|
||||
value: rng.gen::<u16>().into(),
|
||||
input: Bytes::default(),
|
||||
})
|
||||
}
|
||||
@ -68,10 +90,10 @@ pub fn random_tx() -> Transaction {
|
||||
/// On top of the considerations of [random_tx], these apply as well:
|
||||
///
|
||||
/// - There is no guarantee that the nonce is not used twice for the same account
|
||||
pub fn random_signed_tx() -> TransactionSigned {
|
||||
pub fn random_signed_tx<R: Rng>(rng: &mut R) -> TransactionSigned {
|
||||
let secp = Secp256k1::new();
|
||||
let key_pair = KeyPair::new(&secp, &mut rand::thread_rng());
|
||||
let tx = random_tx();
|
||||
let key_pair = KeyPair::new(&secp, rng);
|
||||
let tx = random_tx(rng);
|
||||
sign_tx_with_key_pair(key_pair, tx)
|
||||
}
|
||||
|
||||
@ -96,23 +118,23 @@ pub fn sign_tx_with_key_pair(key_pair: KeyPair, tx: Transaction) -> TransactionS
|
||||
/// transactions in the block.
|
||||
///
|
||||
/// The ommer headers are not assumed to be valid.
|
||||
pub fn random_block(
|
||||
pub fn random_block<R: Rng>(
|
||||
rng: &mut R,
|
||||
number: u64,
|
||||
parent: Option<H256>,
|
||||
tx_count: Option<u8>,
|
||||
ommers_count: Option<u8>,
|
||||
) -> SealedBlock {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// Generate transactions
|
||||
let tx_count = tx_count.unwrap_or_else(|| rng.gen::<u8>());
|
||||
let transactions: Vec<TransactionSigned> = (0..tx_count).map(|_| random_signed_tx()).collect();
|
||||
let transactions: Vec<TransactionSigned> =
|
||||
(0..tx_count).map(|_| random_signed_tx(rng)).collect();
|
||||
let total_gas = transactions.iter().fold(0, |sum, tx| sum + tx.transaction.gas_limit());
|
||||
|
||||
// Generate ommers
|
||||
let ommers_count = ommers_count.unwrap_or_else(|| rng.gen_range(0..2));
|
||||
let ommers =
|
||||
(0..ommers_count).map(|_| random_header(number, parent).unseal()).collect::<Vec<_>>();
|
||||
(0..ommers_count).map(|_| random_header(rng, number, parent).unseal()).collect::<Vec<_>>();
|
||||
|
||||
// Calculate roots
|
||||
let transactions_root = proofs::calculate_transaction_root(&transactions);
|
||||
@ -142,19 +164,21 @@ pub fn random_block(
|
||||
/// in the result will be equal to `head`.
|
||||
///
|
||||
/// See [random_block] for considerations when validating the generated blocks.
|
||||
pub fn random_block_range(
|
||||
pub fn random_block_range<R: Rng>(
|
||||
rng: &mut R,
|
||||
block_numbers: RangeInclusive<BlockNumber>,
|
||||
head: H256,
|
||||
tx_count: Range<u8>,
|
||||
) -> Vec<SealedBlock> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut blocks =
|
||||
Vec::with_capacity(block_numbers.end().saturating_sub(*block_numbers.start()) as usize);
|
||||
for idx in block_numbers {
|
||||
let tx_count = tx_count.clone().sample_single(rng);
|
||||
blocks.push(random_block(
|
||||
rng,
|
||||
idx,
|
||||
Some(blocks.last().map(|block: &SealedBlock| block.header.hash()).unwrap_or(head)),
|
||||
Some(tx_count.clone().sample_single(&mut rng)),
|
||||
Some(tx_count),
|
||||
None,
|
||||
));
|
||||
}
|
||||
@ -169,7 +193,8 @@ type AccountState = (Account, Vec<StorageEntry>);
|
||||
///
|
||||
/// Returns a Vec of account and storage changes for each transition,
|
||||
/// along with the final state of all accounts and storages.
|
||||
pub fn random_transition_range<'a, IBlk, IAcc>(
|
||||
pub fn random_transition_range<'a, R: Rng, IBlk, IAcc>(
|
||||
rng: &mut R,
|
||||
blocks: IBlk,
|
||||
accounts: IAcc,
|
||||
n_changes: std::ops::Range<u64>,
|
||||
@ -179,7 +204,6 @@ where
|
||||
IBlk: IntoIterator<Item = &'a SealedBlock>,
|
||||
IAcc: IntoIterator<Item = (Address, (Account, Vec<StorageEntry>))>,
|
||||
{
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut state: BTreeMap<_, _> = accounts
|
||||
.into_iter()
|
||||
.map(|(addr, (acc, st))| (addr, (acc, st.into_iter().map(|e| (e.key, e.value)).collect())))
|
||||
@ -192,7 +216,7 @@ where
|
||||
blocks.into_iter().for_each(|block| {
|
||||
let mut transition = Vec::new();
|
||||
let (from, to, mut transfer, new_entries) =
|
||||
random_account_change(&valid_addresses, n_changes.clone(), key_range.clone());
|
||||
random_account_change(rng, &valid_addresses, n_changes.clone(), key_range.clone());
|
||||
|
||||
// extract from sending account
|
||||
let (prev_from, _) = state.get_mut(&from).unwrap();
|
||||
@ -239,61 +263,63 @@ where
|
||||
/// Generate a random account change.
|
||||
///
|
||||
/// Returns two addresses, a balance_change, and a Vec of new storage entries.
|
||||
pub fn random_account_change(
|
||||
pub fn random_account_change<R: Rng>(
|
||||
rng: &mut R,
|
||||
valid_addresses: &Vec<Address>,
|
||||
n_changes: std::ops::Range<u64>,
|
||||
key_range: std::ops::Range<u64>,
|
||||
) -> (Address, Address, U256, Vec<StorageEntry>) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut addresses = valid_addresses.choose_multiple(&mut rng, 2).cloned();
|
||||
let mut addresses = valid_addresses.choose_multiple(rng, 2).cloned();
|
||||
|
||||
let addr_from = addresses.next().unwrap_or_else(Address::random);
|
||||
let addr_to = addresses.next().unwrap_or_else(Address::random);
|
||||
|
||||
let balance_change = U256::from(rng.gen::<u64>());
|
||||
|
||||
let storage_changes = (0..n_changes.sample_single(&mut rng))
|
||||
.map(|_| random_storage_entry(key_range.clone()))
|
||||
let storage_changes = (0..n_changes.sample_single(rng))
|
||||
.map(|_| random_storage_entry(rng, key_range.clone()))
|
||||
.collect();
|
||||
|
||||
(addr_from, addr_to, balance_change, storage_changes)
|
||||
}
|
||||
|
||||
/// Generate a random storage change.
|
||||
pub fn random_storage_entry(key_range: std::ops::Range<u64>) -> StorageEntry {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let key = H256::from_low_u64_be(key_range.sample_single(&mut rng));
|
||||
pub fn random_storage_entry<R: Rng>(rng: &mut R, key_range: std::ops::Range<u64>) -> StorageEntry {
|
||||
let key = H256::from_low_u64_be(key_range.sample_single(rng));
|
||||
let value = U256::from(rng.gen::<u64>());
|
||||
|
||||
StorageEntry { key, value }
|
||||
}
|
||||
|
||||
/// Generate random Externally Owned Account (EOA account without contract).
|
||||
pub fn random_eoa_account() -> (Address, Account) {
|
||||
let nonce: u64 = rand::random();
|
||||
let balance = U256::from(rand::random::<u32>());
|
||||
let addr = H160::from(rand::random::<u64>());
|
||||
pub fn random_eoa_account<R: Rng>(rng: &mut R) -> (Address, Account) {
|
||||
let nonce: u64 = rng.gen();
|
||||
let balance = U256::from(rng.gen::<u32>());
|
||||
let addr = H160::from(rng.gen::<u64>());
|
||||
|
||||
(addr, Account { nonce, balance, bytecode_hash: None })
|
||||
}
|
||||
|
||||
/// Generate random Externally Owned Accounts
|
||||
pub fn random_eoa_account_range(acc_range: std::ops::Range<u64>) -> Vec<(Address, Account)> {
|
||||
pub fn random_eoa_account_range<R: Rng>(
|
||||
rng: &mut R,
|
||||
acc_range: std::ops::Range<u64>,
|
||||
) -> Vec<(Address, Account)> {
|
||||
let mut accounts = Vec::with_capacity(acc_range.end.saturating_sub(acc_range.start) as usize);
|
||||
for _ in acc_range {
|
||||
accounts.push(random_eoa_account())
|
||||
accounts.push(random_eoa_account(rng))
|
||||
}
|
||||
accounts
|
||||
}
|
||||
|
||||
/// Generate random Contract Accounts
|
||||
pub fn random_contract_account_range(
|
||||
pub fn random_contract_account_range<R: Rng>(
|
||||
rng: &mut R,
|
||||
acc_range: &mut std::ops::Range<u64>,
|
||||
) -> Vec<(Address, Account)> {
|
||||
let mut accounts = Vec::with_capacity(acc_range.end.saturating_sub(acc_range.start) as usize);
|
||||
for _ in acc_range {
|
||||
let (address, eoa_account) = random_eoa_account();
|
||||
let (address, eoa_account) = random_eoa_account(rng);
|
||||
let account = Account { bytecode_hash: Some(H256::random()), ..eoa_account };
|
||||
accounts.push((address, account))
|
||||
}
|
||||
|
||||
@ -595,7 +595,7 @@ mod tests {
|
||||
use assert_matches::assert_matches;
|
||||
use futures_util::stream::StreamExt;
|
||||
use reth_db::mdbx::{test_utils::create_test_db, EnvKind, WriteMap};
|
||||
use reth_interfaces::test_utils::{generators::random_block_range, TestConsensus};
|
||||
use reth_interfaces::test_utils::{generators, generators::random_block_range, TestConsensus};
|
||||
use reth_primitives::{BlockBody, H256};
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
@ -632,7 +632,8 @@ mod tests {
|
||||
async fn requests_correct_number_of_times() {
|
||||
// Generate some random blocks
|
||||
let db = create_test_db::<WriteMap>(EnvKind::RW);
|
||||
let blocks = random_block_range(0..=199, H256::zero(), 1..2);
|
||||
let mut rng = generators::rng();
|
||||
let blocks = random_block_range(&mut rng, 0..=199, H256::zero(), 1..2);
|
||||
|
||||
let headers = blocks.iter().map(|block| block.header.clone()).collect::<Vec<_>>();
|
||||
let bodies = blocks
|
||||
|
||||
@ -239,7 +239,7 @@ mod tests {
|
||||
};
|
||||
use reth_interfaces::{
|
||||
p2p::bodies::response::BlockResponse,
|
||||
test_utils::{generators::random_header_range, TestConsensus},
|
||||
test_utils::{generators, generators::random_header_range, TestConsensus},
|
||||
};
|
||||
use reth_primitives::H256;
|
||||
use std::sync::Arc;
|
||||
@ -247,7 +247,8 @@ mod tests {
|
||||
/// Check if future returns empty bodies without dispathing any requests.
|
||||
#[tokio::test]
|
||||
async fn request_returns_empty_bodies() {
|
||||
let headers = random_header_range(0..20, H256::zero());
|
||||
let mut rng = generators::rng();
|
||||
let headers = random_header_range(&mut rng, 0..20, H256::zero());
|
||||
|
||||
let client = Arc::new(TestBodiesClient::default());
|
||||
let fut = BodiesRequestFuture::new(
|
||||
|
||||
@ -18,15 +18,17 @@ mod file_codec;
|
||||
pub use bodies_client::TestBodiesClient;
|
||||
pub use file_client::{FileClient, FileClientError};
|
||||
pub(crate) use file_codec::BlockFileCodec;
|
||||
use reth_interfaces::test_utils::generators;
|
||||
|
||||
/// Metrics scope used for testing.
|
||||
pub(crate) const TEST_SCOPE: &str = "downloaders.test";
|
||||
|
||||
/// Generate a set of bodies and their corresponding block hashes
|
||||
pub(crate) fn generate_bodies(
|
||||
rng: RangeInclusive<u64>,
|
||||
range: RangeInclusive<u64>,
|
||||
) -> (Vec<SealedHeader>, HashMap<H256, BlockBody>) {
|
||||
let blocks = random_block_range(rng, H256::zero(), 0..2);
|
||||
let mut rng = generators::rng();
|
||||
let blocks = random_block_range(&mut rng, range, H256::zero(), 0..2);
|
||||
|
||||
let headers = blocks.iter().map(|block| block.header.clone()).collect();
|
||||
let bodies = blocks
|
||||
|
||||
@ -476,7 +476,7 @@ mod tests {
|
||||
// tests covering `engine_getPayloadBodiesByRange` and `engine_getPayloadBodiesByHash`
|
||||
mod get_payload_bodies {
|
||||
use super::*;
|
||||
use reth_interfaces::test_utils::generators::random_block_range;
|
||||
use reth_interfaces::test_utils::{generators, generators::random_block_range};
|
||||
|
||||
#[tokio::test]
|
||||
async fn invalid_params() {
|
||||
@ -507,10 +507,12 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_payload_bodies() {
|
||||
let mut rng = generators::rng();
|
||||
let (handle, api) = setup_engine_api();
|
||||
|
||||
let (start, count) = (1, 10);
|
||||
let blocks = random_block_range(start..=start + count - 1, H256::default(), 0..2);
|
||||
let blocks =
|
||||
random_block_range(&mut rng, start..=start + count - 1, H256::default(), 0..2);
|
||||
handle.provider.extend_blocks(blocks.iter().cloned().map(|b| (b.hash(), b.unseal())));
|
||||
|
||||
let expected =
|
||||
@ -522,10 +524,12 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_payload_bodies_with_gaps() {
|
||||
let mut rng = generators::rng();
|
||||
let (handle, api) = setup_engine_api();
|
||||
|
||||
let (start, count) = (1, 100);
|
||||
let blocks = random_block_range(start..=start + count - 1, H256::default(), 0..2);
|
||||
let blocks =
|
||||
random_block_range(&mut rng, start..=start + count - 1, H256::default(), 0..2);
|
||||
|
||||
// Insert only blocks in ranges 1-25 and 50-75
|
||||
let first_missing_range = 26..=50;
|
||||
@ -566,6 +570,7 @@ mod tests {
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#specification-3
|
||||
mod exchange_transition_configuration {
|
||||
use super::*;
|
||||
use reth_interfaces::test_utils::generators;
|
||||
use reth_primitives::U256;
|
||||
|
||||
#[tokio::test]
|
||||
@ -589,11 +594,15 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn terminal_block_hash_mismatch() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let (handle, api) = setup_engine_api();
|
||||
|
||||
let terminal_block_number = 1000;
|
||||
let consensus_terminal_block = random_block(terminal_block_number, None, None, None);
|
||||
let execution_terminal_block = random_block(terminal_block_number, None, None, None);
|
||||
let consensus_terminal_block =
|
||||
random_block(&mut rng, terminal_block_number, None, None, None);
|
||||
let execution_terminal_block =
|
||||
random_block(&mut rng, terminal_block_number, None, None, None);
|
||||
|
||||
let transition_config = TransitionConfiguration {
|
||||
terminal_total_difficulty: handle.chain_spec.fork(Hardfork::Paris).ttd().unwrap(),
|
||||
@ -630,7 +639,8 @@ mod tests {
|
||||
let (handle, api) = setup_engine_api();
|
||||
|
||||
let terminal_block_number = 1000;
|
||||
let terminal_block = random_block(terminal_block_number, None, None, None);
|
||||
let terminal_block =
|
||||
random_block(&mut generators::rng(), terminal_block_number, None, None, None);
|
||||
|
||||
let transition_config = TransitionConfiguration {
|
||||
terminal_total_difficulty: handle.chain_spec.fork(Hardfork::Paris).ttd().unwrap(),
|
||||
|
||||
@ -427,7 +427,7 @@ mod tests {
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
random_block, random_block_range, random_header,
|
||||
self, random_block, random_block_range, random_header,
|
||||
};
|
||||
use reth_primitives::{
|
||||
bytes::{Bytes, BytesMut},
|
||||
@ -453,7 +453,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn payload_body_roundtrip() {
|
||||
for block in random_block_range(0..=99, H256::default(), 0..2) {
|
||||
let mut rng = generators::rng();
|
||||
for block in random_block_range(&mut rng, 0..=99, H256::default(), 0..2) {
|
||||
let unsealed = block.clone().unseal();
|
||||
let payload_body: ExecutionPayloadBody = unsealed.into();
|
||||
|
||||
@ -472,7 +473,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn payload_validation() {
|
||||
let block = random_block(100, Some(H256::random()), Some(3), Some(0));
|
||||
let mut rng = generators::rng();
|
||||
let block = random_block(&mut rng, 100, Some(H256::random()), Some(3), Some(0));
|
||||
|
||||
// Valid extra data
|
||||
let block_with_valid_extra_data = transform_block(block.clone(), |mut b| {
|
||||
@ -514,7 +516,7 @@ mod tests {
|
||||
|
||||
// Non empty ommers
|
||||
let block_with_ommers = transform_block(block.clone(), |mut b| {
|
||||
b.ommers.push(random_header(100, None).unseal());
|
||||
b.ommers.push(random_header(&mut rng, 100, None).unseal());
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
|
||||
@ -5,9 +5,12 @@ use reth_db::{
|
||||
tables,
|
||||
transaction::{DbTx, DbTxMut},
|
||||
};
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
random_block_range, random_contract_account_range, random_eoa_account_range,
|
||||
random_transition_range,
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{
|
||||
random_block_range, random_contract_account_range, random_eoa_account_range,
|
||||
random_transition_range,
|
||||
},
|
||||
};
|
||||
use reth_primitives::{Account, Address, SealedBlock, H256, MAINNET};
|
||||
use reth_provider::ProviderFactory;
|
||||
@ -98,6 +101,9 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> PathBuf {
|
||||
let n_eoa = 131;
|
||||
let n_contract = 31;
|
||||
|
||||
// rng
|
||||
let mut rng = generators::rng();
|
||||
|
||||
if !path.exists() {
|
||||
// create the dirs
|
||||
std::fs::create_dir_all(&path).unwrap();
|
||||
@ -105,15 +111,16 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> PathBuf {
|
||||
let tx = TestTransaction::new(&path);
|
||||
|
||||
let accounts: BTreeMap<Address, Account> = concat([
|
||||
random_eoa_account_range(0..n_eoa),
|
||||
random_contract_account_range(&mut (0..n_contract)),
|
||||
random_eoa_account_range(&mut rng, 0..n_eoa),
|
||||
random_contract_account_range(&mut rng, &mut (0..n_contract)),
|
||||
])
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let mut blocks = random_block_range(0..=num_blocks, H256::zero(), txs_range);
|
||||
let mut blocks = random_block_range(&mut rng, 0..=num_blocks, H256::zero(), txs_range);
|
||||
|
||||
let (transitions, start_state) = random_transition_range(
|
||||
&mut rng,
|
||||
blocks.iter().take(2),
|
||||
accounts.into_iter().map(|(addr, acc)| (addr, (acc, Vec::new()))),
|
||||
n_changes.clone(),
|
||||
@ -135,8 +142,13 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> PathBuf {
|
||||
tx.insert_transitions(transitions, None).unwrap();
|
||||
tx.commit(|tx| updates.flush(tx)).unwrap();
|
||||
|
||||
let (transitions, final_state) =
|
||||
random_transition_range(blocks.iter().skip(2), start_state, n_changes, key_range);
|
||||
let (transitions, final_state) = random_transition_range(
|
||||
&mut rng,
|
||||
blocks.iter().skip(2),
|
||||
start_state,
|
||||
n_changes,
|
||||
key_range,
|
||||
);
|
||||
|
||||
tx.insert_transitions(transitions, Some(offset)).unwrap();
|
||||
|
||||
|
||||
@ -482,7 +482,9 @@ mod tests {
|
||||
use assert_matches::assert_matches;
|
||||
use reth_db::mdbx::{self, test_utils, EnvKind};
|
||||
use reth_interfaces::{
|
||||
consensus, provider::ProviderError, test_utils::generators::random_header,
|
||||
consensus,
|
||||
provider::ProviderError,
|
||||
test_utils::{generators, generators::random_header},
|
||||
};
|
||||
use reth_primitives::{stage::StageCheckpoint, MAINNET};
|
||||
use tokio_stream::StreamExt;
|
||||
@ -787,7 +789,7 @@ mod tests {
|
||||
.add_stage(
|
||||
TestStage::new(StageId::Other("B"))
|
||||
.add_exec(Err(StageError::Validation {
|
||||
block: random_header(5, Default::default()),
|
||||
block: random_header(&mut generators::rng(), 5, Default::default()),
|
||||
error: consensus::ConsensusError::BaseFeeMissing,
|
||||
}))
|
||||
.add_unwind(Ok(UnwindOutput { checkpoint: StageCheckpoint::new(0) }))
|
||||
|
||||
@ -473,6 +473,7 @@ mod tests {
|
||||
priority::Priority,
|
||||
},
|
||||
test_utils::{
|
||||
generators,
|
||||
generators::{random_block_range, random_signed_tx},
|
||||
TestConsensus,
|
||||
},
|
||||
@ -556,7 +557,8 @@ mod tests {
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let start = input.checkpoint().block_number;
|
||||
let end = input.target();
|
||||
let blocks = random_block_range(start..=end, GENESIS_HASH, 0..2);
|
||||
let mut rng = generators::rng();
|
||||
let blocks = random_block_range(&mut rng, start..=end, GENESIS_HASH, 0..2);
|
||||
self.tx.insert_headers_with_td(blocks.iter().map(|block| &block.header))?;
|
||||
if let Some(progress) = blocks.first() {
|
||||
// Insert last progress data
|
||||
@ -566,7 +568,7 @@ mod tests {
|
||||
tx_count: progress.body.len() as u64,
|
||||
};
|
||||
body.tx_num_range().try_for_each(|tx_num| {
|
||||
let transaction = random_signed_tx();
|
||||
let transaction = random_signed_tx(&mut rng);
|
||||
tx.put::<tables::Transactions>(tx_num, transaction.into())
|
||||
})?;
|
||||
|
||||
|
||||
@ -40,7 +40,10 @@ mod tests {
|
||||
stage_test_suite_ext, ExecuteStageTestRunner, StageTestRunner, TestRunnerError,
|
||||
TestTransaction, UnwindStageTestRunner,
|
||||
};
|
||||
use reth_interfaces::test_utils::generators::{random_header, random_header_range};
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{random_header, random_header_range},
|
||||
};
|
||||
use reth_primitives::SealedHeader;
|
||||
|
||||
stage_test_suite_ext!(FinishTestRunner, finish);
|
||||
@ -67,7 +70,8 @@ mod tests {
|
||||
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let start = input.checkpoint().block_number;
|
||||
let head = random_header(start, None);
|
||||
let mut rng = generators::rng();
|
||||
let head = random_header(&mut rng, start, None);
|
||||
self.tx.insert_headers_with_td(std::iter::once(&head))?;
|
||||
|
||||
// use previous progress as seed size
|
||||
@ -77,7 +81,7 @@ mod tests {
|
||||
return Ok(Vec::default())
|
||||
}
|
||||
|
||||
let mut headers = random_header_range(start + 1..end, head.hash());
|
||||
let mut headers = random_header_range(&mut rng, start + 1..end, head.hash());
|
||||
self.tx.insert_headers_with_td(headers.iter())?;
|
||||
headers.insert(0, head);
|
||||
Ok(headers)
|
||||
|
||||
@ -83,18 +83,21 @@ impl AccountHashingStage {
|
||||
opts: SeedOpts,
|
||||
) -> Result<Vec<(reth_primitives::Address, reth_primitives::Account)>, StageError> {
|
||||
use reth_db::models::AccountBeforeTx;
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
random_block_range, random_eoa_account_range,
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{random_block_range, random_eoa_account_range},
|
||||
};
|
||||
use reth_primitives::{Account, H256, U256};
|
||||
use reth_provider::insert_canonical_block;
|
||||
|
||||
let blocks = random_block_range(opts.blocks.clone(), H256::zero(), opts.txs);
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let blocks = random_block_range(&mut rng, opts.blocks.clone(), H256::zero(), opts.txs);
|
||||
|
||||
for block in blocks {
|
||||
insert_canonical_block(provider.tx_ref(), block, None).unwrap();
|
||||
}
|
||||
let mut accounts = random_eoa_account_range(opts.accounts);
|
||||
let mut accounts = random_eoa_account_range(&mut rng, opts.accounts);
|
||||
{
|
||||
// Account State generator
|
||||
let mut account_cursor =
|
||||
|
||||
@ -231,13 +231,15 @@ mod tests {
|
||||
TestTransaction, UnwindStageTestRunner,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use rand::Rng;
|
||||
use reth_db::{
|
||||
cursor::{DbCursorRO, DbCursorRW},
|
||||
mdbx::{tx::Tx, WriteMap, RW},
|
||||
models::{BlockNumberAddress, StoredBlockBodyIndices},
|
||||
};
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
random_block_range, random_contract_account_range,
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{random_block_range, random_contract_account_range},
|
||||
};
|
||||
use reth_primitives::{
|
||||
stage::StageUnitCheckpoint, Address, SealedBlock, StorageEntry, H256, U256,
|
||||
@ -487,11 +489,12 @@ mod tests {
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let stage_progress = input.next_block();
|
||||
let end = input.target();
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let n_accounts = 31;
|
||||
let mut accounts = random_contract_account_range(&mut (0..n_accounts));
|
||||
let mut accounts = random_contract_account_range(&mut rng, &mut (0..n_accounts));
|
||||
|
||||
let blocks = random_block_range(stage_progress..=end, H256::zero(), 0..3);
|
||||
let blocks = random_block_range(&mut rng, stage_progress..=end, H256::zero(), 0..3);
|
||||
|
||||
self.tx.insert_headers(blocks.iter().map(|block| &block.header))?;
|
||||
|
||||
@ -510,14 +513,13 @@ mod tests {
|
||||
transaction.clone().into(),
|
||||
)?;
|
||||
|
||||
let (addr, _) = accounts
|
||||
.get_mut(rand::random::<usize>() % n_accounts as usize)
|
||||
.unwrap();
|
||||
let (addr, _) =
|
||||
accounts.get_mut(rng.gen::<usize>() % n_accounts as usize).unwrap();
|
||||
|
||||
for _ in 0..2 {
|
||||
let new_entry = StorageEntry {
|
||||
key: keccak256([rand::random::<u8>()]),
|
||||
value: U256::from(rand::random::<u8>() % 30 + 1),
|
||||
key: keccak256([rng.gen::<u8>()]),
|
||||
value: U256::from(rng.gen::<u8>() % 30 + 1),
|
||||
};
|
||||
self.insert_storage_entry(
|
||||
tx,
|
||||
@ -533,14 +535,14 @@ mod tests {
|
||||
)?;
|
||||
|
||||
// Randomize rewards
|
||||
let has_reward: bool = rand::random();
|
||||
let has_reward: bool = rng.gen();
|
||||
if has_reward {
|
||||
self.insert_storage_entry(
|
||||
tx,
|
||||
(block_number, Address::random()).into(),
|
||||
StorageEntry {
|
||||
key: keccak256("mining"),
|
||||
value: U256::from(rand::random::<u32>()),
|
||||
value: U256::from(rng.gen::<u32>()),
|
||||
},
|
||||
progress.header.number == stage_progress,
|
||||
)?;
|
||||
|
||||
@ -388,7 +388,7 @@ mod tests {
|
||||
stage_test_suite, ExecuteStageTestRunner, StageTestRunner, UnwindStageTestRunner,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use reth_interfaces::test_utils::generators::random_header;
|
||||
use reth_interfaces::test_utils::{generators, generators::random_header};
|
||||
use reth_primitives::{stage::StageUnitCheckpoint, H256, MAINNET};
|
||||
use reth_provider::ProviderFactory;
|
||||
use test_runner::HeadersTestRunner;
|
||||
@ -400,7 +400,8 @@ mod tests {
|
||||
ReverseHeadersDownloader, ReverseHeadersDownloaderBuilder,
|
||||
};
|
||||
use reth_interfaces::test_utils::{
|
||||
generators::random_header_range, TestConsensus, TestHeaderDownloader, TestHeadersClient,
|
||||
generators, generators::random_header_range, TestConsensus, TestHeaderDownloader,
|
||||
TestHeadersClient,
|
||||
};
|
||||
use reth_primitives::U256;
|
||||
use reth_provider::{BlockHashProvider, BlockNumProvider, HeaderProvider};
|
||||
@ -452,8 +453,9 @@ mod tests {
|
||||
type Seed = Vec<SealedHeader>;
|
||||
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let mut rng = generators::rng();
|
||||
let start = input.checkpoint().block_number;
|
||||
let head = random_header(start, None);
|
||||
let head = random_header(&mut rng, start, None);
|
||||
self.tx.insert_headers(std::iter::once(&head))?;
|
||||
// patch td table for `update_head` call
|
||||
self.tx.commit(|tx| tx.put::<tables::HeaderTD>(head.number, U256::ZERO.into()))?;
|
||||
@ -465,7 +467,7 @@ mod tests {
|
||||
return Ok(Vec::default())
|
||||
}
|
||||
|
||||
let mut headers = random_header_range(start + 1..end, head.hash());
|
||||
let mut headers = random_header_range(&mut rng, start + 1..end, head.hash());
|
||||
headers.insert(0, head);
|
||||
Ok(headers)
|
||||
}
|
||||
@ -505,7 +507,7 @@ mod tests {
|
||||
let tip = if !headers.is_empty() {
|
||||
headers.last().unwrap().hash()
|
||||
} else {
|
||||
let tip = random_header(0, None);
|
||||
let tip = random_header(&mut generators::rng(), 0, None);
|
||||
self.tx.insert_headers(std::iter::once(&tip))?;
|
||||
tip.hash()
|
||||
};
|
||||
@ -603,14 +605,16 @@ mod tests {
|
||||
let tx = provider.tx_ref();
|
||||
let mut stage = runner.stage();
|
||||
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let consensus_tip = H256::random();
|
||||
runner.send_tip(consensus_tip);
|
||||
|
||||
// Genesis
|
||||
let checkpoint = 0;
|
||||
let head = random_header(0, None);
|
||||
let gap_fill = random_header(1, Some(head.hash()));
|
||||
let gap_tip = random_header(2, Some(gap_fill.hash()));
|
||||
let head = random_header(&mut rng, 0, None);
|
||||
let gap_fill = random_header(&mut rng, 1, Some(head.hash()));
|
||||
let gap_tip = random_header(&mut rng, 2, Some(gap_fill.hash()));
|
||||
|
||||
// Empty database
|
||||
assert_matches!(
|
||||
|
||||
@ -346,8 +346,12 @@ mod tests {
|
||||
tables,
|
||||
transaction::{DbTx, DbTxMut},
|
||||
};
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
random_block, random_block_range, random_contract_account_range, random_transition_range,
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{
|
||||
random_block, random_block_range, random_contract_account_range,
|
||||
random_transition_range,
|
||||
},
|
||||
};
|
||||
use reth_primitives::{
|
||||
keccak256, stage::StageUnitCheckpoint, SealedBlock, StorageEntry, H256, U256,
|
||||
@ -469,9 +473,10 @@ mod tests {
|
||||
let stage_progress = input.checkpoint().block_number;
|
||||
let start = stage_progress + 1;
|
||||
let end = input.target();
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let num_of_accounts = 31;
|
||||
let accounts = random_contract_account_range(&mut (0..num_of_accounts))
|
||||
let accounts = random_contract_account_range(&mut rng, &mut (0..num_of_accounts))
|
||||
.into_iter()
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
@ -480,7 +485,7 @@ mod tests {
|
||||
)?;
|
||||
|
||||
let SealedBlock { header, body, ommers, withdrawals } =
|
||||
random_block(stage_progress, None, Some(0), None);
|
||||
random_block(&mut rng, stage_progress, None, Some(0), None);
|
||||
let mut header = header.unseal();
|
||||
|
||||
header.state_root = state_root(
|
||||
@ -493,10 +498,11 @@ mod tests {
|
||||
|
||||
let head_hash = sealed_head.hash();
|
||||
let mut blocks = vec![sealed_head];
|
||||
blocks.extend(random_block_range(start..=end, head_hash, 0..3));
|
||||
blocks.extend(random_block_range(&mut rng, start..=end, head_hash, 0..3));
|
||||
self.tx.insert_blocks(blocks.iter(), None)?;
|
||||
|
||||
let (transitions, final_state) = random_transition_range(
|
||||
&mut rng,
|
||||
blocks.iter(),
|
||||
accounts.into_iter().map(|(addr, acc)| (addr, (acc, Vec::new()))),
|
||||
0..3,
|
||||
|
||||
@ -231,7 +231,10 @@ struct FailedSenderRecoveryError {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use assert_matches::assert_matches;
|
||||
use reth_interfaces::test_utils::generators::{random_block, random_block_range};
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{random_block, random_block_range},
|
||||
};
|
||||
use reth_primitives::{
|
||||
stage::StageUnitCheckpoint, BlockNumber, SealedBlock, TransactionSigned, H256,
|
||||
};
|
||||
@ -249,6 +252,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn execute_single_transaction() {
|
||||
let (previous_stage, stage_progress) = (500, 100);
|
||||
let mut rng = generators::rng();
|
||||
|
||||
// Set up the runner
|
||||
let runner = SenderRecoveryTestRunner::default();
|
||||
@ -261,7 +265,13 @@ mod tests {
|
||||
let non_empty_block_number = stage_progress + 10;
|
||||
let blocks = (stage_progress..=input.target())
|
||||
.map(|number| {
|
||||
random_block(number, None, Some((number == non_empty_block_number) as u8), None)
|
||||
random_block(
|
||||
&mut rng,
|
||||
number,
|
||||
None,
|
||||
Some((number == non_empty_block_number) as u8),
|
||||
None,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
runner.tx.insert_blocks(blocks.iter(), None).expect("failed to insert blocks");
|
||||
@ -288,13 +298,16 @@ mod tests {
|
||||
/// Execute the stage twice with input range that exceeds the commit threshold
|
||||
#[tokio::test]
|
||||
async fn execute_intermediate_commit() {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let threshold = 10;
|
||||
let mut runner = SenderRecoveryTestRunner::default();
|
||||
runner.set_threshold(threshold);
|
||||
let (stage_progress, previous_stage) = (1000, 1100); // input exceeds threshold
|
||||
|
||||
// Manually seed once with full input range
|
||||
let seed = random_block_range(stage_progress + 1..=previous_stage, H256::zero(), 0..4); // set tx count range high enough to hit the threshold
|
||||
let seed =
|
||||
random_block_range(&mut rng, stage_progress + 1..=previous_stage, H256::zero(), 0..4); // set tx count range high enough to hit the threshold
|
||||
runner.tx.insert_blocks(seed.iter(), None).expect("failed to seed execution");
|
||||
|
||||
let total_transactions = runner.tx.table::<tables::Transactions>().unwrap().len() as u64;
|
||||
@ -403,10 +416,11 @@ mod tests {
|
||||
type Seed = Vec<SealedBlock>;
|
||||
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let mut rng = generators::rng();
|
||||
let stage_progress = input.checkpoint().block_number;
|
||||
let end = input.target();
|
||||
|
||||
let blocks = random_block_range(stage_progress..=end, H256::zero(), 0..2);
|
||||
let blocks = random_block_range(&mut rng, stage_progress..=end, H256::zero(), 0..2);
|
||||
self.tx.insert_blocks(blocks.iter(), None)?;
|
||||
Ok(blocks)
|
||||
}
|
||||
|
||||
@ -126,6 +126,7 @@ mod tests {
|
||||
use assert_matches::assert_matches;
|
||||
use reth_db::transaction::DbTx;
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{random_header, random_header_range},
|
||||
TestConsensus,
|
||||
};
|
||||
@ -228,8 +229,9 @@ mod tests {
|
||||
type Seed = Vec<SealedHeader>;
|
||||
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let mut rng = generators::rng();
|
||||
let start = input.checkpoint().block_number;
|
||||
let head = random_header(start, None);
|
||||
let head = random_header(&mut rng, start, None);
|
||||
self.tx.insert_headers(std::iter::once(&head))?;
|
||||
self.tx.commit(|tx| {
|
||||
let td: U256 = tx
|
||||
@ -248,7 +250,7 @@ mod tests {
|
||||
return Ok(Vec::default())
|
||||
}
|
||||
|
||||
let mut headers = random_header_range(start + 1..end, head.hash());
|
||||
let mut headers = random_header_range(&mut rng, start + 1..end, head.hash());
|
||||
self.tx.insert_headers(headers.iter())?;
|
||||
headers.insert(0, head);
|
||||
Ok(headers)
|
||||
|
||||
@ -198,7 +198,10 @@ mod tests {
|
||||
TestTransaction, UnwindStageTestRunner,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use reth_interfaces::test_utils::generators::{random_block, random_block_range};
|
||||
use reth_interfaces::test_utils::{
|
||||
generators,
|
||||
generators::{random_block, random_block_range},
|
||||
};
|
||||
use reth_primitives::{stage::StageUnitCheckpoint, BlockNumber, SealedBlock, H256};
|
||||
use reth_provider::TransactionsProvider;
|
||||
|
||||
@ -208,6 +211,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn execute_single_transaction_lookup() {
|
||||
let (previous_stage, stage_progress) = (500, 100);
|
||||
let mut rng = generators::rng();
|
||||
|
||||
// Set up the runner
|
||||
let runner = TransactionLookupTestRunner::default();
|
||||
@ -220,7 +224,13 @@ mod tests {
|
||||
let non_empty_block_number = stage_progress + 10;
|
||||
let blocks = (stage_progress..=input.target())
|
||||
.map(|number| {
|
||||
random_block(number, None, Some((number == non_empty_block_number) as u8), None)
|
||||
random_block(
|
||||
&mut rng,
|
||||
number,
|
||||
None,
|
||||
Some((number == non_empty_block_number) as u8),
|
||||
None,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
runner.tx.insert_blocks(blocks.iter(), None).expect("failed to insert blocks");
|
||||
@ -256,9 +266,11 @@ mod tests {
|
||||
target: Some(previous_stage),
|
||||
checkpoint: Some(StageCheckpoint::new(stage_progress)),
|
||||
};
|
||||
let mut rng = generators::rng();
|
||||
|
||||
// Seed only once with full input range
|
||||
let seed = random_block_range(stage_progress + 1..=previous_stage, H256::zero(), 0..4); // set tx count range high enough to hit the threshold
|
||||
let seed =
|
||||
random_block_range(&mut rng, stage_progress + 1..=previous_stage, H256::zero(), 0..4); // set tx count range high enough to hit the threshold
|
||||
runner.tx.insert_blocks(seed.iter(), None).expect("failed to seed execution");
|
||||
|
||||
let total_txs = runner.tx.table::<tables::Transactions>().unwrap().len() as u64;
|
||||
@ -366,8 +378,9 @@ mod tests {
|
||||
fn seed_execution(&mut self, input: ExecInput) -> Result<Self::Seed, TestRunnerError> {
|
||||
let stage_progress = input.checkpoint().block_number;
|
||||
let end = input.target();
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let blocks = random_block_range(stage_progress + 1..=end, H256::zero(), 0..2);
|
||||
let blocks = random_block_range(&mut rng, stage_progress + 1..=end, H256::zero(), 0..2);
|
||||
self.tx.insert_blocks(blocks.iter(), None)?;
|
||||
Ok(blocks)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user