@@ -2,9 +2,9 @@ use crate::{
22 db:: { HistoryError , UnsafeDbWrite , UnsafeHistoryWrite } ,
33 tables,
44} ;
5+ use ahash:: AHashSet ;
56use alloy:: primitives:: { Address , BlockNumber , U256 , address} ;
67use signet_storage_types:: { BlockNumberList , SealedHeader } ;
7- use std:: collections:: HashSet ;
88use trevm:: revm:: database:: BundleState ;
99
1010/// Maximum address value (all bits set to 1).
@@ -24,13 +24,10 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
2424 where
2525 I : IntoIterator < Item = & ' a SealedHeader > ,
2626 {
27- let headers: Vec < _ > = headers. into_iter ( ) . collect ( ) ;
28- if headers. is_empty ( ) {
29- return Err ( HistoryError :: EmptyRange ) ;
30- }
27+ let mut iter = headers. into_iter ( ) ;
28+ let first = iter. next ( ) . ok_or ( HistoryError :: EmptyRange ) ?;
3129
3230 // Validate first header against current DB tip
33- let first = headers[ 0 ] ;
3431 match self . get_chain_tip ( ) . map_err ( HistoryError :: Db ) ? {
3532 None => {
3633 // Empty DB - first block is valid as genesis
@@ -52,11 +49,8 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
5249 }
5350 }
5451
55- // Validate each subsequent header extends the previous
56- for window in headers. windows ( 2 ) {
57- let prev = window[ 0 ] ;
58- let curr = window[ 1 ] ;
59-
52+ // Validate each subsequent header extends the previous using fold
53+ iter. try_fold ( first, |prev, curr| {
6054 let expected_number = prev. number + 1 ;
6155 if curr. number != expected_number {
6256 return Err ( HistoryError :: NonContiguousBlock {
@@ -72,7 +66,9 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
7266 got : curr. parent_hash ,
7367 } ) ;
7468 }
75- }
69+
70+ Ok ( curr)
71+ } ) ?;
7672
7773 Ok ( ( ) )
7874 }
@@ -113,7 +109,8 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
113109 // ═══════════════════════════════════════════════════════════════════
114110 // 1. STREAM AccountChangeSets → restore + filter history in one pass
115111 // ═══════════════════════════════════════════════════════════════════
116- let mut seen_accounts: HashSet < Address > = HashSet :: new ( ) ;
112+ // TODO: estimate capacity from block range size for better allocation
113+ let mut seen_accounts: AHashSet < Address > = AHashSet :: new ( ) ;
117114 let mut account_cursor = self . traverse_dual :: < tables:: AccountChangeSets > ( ) ?;
118115
119116 // Position at first entry
@@ -136,8 +133,8 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
136133 // Filter history index
137134 if let Some ( ( shard_key, list) ) = self . last_account_history ( address) ? {
138135 self . queue_delete_dual :: < tables:: AccountsHistory > ( & address, & shard_key) ?;
139- let filtered: Vec < u64 > = list. iter ( ) . filter ( |& bn| bn <= block) . collect ( ) ;
140- if ! filtered. is_empty ( ) {
136+ let mut filtered = list. iter ( ) . take_while ( |& bn| bn <= block) . peekable ( ) ;
137+ if filtered. peek ( ) . is_some ( ) {
141138 self . write_account_history (
142139 & address,
143140 u64:: MAX ,
@@ -153,7 +150,8 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
153150 // ═══════════════════════════════════════════════════════════════════
154151 // 2. STREAM StorageChangeSets → restore + filter history in one pass
155152 // ═══════════════════════════════════════════════════════════════════
156- let mut seen_storage: HashSet < ( Address , U256 ) > = HashSet :: new ( ) ;
153+ // TODO: estimate capacity from block range size for better allocation
154+ let mut seen_storage: AHashSet < ( Address , U256 ) > = AHashSet :: new ( ) ;
157155 let mut storage_cursor = self . traverse_dual :: < tables:: StorageChangeSets > ( ) ?;
158156
159157 // Position at first entry
@@ -176,8 +174,8 @@ pub trait HistoryWrite: UnsafeDbWrite + UnsafeHistoryWrite {
176174 // Filter history index
177175 if let Some ( ( shard_key, list) ) = self . last_storage_history ( & address, & slot) ? {
178176 self . queue_delete_dual :: < tables:: StorageHistory > ( & address, & shard_key) ?;
179- let filtered: Vec < u64 > = list. iter ( ) . filter ( |& bn| bn <= block) . collect ( ) ;
180- if ! filtered. is_empty ( ) {
177+ let mut filtered = list. iter ( ) . take_while ( |& bn| bn <= block) . peekable ( ) ;
178+ if filtered. peek ( ) . is_some ( ) {
181179 self . write_storage_history (
182180 & address,
183181 slot,
0 commit comments