test: add support for seeded rng (#3270)

This commit is contained in:
Bjerg
2023-06-21 23:35:28 +02:00
committed by GitHub
parent 938b979703
commit dc74fad816
23 changed files with 323 additions and 175 deletions

View File

@ -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 }}

View File

@ -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 }}

View File

@ -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].

View File

@ -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);

View File

@ -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));

View File

@ -52,4 +52,4 @@ secp256k1 = { workspace = true, features = [
] }
[features]
test-utils = ["tokio-stream/sync", "secp256k1"]
test-utils = ["tokio-stream/sync", "secp256k1", "rand/std_rng"]

View File

@ -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))
}

View File

@ -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

View File

@ -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(

View File

@ -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

View File

@ -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(),

View File

@ -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!(

View File

@ -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();

View File

@ -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) }))

View File

@ -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())
})?;

View File

@ -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)

View File

@ -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 =

View File

@ -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,
)?;

View File

@ -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!(

View File

@ -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,

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}