mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: remove proptest arbitrary from codec derive and tests (#8968)
This commit is contained in:
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -5780,6 +5780,16 @@ dependencies = [
|
||||
"unarray",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proptest-arbitrary-interop"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1981e49bd2432249da8b0e11e5557099a8e74690d6b94e721f7dc0bb7f3555f"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"proptest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proptest-derive"
|
||||
version = "0.4.0"
|
||||
@ -6182,6 +6192,7 @@ dependencies = [
|
||||
"ahash",
|
||||
"alloy-rlp",
|
||||
"aquamarine",
|
||||
"arbitrary",
|
||||
"assert_matches",
|
||||
"backon",
|
||||
"boyer-moore-magiclen",
|
||||
@ -6199,6 +6210,7 @@ dependencies = [
|
||||
"libc",
|
||||
"metrics-process",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"rand 0.8.5",
|
||||
"ratatui",
|
||||
"rayon",
|
||||
@ -6492,6 +6504,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"modular-bitfield",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"reth-codecs-derive",
|
||||
"serde",
|
||||
@ -6621,6 +6634,7 @@ dependencies = [
|
||||
"paste",
|
||||
"pprof",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"rand 0.8.5",
|
||||
"reth-codecs",
|
||||
@ -6866,6 +6880,7 @@ dependencies = [
|
||||
"futures",
|
||||
"pin-project",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"rand 0.8.5",
|
||||
"reth-chainspec",
|
||||
@ -6900,6 +6915,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"derive_more",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"rand 0.8.5",
|
||||
"reth-chainspec",
|
||||
@ -7688,6 +7704,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"pprof",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"rand 0.8.5",
|
||||
"rayon",
|
||||
@ -7726,6 +7743,7 @@ dependencies = [
|
||||
"derive_more",
|
||||
"modular-bitfield",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"rand 0.8.5",
|
||||
"reth-codecs",
|
||||
@ -7818,6 +7836,7 @@ dependencies = [
|
||||
"derive_more",
|
||||
"modular-bitfield",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"reth-codecs",
|
||||
"serde",
|
||||
@ -8153,6 +8172,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"modular-bitfield",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"rand 0.8.5",
|
||||
"reth-codecs",
|
||||
@ -8285,6 +8305,7 @@ dependencies = [
|
||||
"paste",
|
||||
"pprof",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"rand 0.8.5",
|
||||
"reth-chainspec",
|
||||
"reth-eth-wire-types",
|
||||
@ -8319,6 +8340,7 @@ dependencies = [
|
||||
"metrics",
|
||||
"once_cell",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"rayon",
|
||||
"reth-chainspec",
|
||||
"reth-db",
|
||||
@ -8358,6 +8380,7 @@ dependencies = [
|
||||
"nybbles",
|
||||
"plain_hasher",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"proptest-derive",
|
||||
"reth-codecs",
|
||||
"reth-primitives-traits",
|
||||
@ -8378,6 +8401,7 @@ dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"metrics",
|
||||
"proptest",
|
||||
"proptest-arbitrary-interop",
|
||||
"rand 0.8.5",
|
||||
"rayon",
|
||||
"reth-db",
|
||||
|
||||
@ -468,6 +468,7 @@ jsonrpsee-http-client = "0.23"
|
||||
http = "1.0"
|
||||
http-body = "1.0"
|
||||
jsonwebtoken = "9"
|
||||
proptest-arbitrary-interop = "0.1.0"
|
||||
|
||||
# crypto
|
||||
secp256k1 = { version = "0.29", default-features = false, features = [
|
||||
|
||||
@ -86,6 +86,8 @@ metrics-process.workspace = true
|
||||
|
||||
# test vectors generation
|
||||
proptest.workspace = true
|
||||
arbitrary.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
rand.workspace = true
|
||||
|
||||
# tui
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use arbitrary::Arbitrary;
|
||||
use eyre::Result;
|
||||
use proptest::{
|
||||
arbitrary::Arbitrary,
|
||||
prelude::{any_with, ProptestConfig},
|
||||
prelude::ProptestConfig,
|
||||
strategy::{Strategy, ValueTree},
|
||||
test_runner::TestRunner,
|
||||
};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_db::tables;
|
||||
use reth_db_api::table::{DupSort, Table, TableRow};
|
||||
use reth_fs_util as fs;
|
||||
use std::collections::HashSet;
|
||||
use tracing::error;
|
||||
|
||||
const VECTORS_FOLDER: &str = "testdata/micro/db";
|
||||
@ -73,21 +73,14 @@ pub(crate) fn generate_vectors(mut tables: Vec<String>) -> Result<()> {
|
||||
/// Generates test-vectors for normal tables. Keys are sorted and not repeated.
|
||||
fn generate_table_vector<T>(runner: &mut TestRunner, per_table: usize) -> Result<()>
|
||||
where
|
||||
T::Key: Arbitrary + serde::Serialize + Ord + std::hash::Hash,
|
||||
T::Value: Arbitrary + serde::Serialize,
|
||||
T: Table,
|
||||
T::Key: for<'a> Arbitrary<'a> + serde::Serialize + Ord + std::hash::Hash + Clone,
|
||||
T::Value: for<'a> Arbitrary<'a> + serde::Serialize + Clone,
|
||||
{
|
||||
let mut rows = vec![];
|
||||
let mut seen_keys = HashSet::new();
|
||||
let strategy = proptest::collection::vec(
|
||||
any_with::<TableRow<T>>((
|
||||
<T::Key as Arbitrary>::Parameters::default(),
|
||||
<T::Value as Arbitrary>::Parameters::default(),
|
||||
)),
|
||||
per_table - rows.len(),
|
||||
)
|
||||
.no_shrink()
|
||||
.boxed();
|
||||
let strategy =
|
||||
proptest::collection::vec(arb::<TableRow<T>>(), per_table - rows.len()).no_shrink().boxed();
|
||||
|
||||
while rows.len() < per_table {
|
||||
// Generate all `per_table` rows: (Key, Value)
|
||||
@ -111,23 +104,17 @@ where
|
||||
fn generate_dupsort_vector<T>(runner: &mut TestRunner, per_table: usize) -> Result<()>
|
||||
where
|
||||
T: Table + DupSort,
|
||||
T::Key: Arbitrary + serde::Serialize + Ord + std::hash::Hash,
|
||||
T::Value: Arbitrary + serde::Serialize + Ord,
|
||||
T::Key: for<'a> Arbitrary<'a> + serde::Serialize + Ord + std::hash::Hash + Clone,
|
||||
T::Value: for<'a> Arbitrary<'a> + serde::Serialize + Ord + Clone,
|
||||
{
|
||||
let mut rows = vec![];
|
||||
|
||||
// We want to control our repeated keys
|
||||
let mut seen_keys = HashSet::new();
|
||||
|
||||
let strat_values = proptest::collection::vec(
|
||||
any_with::<T::Value>(<T::Value as Arbitrary>::Parameters::default()),
|
||||
100..300,
|
||||
)
|
||||
.no_shrink()
|
||||
.boxed();
|
||||
let strat_values = proptest::collection::vec(arb::<T::Value>(), 100..300).no_shrink().boxed();
|
||||
|
||||
let strat_keys =
|
||||
any_with::<T::Key>(<T::Key as Arbitrary>::Parameters::default()).no_shrink().boxed();
|
||||
let strat_keys = arb::<T::Key>().no_shrink().boxed();
|
||||
|
||||
while rows.len() < per_table {
|
||||
let key: T::Key = strat_keys.new_tree(runner).map_err(|e| eyre::eyre!("{e}"))?.current();
|
||||
|
||||
@ -27,7 +27,7 @@ serde = { workspace = true, optional = true }
|
||||
# arbitrary utils
|
||||
arbitrary = { workspace = true, features = ["derive"], optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
proptest-arbitrary-interop = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
reth-net-common.workspace = true
|
||||
@ -40,6 +40,7 @@ rand.workspace = true
|
||||
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
async-stream.workspace = true
|
||||
|
||||
@ -49,7 +50,7 @@ arbitrary = [
|
||||
"reth-primitives/arbitrary",
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive",
|
||||
"dep:proptest-arbitrary-interop",
|
||||
]
|
||||
serde = ["dep:serde"]
|
||||
|
||||
|
||||
@ -3,13 +3,10 @@
|
||||
|
||||
use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
|
||||
use reth_codecs_derive::{add_arbitrary_tests, derive_arbitrary};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use reth_primitives::generate_valid_header;
|
||||
use reth_primitives::{BlockBody, BlockHashOrNumber, Header, HeadersDirection, B256};
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use proptest::{collection::vec, prelude::*};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use reth_primitives::{generate_valid_header, valid_header_strategy};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -51,18 +48,6 @@ pub struct BlockHeaders(
|
||||
pub Vec<Header>,
|
||||
);
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl proptest::arbitrary::Arbitrary for BlockHeaders {
|
||||
type Parameters = ();
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
let headers_strategy = vec(valid_header_strategy(), 0..10); // Adjust the range as needed
|
||||
|
||||
headers_strategy.prop_map(BlockHeaders).boxed()
|
||||
}
|
||||
|
||||
type Strategy = proptest::prelude::BoxedStrategy<Self>;
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for BlockHeaders {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
@ -111,12 +96,6 @@ impl From<Vec<B256>> for GetBlockBodies {
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct BlockBodies(
|
||||
/// The requested block bodies, each of which should correspond to a hash in the request.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<BlockBody>(), 0..=20)"
|
||||
)
|
||||
)]
|
||||
pub Vec<BlockBody>,
|
||||
);
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ use std::{
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use proptest::{collection::vec, prelude::*};
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -351,7 +353,7 @@ impl Arbitrary for NewPooledTransactionHashes68 {
|
||||
.prop_flat_map(|len| {
|
||||
// Use the generated length to create vectors of TxType, usize, and B256
|
||||
let types_vec =
|
||||
vec(any::<reth_primitives::TxType>().prop_map(|ty| ty as u8), len..=len);
|
||||
vec(arb::<reth_primitives::TxType>().prop_map(|ty| ty as u8), len..=len);
|
||||
|
||||
// Map the usize values to the range 0..131072(0x20000)
|
||||
let sizes_vec = vec(proptest::num::usize::ANY.prop_map(|x| x % 131072), len..=len);
|
||||
|
||||
@ -23,12 +23,6 @@ pub struct GetReceipts(
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Receipts(
|
||||
/// Each receipt hash should correspond to a block hash in the request.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(
|
||||
strategy = "proptest::collection::vec(proptest::collection::vec(proptest::arbitrary::any::<ReceiptWithBloom>(), 0..=50), 0..=5)"
|
||||
)
|
||||
)]
|
||||
pub Vec<Vec<ReceiptWithBloom>>,
|
||||
);
|
||||
|
||||
|
||||
@ -39,8 +39,6 @@ snap = "1.0.5"
|
||||
|
||||
# arbitrary utils
|
||||
arbitrary = { workspace = true, features = ["derive"], optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
reth-net-common.workspace = true
|
||||
@ -58,6 +56,7 @@ secp256k1 = { workspace = true, features = [
|
||||
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
async-stream.workspace = true
|
||||
|
||||
@ -66,8 +65,6 @@ default = ["serde"]
|
||||
arbitrary = [
|
||||
"reth-primitives/arbitrary",
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive",
|
||||
]
|
||||
optimism = ["reth-primitives/optimism"]
|
||||
serde = ["dep:serde"]
|
||||
|
||||
@ -129,22 +129,6 @@ impl<'a> arbitrary::Arbitrary<'a> for Capability {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl proptest::arbitrary::Arbitrary for Capability {
|
||||
type Parameters = proptest::arbitrary::ParamsFor<String>;
|
||||
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
|
||||
use proptest::strategy::Strategy;
|
||||
proptest::arbitrary::any_with::<String>(args) // TODO: what possible values?
|
||||
.prop_flat_map(move |name| {
|
||||
proptest::arbitrary::any_with::<usize>(()) // TODO: What's the max?
|
||||
.prop_map(move |version| Self::new(name.clone(), version))
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
type Strategy = proptest::strategy::BoxedStrategy<Self>;
|
||||
}
|
||||
|
||||
/// Represents all capabilities of a node.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Capabilities {
|
||||
|
||||
@ -19,7 +19,7 @@ alloy-eips.workspace = true
|
||||
alloy-genesis.workspace = true
|
||||
alloy-primitives.workspace = true
|
||||
alloy-rlp.workspace = true
|
||||
alloy-rpc-types-eth = { workspace = true, optional = true }
|
||||
alloy-rpc-types-eth = { workspace = true, optional = true }
|
||||
|
||||
derive_more.workspace = true
|
||||
revm-primitives = { workspace = true, features = ["serde"] }
|
||||
@ -37,11 +37,12 @@ serde.workspace = true
|
||||
# arbitrary utils
|
||||
arbitrary = { workspace = true, features = ["derive"], optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
proptest-arbitrary-interop = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
test-fuzz.workspace = true
|
||||
rand.workspace = true
|
||||
@ -55,6 +56,6 @@ arbitrary = [
|
||||
"alloy-consensus/arbitrary",
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive"
|
||||
"dep:proptest-arbitrary-interop",
|
||||
]
|
||||
alloy-compat = ["alloy-rpc-types-eth"]
|
||||
alloy-compat = ["alloy-rpc-types-eth"]
|
||||
|
||||
@ -16,11 +16,12 @@ use alloy_primitives::{keccak256, Address, BlockNumber, Bloom, Bytes, B256, B64,
|
||||
use alloy_rlp::{length_of_length, Decodable, Encodable};
|
||||
use bytes::BufMut;
|
||||
use core::mem;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use reth_codecs::{add_arbitrary_tests, main_codec, Compact};
|
||||
use revm_primitives::{calc_blob_gasprice, calc_excess_blob_gas};
|
||||
|
||||
/// Block header
|
||||
#[main_codec]
|
||||
#[main_codec(no_arbitrary)]
|
||||
#[add_arbitrary_tests(rlp, 25)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Header {
|
||||
/// The Keccak 256-bit hash of the parent
|
||||
@ -487,3 +488,42 @@ impl Decodable for Header {
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for Header {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
// Generate an arbitrary header, passing it to the generate_valid_header function to make
|
||||
// sure it is valid _with respect to hardforks only_.
|
||||
let base = Self {
|
||||
parent_hash: u.arbitrary()?,
|
||||
ommers_hash: u.arbitrary()?,
|
||||
beneficiary: u.arbitrary()?,
|
||||
state_root: u.arbitrary()?,
|
||||
transactions_root: u.arbitrary()?,
|
||||
receipts_root: u.arbitrary()?,
|
||||
logs_bloom: u.arbitrary()?,
|
||||
difficulty: u.arbitrary()?,
|
||||
number: u.arbitrary()?,
|
||||
gas_limit: u.arbitrary()?,
|
||||
gas_used: u.arbitrary()?,
|
||||
timestamp: u.arbitrary()?,
|
||||
extra_data: u.arbitrary()?,
|
||||
mix_hash: u.arbitrary()?,
|
||||
nonce: u.arbitrary()?,
|
||||
base_fee_per_gas: u.arbitrary()?,
|
||||
blob_gas_used: u.arbitrary()?,
|
||||
excess_blob_gas: u.arbitrary()?,
|
||||
parent_beacon_block_root: u.arbitrary()?,
|
||||
requests_root: u.arbitrary()?,
|
||||
withdrawals_root: u.arbitrary()?,
|
||||
};
|
||||
|
||||
Ok(test_utils::generate_valid_header(
|
||||
base,
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,6 @@ use alloy_rlp::{Decodable, Encodable};
|
||||
use bytes::BufMut;
|
||||
use core::mem;
|
||||
use derive_more::{AsRef, Deref};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use proptest::prelude::*;
|
||||
use reth_codecs::{add_arbitrary_tests, main_codec, Compact};
|
||||
|
||||
/// A [`Header`] that is sealed at a precalculated hash, use [`SealedHeader::unseal()`] if you want
|
||||
@ -130,27 +128,9 @@ impl SealedHeader {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl proptest::arbitrary::Arbitrary for SealedHeader {
|
||||
type Parameters = ();
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
// map valid header strategy by sealing
|
||||
crate::test_utils::valid_header_strategy().prop_map(|header| header.seal_slow()).boxed()
|
||||
}
|
||||
type Strategy = proptest::strategy::BoxedStrategy<Self>;
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for SealedHeader {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
let sealed_header = crate::test_utils::generate_valid_header(
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
u.arbitrary()?,
|
||||
)
|
||||
.seal_slow();
|
||||
Ok(sealed_header)
|
||||
Ok(Header::arbitrary(u)?.seal_slow())
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
use crate::Header;
|
||||
use alloy_primitives::B256;
|
||||
use proptest::{arbitrary::any, prop_compose};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
/// Generates a header which is valid __with respect to past and future forks__. This means, for
|
||||
/// example, that if the withdrawals root is present, the base fee per gas is also present.
|
||||
@ -55,11 +56,11 @@ prop_compose! {
|
||||
///
|
||||
/// See docs for [generate_valid_header] for more information.
|
||||
pub fn valid_header_strategy()(
|
||||
header in any::<Header>(),
|
||||
header in arb::<Header>(),
|
||||
eip_4844_active in any::<bool>(),
|
||||
blob_gas_used in any::<u64>(),
|
||||
excess_blob_gas in any::<u64>(),
|
||||
parent_beacon_block_root in any::<B256>()
|
||||
parent_beacon_block_root in arb::<B256>()
|
||||
) -> Header {
|
||||
generate_valid_header(header, eip_4844_active, blob_gas_used, excess_blob_gas, parent_beacon_block_root)
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ mod tests {
|
||||
use alloy_primitives::{Address, Bytes, Log as AlloyLog, B256};
|
||||
use alloy_rlp::{RlpDecodable, RlpEncodable};
|
||||
use proptest::proptest;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
|
||||
/// This type is kept for compatibility tests after the codec support was added to
|
||||
@ -28,12 +29,6 @@ mod tests {
|
||||
/// Contract that emitted this log.
|
||||
address: Address,
|
||||
/// Topics of the log. The number of logs depend on what `LOG` opcode is used.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<B256>(), 0..=5)"
|
||||
)
|
||||
)]
|
||||
topics: Vec<B256>,
|
||||
/// Arbitrary length data.
|
||||
data: Bytes,
|
||||
@ -57,7 +52,7 @@ mod tests {
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn test_roundtrip_conversion_between_log_and_alloy_log(log: Log) {
|
||||
fn test_roundtrip_conversion_between_log_and_alloy_log(log in arb::<Log>()) {
|
||||
// Convert log to buffer and then create alloy_log from buffer and compare
|
||||
let mut compacted_log = Vec::<u8>::new();
|
||||
let len = log.clone().to_compact(&mut compacted_log);
|
||||
|
||||
@ -71,6 +71,7 @@ mod tests {
|
||||
use alloy_primitives::Address;
|
||||
use alloy_rlp::{RlpDecodable, RlpEncodable};
|
||||
use proptest::proptest;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
/// This type is kept for compatibility tests after the codec support was added to alloy-eips
|
||||
/// Withdrawal type natively
|
||||
@ -108,7 +109,7 @@ mod tests {
|
||||
|
||||
proptest!(
|
||||
#[test]
|
||||
fn test_roundtrip_withdrawal_compat(withdrawal: RethWithdrawal) {
|
||||
fn test_roundtrip_withdrawal_compat(withdrawal in arb::<RethWithdrawal>()) {
|
||||
// Convert to buffer and then create alloy_access_list from buffer and
|
||||
// compare
|
||||
let mut compacted_reth_withdrawal = Vec::<u8>::new();
|
||||
|
||||
@ -51,7 +51,7 @@ zstd = { version = "0.13", features = ["experimental"], optional = true }
|
||||
# arbitrary utils
|
||||
arbitrary = { workspace = true, features = ["derive"], optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
# proptest-derive = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# eth
|
||||
@ -64,6 +64,7 @@ alloy-eips = { workspace = true, features = ["arbitrary"] }
|
||||
assert_matches.workspace = true
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
rand.workspace = true
|
||||
serde_json.workspace = true
|
||||
@ -94,7 +95,6 @@ arbitrary = [
|
||||
"alloy-eips/arbitrary",
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive",
|
||||
"zstd-codec",
|
||||
]
|
||||
c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg", "dep:tempfile", "alloy-eips/kzg"]
|
||||
|
||||
@ -10,6 +10,7 @@ use proptest::{
|
||||
strategy::ValueTree,
|
||||
test_runner::{RngAlgorithm, TestRng, TestRunner},
|
||||
};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_primitives::{
|
||||
constants::eip4844::MAINNET_KZG_TRUSTED_SETUP, BlobTransactionSidecar, TxEip4844,
|
||||
};
|
||||
@ -42,13 +43,13 @@ fn validate_blob_tx(
|
||||
let mut runner = TestRunner::new_with_rng(config, rng);
|
||||
|
||||
// generate tx and sidecar
|
||||
let mut tx = any::<TxEip4844>().new_tree(&mut runner).unwrap().current();
|
||||
let mut tx = arb::<TxEip4844>().new_tree(&mut runner).unwrap().current();
|
||||
let mut blob_sidecar =
|
||||
any::<BlobTransactionSidecar>().new_tree(&mut runner).unwrap().current();
|
||||
arb::<BlobTransactionSidecar>().new_tree(&mut runner).unwrap().current();
|
||||
|
||||
while blob_sidecar.blobs.len() < num_blobs as usize {
|
||||
let blob_sidecar_ext =
|
||||
any::<BlobTransactionSidecar>().new_tree(&mut runner).unwrap().current();
|
||||
arb::<BlobTransactionSidecar>().new_tree(&mut runner).unwrap().current();
|
||||
|
||||
// extend the sidecar with the new blobs
|
||||
blob_sidecar.blobs.extend(blob_sidecar_ext.blobs);
|
||||
|
||||
@ -9,7 +9,7 @@ use alloy_rlp::{RlpDecodable, RlpEncodable};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use proptest::prelude::prop_compose;
|
||||
use reth_codecs::derive_arbitrary;
|
||||
use reth_codecs::{add_arbitrary_tests, derive_arbitrary};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy};
|
||||
use reth_primitives_traits::Requests;
|
||||
@ -31,38 +31,22 @@ prop_compose! {
|
||||
/// Ethereum full block.
|
||||
///
|
||||
/// Withdrawals can be optionally included at the end of the RLP encoded message.
|
||||
#[derive_arbitrary(rlp, 25)]
|
||||
#[add_arbitrary_tests(rlp, 25)]
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Deref, RlpEncodable, RlpDecodable,
|
||||
)]
|
||||
#[rlp(trailing)]
|
||||
pub struct Block {
|
||||
/// Block header.
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), proptest(strategy = "valid_header_strategy()"))]
|
||||
#[deref]
|
||||
pub header: Header,
|
||||
/// Transactions in this block.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<TransactionSigned>(), 0..=100)"
|
||||
)
|
||||
)]
|
||||
pub body: Vec<TransactionSigned>,
|
||||
/// Ommers/uncles header.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(strategy = "proptest::collection::vec(valid_header_strategy(), 0..=2)")
|
||||
)]
|
||||
pub ommers: Vec<Header>,
|
||||
/// Block withdrawals.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(strategy = "proptest::option::of(proptest::arbitrary::any::<Withdrawals>())")
|
||||
)]
|
||||
pub withdrawals: Option<Withdrawals>,
|
||||
/// Block requests.
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), proptest(strategy = "empty_requests_strategy()"))]
|
||||
pub requests: Option<Requests>,
|
||||
}
|
||||
|
||||
@ -187,6 +171,28 @@ impl Block {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for Block {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
// first generate up to 100 txs
|
||||
let transactions = (0..100)
|
||||
.map(|_| TransactionSigned::arbitrary(u))
|
||||
.collect::<arbitrary::Result<Vec<_>>>()?;
|
||||
|
||||
// then generate up to 2 ommers
|
||||
let ommers = (0..2).map(|_| Header::arbitrary(u)).collect::<arbitrary::Result<Vec<_>>>()?;
|
||||
|
||||
Ok(Self {
|
||||
header: u.arbitrary()?,
|
||||
body: transactions,
|
||||
ommers,
|
||||
// for now just generate empty requests, see HACK above
|
||||
requests: u.arbitrary()?,
|
||||
withdrawals: u.arbitrary()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Sealed block with senders recovered from transactions.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Deref, DerefMut)]
|
||||
pub struct BlockWithSenders {
|
||||
@ -278,27 +284,12 @@ pub struct SealedBlock {
|
||||
#[deref_mut]
|
||||
pub header: SealedHeader,
|
||||
/// Transactions with signatures.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<TransactionSigned>(), 0..=100)"
|
||||
)
|
||||
)]
|
||||
pub body: Vec<TransactionSigned>,
|
||||
/// Ommer/uncle headers
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(strategy = "proptest::collection::vec(valid_header_strategy(), 0..=2)")
|
||||
)]
|
||||
pub ommers: Vec<Header>,
|
||||
/// Block withdrawals.
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(strategy = "proptest::option::of(proptest::arbitrary::any::<Withdrawals>())")
|
||||
)]
|
||||
pub withdrawals: Option<Withdrawals>,
|
||||
/// Block requests.
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), proptest(strategy = "empty_requests_strategy()"))]
|
||||
pub requests: Option<Requests>,
|
||||
}
|
||||
|
||||
@ -548,30 +539,19 @@ impl SealedBlockWithSenders {
|
||||
/// A response to `GetBlockBodies`, containing bodies if any bodies were found.
|
||||
///
|
||||
/// Withdrawals can be optionally included at the end of the RLP encoded message.
|
||||
#[derive_arbitrary(rlp, 10)]
|
||||
#[add_arbitrary_tests(rlp, 10)]
|
||||
#[derive(
|
||||
Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, RlpEncodable, RlpDecodable,
|
||||
)]
|
||||
#[rlp(trailing)]
|
||||
pub struct BlockBody {
|
||||
/// Transactions in the block
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<TransactionSigned>(), 0..=100)"
|
||||
)
|
||||
)]
|
||||
pub transactions: Vec<TransactionSigned>,
|
||||
/// Uncle headers for the given block
|
||||
#[cfg_attr(
|
||||
any(test, feature = "arbitrary"),
|
||||
proptest(strategy = "proptest::collection::vec(valid_header_strategy(), 0..=2)")
|
||||
)]
|
||||
pub ommers: Vec<Header>,
|
||||
/// Withdrawals in the block.
|
||||
pub withdrawals: Option<Withdrawals>,
|
||||
/// Requests in the block.
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), proptest(strategy = "empty_requests_strategy()"))]
|
||||
pub requests: Option<Requests>,
|
||||
}
|
||||
|
||||
@ -634,6 +614,22 @@ impl From<Block> for BlockBody {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for BlockBody {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
// first generate up to 100 txs
|
||||
let transactions = (0..100)
|
||||
.map(|_| TransactionSigned::arbitrary(u))
|
||||
.collect::<arbitrary::Result<Vec<_>>>()?;
|
||||
|
||||
// then generate up to 2 ommers
|
||||
let ommers = (0..2).map(|_| Header::arbitrary(u)).collect::<arbitrary::Result<Vec<_>>>()?;
|
||||
|
||||
// for now just generate empty requests, see HACK above
|
||||
Ok(Self { transactions, ommers, requests: None, withdrawals: u.arbitrary()? })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{BlockNumberOrTag::*, *};
|
||||
|
||||
@ -6,8 +6,6 @@ use alloy_rlp::{length_of_length, Decodable, Encodable, RlpDecodable, RlpEncodab
|
||||
use bytes::{Buf, BufMut};
|
||||
use core::{cmp::Ordering, ops::Deref};
|
||||
use derive_more::{Deref, DerefMut, From, IntoIterator};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use proptest::strategy::Strategy;
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
use reth_codecs::CompactZstd;
|
||||
use reth_codecs::{add_arbitrary_tests, main_codec, Compact};
|
||||
@ -186,50 +184,6 @@ pub fn gas_spent_by_transactions<T: Deref<Target = Receipt>>(
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl proptest::arbitrary::Arbitrary for Receipt {
|
||||
type Parameters = ();
|
||||
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
use proptest::prelude::{any, prop_compose};
|
||||
|
||||
prop_compose! {
|
||||
fn arbitrary_receipt()(tx_type in any::<TxType>(),
|
||||
success in any::<bool>(),
|
||||
cumulative_gas_used in any::<u64>(),
|
||||
logs in proptest::collection::vec(proptest::arbitrary::any::<Log>(), 0..=20),
|
||||
_deposit_nonce in any::<Option<u64>>(),
|
||||
_deposit_receipt_version in any::<Option<u64>>()) -> Receipt
|
||||
{
|
||||
// Only receipts for deposit transactions may contain a deposit nonce
|
||||
#[cfg(feature = "optimism")]
|
||||
let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::Deposit {
|
||||
// The deposit receipt version is only present if the deposit nonce is present
|
||||
let deposit_receipt_version = _deposit_nonce.and(_deposit_receipt_version);
|
||||
(_deposit_nonce, deposit_receipt_version)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
Receipt { tx_type,
|
||||
success,
|
||||
cumulative_gas_used,
|
||||
logs,
|
||||
// Only receipts for deposit transactions may contain a deposit nonce
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_nonce,
|
||||
// Only receipts for deposit transactions may contain a deposit nonce
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version
|
||||
}
|
||||
}
|
||||
}
|
||||
arbitrary_receipt().boxed()
|
||||
}
|
||||
|
||||
type Strategy = proptest::strategy::BoxedStrategy<Self>;
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for Receipt {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
|
||||
@ -10,6 +10,7 @@ mod tests {
|
||||
use crate::{Address, B256};
|
||||
use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
|
||||
use proptest::proptest;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
|
||||
/// This type is kept for compatibility tests after the codec support was added to alloy-eips
|
||||
@ -18,12 +19,7 @@ mod tests {
|
||||
#[derive(
|
||||
Clone, Debug, PartialEq, Eq, Hash, Default, RlpDecodableWrapper, RlpEncodableWrapper,
|
||||
)]
|
||||
struct RethAccessList(
|
||||
#[proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<RethAccessListItem>(), 0..=20)"
|
||||
)]
|
||||
Vec<RethAccessListItem>,
|
||||
);
|
||||
struct RethAccessList(Vec<RethAccessListItem>);
|
||||
|
||||
impl PartialEq<AccessList> for RethAccessList {
|
||||
fn eq(&self, other: &AccessList) -> bool {
|
||||
@ -41,9 +37,6 @@ mod tests {
|
||||
/// The storage keys to be loaded at the start of execution.
|
||||
///
|
||||
/// Each key is a 32-byte value representing a specific storage slot.
|
||||
#[proptest(
|
||||
strategy = "proptest::collection::vec(proptest::arbitrary::any::<B256>(), 0..=20)"
|
||||
)]
|
||||
storage_keys: Vec<B256>,
|
||||
}
|
||||
|
||||
@ -55,7 +48,7 @@ mod tests {
|
||||
|
||||
proptest!(
|
||||
#[test]
|
||||
fn test_roundtrip_accesslist_compat(access_list: RethAccessList) {
|
||||
fn test_roundtrip_accesslist_compat(access_list in arb::<RethAccessList>()) {
|
||||
// Convert access_list to buffer and then create alloy_access_list from buffer and
|
||||
// compare
|
||||
let mut compacted_reth_access_list = Vec::<u8>::new();
|
||||
|
||||
@ -148,20 +148,28 @@ impl TxEip4844 {
|
||||
/// - `max_fee_per_blob_gas`
|
||||
/// - `blob_versioned_hashes`
|
||||
pub fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
|
||||
Ok(Self {
|
||||
let mut tx = Self {
|
||||
chain_id: Decodable::decode(buf)?,
|
||||
nonce: Decodable::decode(buf)?,
|
||||
max_priority_fee_per_gas: Decodable::decode(buf)?,
|
||||
max_fee_per_gas: Decodable::decode(buf)?,
|
||||
gas_limit: Decodable::decode(buf)?,
|
||||
placeholder: Some(()),
|
||||
placeholder: None,
|
||||
to: Decodable::decode(buf)?,
|
||||
value: Decodable::decode(buf)?,
|
||||
input: Decodable::decode(buf)?,
|
||||
access_list: Decodable::decode(buf)?,
|
||||
max_fee_per_blob_gas: Decodable::decode(buf)?,
|
||||
blob_versioned_hashes: Decodable::decode(buf)?,
|
||||
})
|
||||
};
|
||||
|
||||
// HACK: our arbitrary implementation sets the placeholder this way for backwards
|
||||
// compatibility, and should be removed once `placeholder` can be removed
|
||||
if tx.to != Address::default() {
|
||||
tx.placeholder = Some(())
|
||||
}
|
||||
|
||||
Ok(tx)
|
||||
}
|
||||
|
||||
/// Outputs the length of the transaction's fields, without a RLP header.
|
||||
|
||||
@ -1463,40 +1463,6 @@ impl Decodable for TransactionSigned {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl proptest::arbitrary::Arbitrary for TransactionSigned {
|
||||
type Parameters = ();
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
use proptest::prelude::{any, Strategy};
|
||||
|
||||
any::<(Transaction, Signature)>()
|
||||
.prop_map(move |(mut transaction, sig)| {
|
||||
if let Some(chain_id) = transaction.chain_id() {
|
||||
// Otherwise we might overflow when calculating `v` on `recalculate_hash`
|
||||
transaction.set_chain_id(chain_id % (u64::MAX / 2 - 36));
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
let sig = transaction
|
||||
.is_deposit()
|
||||
.then(Signature::optimism_deposit_tx_signature)
|
||||
.unwrap_or(sig);
|
||||
|
||||
if let Transaction::Eip4844(ref mut tx_eip_4844) = transaction {
|
||||
tx_eip_4844.placeholder =
|
||||
if tx_eip_4844.to != Address::default() { Some(()) } else { None };
|
||||
}
|
||||
|
||||
let mut tx = Self { hash: Default::default(), signature: sig, transaction };
|
||||
tx.hash = tx.recalculate_hash();
|
||||
tx
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
type Strategy = proptest::strategy::BoxedStrategy<Self>;
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
@ -1506,6 +1472,11 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned {
|
||||
transaction.set_chain_id(chain_id % (u64::MAX / 2 - 36));
|
||||
}
|
||||
|
||||
if let Transaction::Eip4844(ref mut tx_eip_4844) = transaction {
|
||||
tx_eip_4844.placeholder =
|
||||
if tx_eip_4844.to != Address::default() { Some(()) } else { None };
|
||||
}
|
||||
|
||||
let signature = Signature::arbitrary(u)?;
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
@ -1654,6 +1625,7 @@ mod tests {
|
||||
};
|
||||
use alloy_primitives::{address, b256, bytes};
|
||||
use alloy_rlp::{Decodable, Encodable, Error as RlpError};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_codecs::Compact;
|
||||
use secp256k1::{Keypair, Secp256k1};
|
||||
use std::str::FromStr;
|
||||
@ -1929,7 +1901,7 @@ mod tests {
|
||||
#![proptest_config(proptest::prelude::ProptestConfig::with_cases(1))]
|
||||
|
||||
#[test]
|
||||
fn test_parallel_recovery_order(txes in proptest::collection::vec(proptest::prelude::any::<Transaction>(), *PARALLEL_SENDER_RECOVERY_THRESHOLD * 5)) {
|
||||
fn test_parallel_recovery_order(txes in proptest::collection::vec(arb::<Transaction>(), *PARALLEL_SENDER_RECOVERY_THRESHOLD * 5)) {
|
||||
let mut rng =rand::thread_rng();
|
||||
let secp = Secp256k1::new();
|
||||
let txes: Vec<TransactionSigned> = txes.into_iter().map(|mut tx| {
|
||||
|
||||
@ -615,33 +615,6 @@ impl<'a> arbitrary::Arbitrary<'a> for PooledTransactionsElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl proptest::arbitrary::Arbitrary for PooledTransactionsElement {
|
||||
type Parameters = ();
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
use proptest::prelude::{any, Strategy};
|
||||
|
||||
any::<(TransactionSigned, crate::BlobTransactionSidecar)>()
|
||||
.prop_map(move |(transaction, sidecar)| {
|
||||
match Self::try_from(transaction) {
|
||||
Ok(Self::BlobTransaction(mut tx)) => {
|
||||
tx.sidecar = sidecar;
|
||||
Self::BlobTransaction(tx)
|
||||
}
|
||||
Ok(tx) => tx,
|
||||
Err(_) => Self::Eip1559 {
|
||||
transaction: Default::default(),
|
||||
signature: Default::default(),
|
||||
hash: Default::default(),
|
||||
}, // Gen an Eip1559 as arbitrary for testing purpose
|
||||
}
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
type Strategy = proptest::strategy::BoxedStrategy<Self>;
|
||||
}
|
||||
|
||||
/// A signed pooled transaction with recovered signer.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, AsRef, Deref)]
|
||||
pub struct PooledTransactionsElementEcRecovered {
|
||||
|
||||
@ -26,6 +26,7 @@ arbitrary = { workspace = true, features = ["derive"] }
|
||||
assert_matches.workspace = true
|
||||
proptest.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
serde_json.workspace = true
|
||||
test-fuzz.workspace = true
|
||||
toml.workspace = true
|
||||
toml.workspace = true
|
||||
|
||||
@ -24,5 +24,6 @@ serde.workspace = true
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
test-fuzz.workspace = true
|
||||
rand.workspace = true
|
||||
rand.workspace = true
|
||||
|
||||
@ -15,7 +15,7 @@ workspace = true
|
||||
reth-codecs-derive = { path = "./derive", default-features = false }
|
||||
|
||||
# eth
|
||||
alloy-consensus = { workspace = true, optional = true }
|
||||
alloy-consensus = { workspace = true, optional = true, features = ["arbitrary"] }
|
||||
alloy-eips = { workspace = true, optional = true }
|
||||
alloy-genesis = { workspace = true, optional = true }
|
||||
alloy-primitives.workspace = true
|
||||
@ -37,6 +37,7 @@ serde_json.workspace = true
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["std", "alloy"]
|
||||
|
||||
@ -87,12 +87,13 @@ pub fn maybe_generate_tests(args: TokenStream, ast: &DeriveInput) -> TokenStream
|
||||
#[cfg(test)]
|
||||
mod #mod_tests {
|
||||
#(#traits)*
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
#[test]
|
||||
fn proptest() {
|
||||
let mut config = proptest::prelude::ProptestConfig::with_cases(#default_cases as u32);
|
||||
|
||||
proptest::proptest!(config, |(field: super::#type_ident)| {
|
||||
proptest::proptest!(config, |(field in arb::<super::#type_ident>())| {
|
||||
#(#roundtrips)*
|
||||
});
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ pub fn main_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
derive_arbitrary(TokenStream::from_iter(args), compact)
|
||||
}
|
||||
|
||||
/// Adds `Arbitrary` and `proptest::Arbitrary` imports into scope and derives the struct/enum.
|
||||
/// Adds `Arbitrary` imports into scope and derives the struct/enum.
|
||||
///
|
||||
/// If `compact` or `rlp` is passed to `derive_arbitrary`, there will be proptest roundtrip tests
|
||||
/// generated. An integer value passed will limit the number of proptest cases generated (default:
|
||||
@ -89,17 +89,13 @@ pub fn derive_arbitrary(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let tests = arbitrary::maybe_generate_tests(args, &ast);
|
||||
|
||||
// Avoid duplicate names
|
||||
let prop_import = format_ident!("{}PropTestArbitrary", ast.ident);
|
||||
let arb_import = format_ident!("{}Arbitrary", ast.ident);
|
||||
|
||||
quote! {
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use proptest_derive::Arbitrary as #prop_import;
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use arbitrary::Arbitrary as #arb_import;
|
||||
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), derive(#prop_import, #arb_import))]
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), derive(#arb_import))]
|
||||
#ast
|
||||
|
||||
#tests
|
||||
|
||||
@ -26,10 +26,11 @@ impl Compact for Request {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use proptest::proptest;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn roundtrip(request: Request) {
|
||||
fn roundtrip(request in arb::<Request>()) {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
request.to_compact(&mut buf);
|
||||
let (decoded, _) = Request::from_compact(&buf, buf.len());
|
||||
|
||||
@ -36,7 +36,6 @@ bytes.workspace = true
|
||||
# arbitrary utils
|
||||
arbitrary = { workspace = true, features = ["derive"], optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# reth libs with arbitrary
|
||||
@ -58,6 +57,7 @@ iai-callgrind.workspace = true
|
||||
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
|
||||
paste.workspace = true
|
||||
@ -70,6 +70,5 @@ arbitrary = [
|
||||
"reth-primitives/arbitrary",
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive",
|
||||
]
|
||||
optimism = []
|
||||
|
||||
@ -51,6 +51,7 @@ itertools.workspace = true
|
||||
rand = { workspace = true, optional = true }
|
||||
paste = { workspace = true, optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-arbitrary-interop = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
reth-primitives = { workspace = true, features = ["arbitrary"] }
|
||||
@ -59,6 +60,7 @@ reth-tracing.workspace = true
|
||||
paste.workspace = true
|
||||
rand.workspace = true
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
criterion.workspace = true
|
||||
pprof = { workspace = true, features = ["criterion", "flamegraph"] }
|
||||
assert_matches.workspace = true
|
||||
@ -67,9 +69,9 @@ serde_json.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["serde"]
|
||||
arbitrary = ["proptest", "reth-primitives/arbitrary"]
|
||||
serde = ["dep:serde"]
|
||||
test-utils = ["rand", "paste", "serde"]
|
||||
arbitrary = ["proptest", "reth-primitives/arbitrary", "proptest-arbitrary-interop"]
|
||||
|
||||
[[bench]]
|
||||
name = "truncate"
|
||||
|
||||
@ -987,9 +987,10 @@ impl From<MockTransaction> for Transaction {
|
||||
impl proptest::arbitrary::Arbitrary for MockTransaction {
|
||||
type Parameters = ();
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
use proptest::prelude::{any, Strategy};
|
||||
use proptest::prelude::Strategy;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
any::<(Transaction, Address, B256)>()
|
||||
arb::<(Transaction, Address, B256)>()
|
||||
.prop_map(|(tx, sender, tx_hash)| match &tx {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
chain_id,
|
||||
|
||||
@ -32,13 +32,12 @@ nybbles = { workspace = true, features = ["serde", "rlp"] }
|
||||
hash-db = { version = "=0.15.2", optional = true }
|
||||
plain_hasher = { version = "0.2", optional = true }
|
||||
arbitrary = { workspace = true, features = ["derive"], optional = true }
|
||||
proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
arbitrary = { workspace = true, features = ["derive"] }
|
||||
assert_matches.workspace = true
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
proptest-derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
test-fuzz.workspace = true
|
||||
@ -51,6 +50,4 @@ test-utils = ["dep:plain_hasher", "dep:hash-db", "arbitrary"]
|
||||
arbitrary = [
|
||||
"alloy-trie/arbitrary",
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive",
|
||||
]
|
||||
|
||||
@ -148,6 +148,7 @@ impl Compact for HashBuilderState {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
|
||||
#[test]
|
||||
fn hash_builder_state_regression() {
|
||||
@ -161,7 +162,7 @@ mod tests {
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn hash_builder_state_roundtrip(state: HashBuilderState) {
|
||||
fn hash_builder_state_roundtrip(state in arb::<HashBuilderState>()) {
|
||||
let mut buf = vec![];
|
||||
let len = state.clone().to_compact(&mut buf);
|
||||
let (decoded, _) = HashBuilderState::from_compact(&buf, len);
|
||||
|
||||
@ -54,6 +54,7 @@ tokio = { workspace = true, default-features = false, features = ["sync", "rt",
|
||||
rayon.workspace = true
|
||||
criterion = { workspace = true, features = ["async_tokio"] }
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["metrics", "async", "parallel"]
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#![allow(missing_docs, unreachable_pub)]
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use rayon::ThreadPoolBuilder;
|
||||
use reth_primitives::{Account, B256, U256};
|
||||
use reth_provider::{
|
||||
@ -82,7 +83,7 @@ fn generate_test_data(size: usize) -> (HashedPostState, HashedPostState) {
|
||||
let db_state = hash_map(
|
||||
any::<B256>(),
|
||||
(
|
||||
any::<Account>().prop_filter("non empty account", |a| !a.is_empty()),
|
||||
arb::<Account>().prop_filter("non empty account", |a| !a.is_empty()),
|
||||
hash_map(
|
||||
any::<B256>(),
|
||||
any::<U256>().prop_filter("non zero value", |v| !v.is_zero()),
|
||||
|
||||
@ -57,6 +57,7 @@ triehash = "0.8"
|
||||
|
||||
# misc
|
||||
proptest.workspace = true
|
||||
proptest-arbitrary-interop.workspace = true
|
||||
tokio = { workspace = true, default-features = false, features = [
|
||||
"sync",
|
||||
"rt",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#![allow(missing_docs, unreachable_pub)]
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_primitives::{ReceiptWithBloom, B256};
|
||||
use reth_trie::triehash::KeccakHasher;
|
||||
|
||||
@ -26,7 +27,7 @@ pub fn trie_root_benchmark(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
fn generate_test_data(size: usize) -> Vec<ReceiptWithBloom> {
|
||||
prop::collection::vec(any::<ReceiptWithBloom>(), size)
|
||||
prop::collection::vec(arb::<ReceiptWithBloom>(), size)
|
||||
.new_tree(&mut TestRunner::new(ProptestConfig::default()))
|
||||
.unwrap()
|
||||
.current()
|
||||
|
||||
@ -374,6 +374,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::{HashedPostState, HashedStorage};
|
||||
use proptest::prelude::*;
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_db::{tables, test_utils::create_test_rw_db};
|
||||
use reth_db_api::{database::Database, transaction::DbTxMut};
|
||||
use reth_primitives::StorageEntry;
|
||||
@ -537,7 +538,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn fuzz_hashed_account_cursor() {
|
||||
proptest!(ProptestConfig::with_cases(10), |(db_accounts: BTreeMap<B256, Account>, post_state_accounts: BTreeMap<B256, Option<Account>>)| {
|
||||
proptest!(ProptestConfig::with_cases(10), |(db_accounts in arb::<BTreeMap<B256, Account>>(), post_state_accounts in arb::<BTreeMap<B256, Option<Account>>>())| {
|
||||
let db = create_test_rw_db();
|
||||
db.update(|tx| {
|
||||
for (key, account) in &db_accounts {
|
||||
|
||||
@ -551,6 +551,7 @@ mod tests {
|
||||
BranchNodeCompact, TrieMask,
|
||||
};
|
||||
use proptest::{prelude::ProptestConfig, proptest};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_db::{tables, test_utils::TempDatabase, DatabaseEnv};
|
||||
use reth_db_api::{
|
||||
cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO},
|
||||
@ -649,7 +650,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn arbitrary_storage_root() {
|
||||
proptest!(ProptestConfig::with_cases(10), |(item: (Address, std::collections::BTreeMap<B256, U256>))| {
|
||||
proptest!(ProptestConfig::with_cases(10), |(item in arb::<(Address, std::collections::BTreeMap<B256, U256>)>())| {
|
||||
let (address, storage) = item;
|
||||
|
||||
let hashed_address = keccak256(address);
|
||||
@ -759,7 +760,7 @@ mod tests {
|
||||
#[test]
|
||||
fn arbitrary_state_root() {
|
||||
proptest!(
|
||||
ProptestConfig::with_cases(10), | (state: State) | {
|
||||
ProptestConfig::with_cases(10), | (state in arb::<State>()) | {
|
||||
test_state_root_with_state(state);
|
||||
}
|
||||
);
|
||||
@ -768,7 +769,7 @@ mod tests {
|
||||
#[test]
|
||||
fn arbitrary_state_root_with_progress() {
|
||||
proptest!(
|
||||
ProptestConfig::with_cases(10), | (state: State) | {
|
||||
ProptestConfig::with_cases(10), | (state in arb::<State>()) | {
|
||||
let hashed_entries_total = state.len() +
|
||||
state.values().map(|(_, slots)| slots.len()).sum::<usize>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user