@@ -30,7 +30,6 @@ use crate::{
3030 receipt:: { TxReceipt , map_execution_result} ,
3131 state_changes,
3232 state_commit:: StateCommit ,
33- state_root,
3433} ;
3534
3635#[ derive( Debug ) ]
@@ -267,6 +266,14 @@ pub struct PendingCommit {
267266
268267 // Optimization to avoid unnecessary (deep) clones of commit data.
269268 pub built_commit : Option < StateCommit > ,
269+ pub commit_hashes : Option < CommitHashes > ,
270+ }
271+
272+ #[ derive( Clone , Default , Debug , Serialize , Deserialize , PartialEq , Eq ) ]
273+ pub struct CommitHashes {
274+ pub accounts_hash : B256 ,
275+ pub contracts_hash : B256 ,
276+ pub storage_hash : B256 ,
270277}
271278
272279#[ derive( Clone , Debug , Default , Serialize , PartialEq , Eq ) ]
@@ -801,14 +808,15 @@ impl PersistentDB {
801808 & self ,
802809 state_commit : & mut StateCommit ,
803810 commit_data : & Option < CommitData > ,
811+ commit_hashes : & CommitHashes ,
804812 ) -> Result < ( ) , Error > {
805813 let StateCommit {
806814 key,
807815 change_set,
808816 results,
809817 } = state_commit;
810818
811- match self . commit_to_db ( key, change_set, commit_data, results) {
819+ match self . commit_to_db ( key, change_set, commit_data, commit_hashes , results) {
812820 Ok ( _) => return Ok ( ( ) ) ,
813821 Err ( err) => match & err {
814822 Error :: Heed ( heed_err) => match heed_err {
@@ -828,6 +836,7 @@ impl PersistentDB {
828836 key : & CommitKey ,
829837 change_set : & mut state_changes:: StateChangeset ,
830838 commit_data : & Option < CommitData > ,
839+ commit_hashes : & CommitHashes ,
831840 results : & BTreeMap < B256 , ( ExecutionResult , u64 ) > ,
832841 ) -> Result < ( ) , Error > {
833842 assert ! ( !self . is_block_committed( key. 0 ) ) ;
@@ -845,9 +854,9 @@ impl PersistentDB {
845854 merged_legacy_cold_wallets,
846855 } = change_set;
847856
848- accounts. par_sort_by_key ( |a| a. 0 ) ;
849- contracts. par_sort_by_key ( |a| a. 0 ) ;
850- storage. par_sort_by_key ( |a| a. address ) ;
857+ accounts. par_sort_unstable_by_key ( |a| a. 0 ) ;
858+ contracts. par_sort_unstable_by_key ( |a| a. 0 ) ;
859+ storage. par_sort_unstable_by_key ( |a| a. address ) ;
851860
852861 // Update accounts
853862 for ( address, account) in accounts. iter ( ) {
@@ -1067,9 +1076,9 @@ impl PersistentDB {
10671076 rwtxn,
10681077 & key. 0 ,
10691078 & CompressedBincode ( & CommitReceipts {
1070- accounts_hash : state_root :: calculate_accounts_hash ( & change_set ) ? ,
1071- contracts_hash : state_root :: calculate_contracts_hash ( & change_set ) ? ,
1072- storage_hash : state_root :: calculate_storage_hash ( & change_set ) ? ,
1079+ accounts_hash : commit_hashes . accounts_hash ,
1080+ contracts_hash : commit_hashes . contracts_hash ,
1081+ storage_hash : commit_hashes . storage_hash ,
10731082 tx_receipts,
10741083 } ) ,
10751084 ) ?;
@@ -1113,20 +1122,17 @@ impl PersistentDB {
11131122 }
11141123 }
11151124
1116- pub fn get_committed_hashes (
1117- & self ,
1118- block_number : u64 ,
1119- ) -> Result < Option < ( B256 , B256 , B256 ) > , Error > {
1125+ pub fn get_committed_hashes ( & self , block_number : u64 ) -> Result < Option < CommitHashes > , Error > {
11201126 let env = self . env . clone ( ) ;
11211127 let rtxn = env. read_txn ( ) . expect ( "read" ) ;
11221128 let inner = self . inner . borrow ( ) ;
11231129
11241130 match inner. commits . get ( & rtxn, & block_number) ? {
1125- Some ( receipts) => Ok ( Some ( (
1126- receipts. accounts_hash ,
1127- receipts. contracts_hash ,
1128- receipts. storage_hash ,
1129- ) ) ) ,
1131+ Some ( receipts) => Ok ( Some ( CommitHashes {
1132+ accounts_hash : receipts. accounts_hash ,
1133+ contracts_hash : receipts. contracts_hash ,
1134+ storage_hash : receipts. storage_hash ,
1135+ } ) ) ,
11301136 None => Ok ( None ) ,
11311137 }
11321138 }
@@ -1233,6 +1239,7 @@ impl PendingCommit {
12331239 legacy_cold_wallets : Default :: default ( ) ,
12341240 merged_legacy_cold_wallets : Default :: default ( ) ,
12351241 built_commit : Default :: default ( ) ,
1242+ commit_hashes : Default :: default ( ) ,
12361243 }
12371244 }
12381245
@@ -1276,17 +1283,18 @@ mod tests {
12761283 account:: StoredAccountInfo ,
12771284 compression:: CompressedBincode ,
12781285 db:: {
1279- AddressWrapper , BlockHeaderData , CommitData , CommitKey , CommitReceipts , HashWrapper ,
1280- LegacyAddressWrapper , MAP_SIZE_UNIT , PendingCommit , PersistentDB , PersistentDBOptions ,
1281- ProofData , StaticStringWrapper , StorageEntryWrapper , StringWrapper , TransactionData ,
1282- next_map_size,
1286+ AddressWrapper , BlockHeaderData , CommitData , CommitHashes , CommitKey , CommitReceipts ,
1287+ HashWrapper , LegacyAddressWrapper , MAP_SIZE_UNIT , PendingCommit , PersistentDB ,
1288+ PersistentDBOptions , ProofData , StaticStringWrapper , StorageEntryWrapper ,
1289+ StringWrapper , TransactionData , next_map_size,
12831290 } ,
12841291 historical:: HistoricalAccountData ,
12851292 legacy:: { LegacyAccountAttributes , LegacyAddress , LegacyColdWallet } ,
12861293 logger:: Logger ,
12871294 receipt:: TxReceipt ,
12881295 state_changes:: { StateChangeset , StorageChangeset } ,
12891296 state_commit:: { StateCommit , build_commit} ,
1297+ state_root,
12901298 } ;
12911299 use alloy_primitives:: { Address , B256 , Bytes , FixedBytes , U256 , address, b256, hex} ;
12921300 use revm:: {
@@ -1377,6 +1385,7 @@ mod tests {
13771385 PendingCommit {
13781386 key : CommitKey :: default ( ) ,
13791387 transitions : TransitionState { transitions : state } ,
1388+ commit_hashes : Some ( Default :: default ( ) ) ,
13801389 ..Default :: default ( )
13811390 } ,
13821391 Default :: default ( ) ,
@@ -1407,6 +1416,18 @@ mod tests {
14071416 let mut db = create_temp_database ( ) ;
14081417 let mut pending_commit = PendingCommit :: default ( ) ;
14091418 pending_commit. built_commit = Some ( build_commit ( & mut pending_commit) . unwrap ( ) ) ;
1419+ pending_commit. commit_hashes = Some ( CommitHashes :: default ( ) ) ;
1420+
1421+ crate :: state_commit:: commit_to_db ( & mut db, pending_commit, Default :: default ( ) ) . unwrap ( ) ;
1422+ }
1423+
1424+ #[ test]
1425+ fn test_commit_built_without_precomputed_hashes ( ) {
1426+ let mut db = create_temp_database ( ) ;
1427+ let mut pending_commit = PendingCommit :: default ( ) ;
1428+ pending_commit. built_commit = Some ( build_commit ( & mut pending_commit) . unwrap ( ) ) ;
1429+ pending_commit. commit_hashes = None ;
1430+
14101431 crate :: state_commit:: commit_to_db ( & mut db, pending_commit, Default :: default ( ) ) . unwrap ( ) ;
14111432 }
14121433
@@ -1460,6 +1481,7 @@ mod tests {
14601481 PendingCommit {
14611482 key : CommitKey :: default ( ) ,
14621483 transitions : TransitionState { transitions : state } ,
1484+ commit_hashes : Some ( CommitHashes :: default ( ) ) ,
14631485 ..Default :: default ( )
14641486 } ,
14651487 Default :: default ( ) ,
@@ -1515,6 +1537,7 @@ mod tests {
15151537 PendingCommit {
15161538 key : CommitKey :: default ( ) ,
15171539 transitions : TransitionState { transitions : state } ,
1540+ commit_hashes : Some ( Default :: default ( ) ) ,
15181541 ..Default :: default ( )
15191542 } ,
15201543 Default :: default ( ) ,
@@ -1552,6 +1575,7 @@ mod tests {
15521575 PendingCommit {
15531576 key : CommitKey ( 1 , 0 , B256 :: ZERO ) ,
15541577 transitions : TransitionState { transitions : state } ,
1578+ commit_hashes : Some ( Default :: default ( ) ) ,
15551579 ..Default :: default ( )
15561580 } ,
15571581 Default :: default ( ) ,
@@ -1614,6 +1638,7 @@ mod tests {
16141638 PendingCommit {
16151639 key : CommitKey ( block_number, 0 , B256 :: ZERO ) ,
16161640 transitions : TransitionState { transitions : state } ,
1641+ commit_hashes : Some ( Default :: default ( ) ) ,
16171642 ..Default :: default ( )
16181643 }
16191644 } ;
@@ -2248,7 +2273,14 @@ mod tests {
22482273 }
22492274
22502275 let hashes = db. get_committed_hashes ( 1 ) . unwrap ( ) ;
2251- assert_eq ! ( hashes, Some ( ( accounts_hash, contracts_hash, storage_hash) ) ) ;
2276+ assert_eq ! (
2277+ hashes,
2278+ Some ( CommitHashes {
2279+ accounts_hash,
2280+ contracts_hash,
2281+ storage_hash
2282+ } )
2283+ ) ;
22522284 }
22532285
22542286 #[ test]
@@ -2655,7 +2687,13 @@ mod tests {
26552687 ..Default :: default ( )
26562688 } ;
26572689
2658- db. commit ( & mut state, & Some ( data) ) . unwrap ( ) ;
2690+ let commit_hashes = CommitHashes {
2691+ accounts_hash : state_root:: calculate_accounts_hash ( & state. change_set ) . unwrap ( ) ,
2692+ contracts_hash : state_root:: calculate_contracts_hash ( & state. change_set ) . unwrap ( ) ,
2693+ storage_hash : state_root:: calculate_storage_hash ( & state. change_set ) . unwrap ( ) ,
2694+ } ;
2695+
2696+ db. commit ( & mut state, & Some ( data) , & commit_hashes) . unwrap ( ) ;
26592697 }
26602698
26612699 fn create_temp_database ( ) -> PersistentDB {
0 commit comments