From e76fec283865ceb6699cca9cb8083f1e36de2df0 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 8 Nov 2024 18:57:00 +0100 Subject: [PATCH 1/2] test(trie): add ParallelProof unit test --- crates/trie/common/src/proofs.rs | 4 +- crates/trie/parallel/src/proof.rs | 83 ++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/crates/trie/common/src/proofs.rs b/crates/trie/common/src/proofs.rs index a94b2b96fbdf..d04953f1ef85 100644 --- a/crates/trie/common/src/proofs.rs +++ b/crates/trie/common/src/proofs.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; /// The state multiproof of target accounts and multiproofs of their storage tries. /// Multiproof is effectively a state subtrie that only contains the nodes /// in the paths of target accounts. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct MultiProof { /// State trie multiproof for requested accounts. pub account_subtree: ProofNodes, @@ -79,7 +79,7 @@ impl MultiProof { } /// The merkle multiproof of storage trie. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct StorageMultiProof { /// Storage trie root. pub root: B256, diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index 4cb99b50d0c8..5ef61f925e28 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -18,7 +18,7 @@ use reth_trie::{ }; use reth_trie_common::proof::ProofRetainer; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; use tracing::debug; #[cfg(feature = "metrics")] @@ -210,3 +210,84 @@ where Ok(MultiProof { account_subtree: hash_builder.take_proof_nodes(), storages }) } } + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{keccak256, Address, U256}; + use rand::Rng; + use reth_primitives::{Account, StorageEntry}; + use reth_provider::{test_utils::create_test_provider_factory, HashingWriter}; + use reth_trie::proof::Proof; + + #[test] + fn random_parallel_proof() { + let factory = create_test_provider_factory(); + let consistent_view = ConsistentDbView::new(factory.clone(), None); + + let mut rng = rand::thread_rng(); + let state = (0..100) + .map(|_| { + let address = Address::random(); + let account = + Account { balance: U256::from(rng.gen::()), ..Default::default() }; + let mut storage = HashMap::::default(); + let has_storage = rng.gen_bool(0.7); + if has_storage { + for _ in 0..100 { + storage.insert( + B256::from(U256::from(rng.gen::())), + U256::from(rng.gen::()), + ); + } + } + (address, (account, storage)) + }) + .collect::>(); + + { + let provider_rw = factory.provider_rw().unwrap(); + provider_rw + .insert_account_for_hashing( + state.iter().map(|(address, (account, _))| (*address, Some(*account))), + ) + .unwrap(); + provider_rw + .insert_storage_for_hashing(state.iter().map(|(address, (_, storage))| { + ( + *address, + storage + .iter() + .map(|(slot, value)| StorageEntry { key: *slot, value: *value }), + ) + })) + .unwrap(); + provider_rw.commit().unwrap(); + } + + let mut targets = HashMap::new(); + for (address, (_, storage)) in state.iter().take(10) { + let hashed_address = keccak256(*address); + let mut target_slots = HashSet::new(); + + for (slot, _) in storage.iter().take(5) { + target_slots.insert(*slot); + } + + if !target_slots.is_empty() { + targets.insert(hashed_address, target_slots); + } + } + + let provider_rw = factory.provider_rw().unwrap(); + let trie_cursor_factory = DatabaseTrieCursorFactory::new(provider_rw.tx_ref()); + let hashed_cursor_factory = DatabaseHashedCursorFactory::new(provider_rw.tx_ref()); + + assert_eq!( + ParallelProof::new(consistent_view.clone(), Default::default()) + .multiproof(targets.clone()) + .unwrap(), + Proof::new(trie_cursor_factory, hashed_cursor_factory).multiproof(targets).unwrap() + ); + } +} From c260156d635046fe4b9110be065c4fb31f173fed Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 8 Nov 2024 20:36:08 +0100 Subject: [PATCH 2/2] fix build for --all-features --- crates/trie/parallel/src/proof.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index 5ef61f925e28..bafb9917c600 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -1,5 +1,8 @@ use crate::{root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets}; -use alloy_primitives::{map::HashSet, B256}; +use alloy_primitives::{ + map::{HashMap, HashSet}, + B256, +}; use alloy_rlp::{BufMut, Encodable}; use itertools::Itertools; use reth_db::DatabaseError; @@ -214,7 +217,7 @@ where #[cfg(test)] mod tests { use super::*; - use alloy_primitives::{keccak256, Address, U256}; + use alloy_primitives::{keccak256, map::DefaultHashBuilder, Address, U256}; use rand::Rng; use reth_primitives::{Account, StorageEntry}; use reth_provider::{test_utils::create_test_provider_factory, HashingWriter}; @@ -231,7 +234,7 @@ mod tests { let address = Address::random(); let account = Account { balance: U256::from(rng.gen::()), ..Default::default() }; - let mut storage = HashMap::::default(); + let mut storage = HashMap::::default(); let has_storage = rng.gen_bool(0.7); if has_storage { for _ in 0..100 { @@ -243,7 +246,7 @@ mod tests { } (address, (account, storage)) }) - .collect::>(); + .collect::>(); { let provider_rw = factory.provider_rw().unwrap(); @@ -265,10 +268,11 @@ mod tests { provider_rw.commit().unwrap(); } - let mut targets = HashMap::new(); + let mut targets = + HashMap::, DefaultHashBuilder>::default(); for (address, (_, storage)) in state.iter().take(10) { let hashed_address = keccak256(*address); - let mut target_slots = HashSet::new(); + let mut target_slots = HashSet::::default(); for (slot, _) in storage.iter().take(5) { target_slots.insert(*slot); @@ -284,7 +288,7 @@ mod tests { let hashed_cursor_factory = DatabaseHashedCursorFactory::new(provider_rw.tx_ref()); assert_eq!( - ParallelProof::new(consistent_view.clone(), Default::default()) + ParallelProof::new(consistent_view, Default::default()) .multiproof(targets.clone()) .unwrap(), Proof::new(trie_cursor_factory, hashed_cursor_factory).multiproof(targets).unwrap()