diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 4bde73a37fc..1db07033e51 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -377,7 +377,6 @@ impl DatabaseProvider DatabaseProvider DatabaseProvider().unwrap(); + cursor.insert(account_nibbles_key.clone(), &node0).unwrap(); + } + + // Create executed blocks + let mut rng = generators::rng(); + let block0 = random_block(&mut rng, 0, BlockParams { parent: None, ..Default::default() }); + let block1 = random_block( + &mut rng, + 1, + BlockParams { parent: Some(block0.hash()), ..Default::default() }, + ); + let block2 = random_block( + &mut rng, + 2, + BlockParams { parent: Some(block1.hash()), ..Default::default() }, + ); + + let executed0 = ExecutedBlock::new( + Arc::new(RecoveredBlock::new_sealed(block0, Vec::new())), + Arc::new(ExecutionOutcome { + first_block: 0, + receipts: vec![vec![]], + ..Default::default() + }), + ComputedTrieData::without_trie_input( + Arc::new(HashedPostStateSorted::default()), + Arc::new(TrieUpdatesSorted::default()), + ), + ); + + let executed1 = ExecutedBlock::new( + Arc::new(RecoveredBlock::new_sealed(block1, Vec::new())), + Arc::new(ExecutionOutcome { + first_block: 1, + receipts: vec![vec![]], + ..Default::default() + }), + ComputedTrieData::without_trie_input( + Arc::new(HashedPostStateSorted::default()), + Arc::new(TrieUpdatesSorted::new( + vec![(account_nibbles, Some(node1.clone()))], + B256Map::default(), + )), + ), + ); + + let executed2 = ExecutedBlock::new( + Arc::new(RecoveredBlock::new_sealed(block2, Vec::new())), + Arc::new(ExecutionOutcome { + first_block: 2, + receipts: vec![vec![]], + ..Default::default() + }), + ComputedTrieData::without_trie_input( + Arc::new(HashedPostStateSorted::default()), + Arc::new(TrieUpdatesSorted::new( + vec![(account_nibbles, Some(node2.clone()))], + B256Map::default(), + )), + ), + ); + + provider_rw.save_blocks(vec![executed0, executed1, executed2]).unwrap(); + + // Block 1 changeset should see the pre-existing db value. + { + let mut cursor = + provider_rw.tx_ref().cursor_dup_read::().unwrap(); + let entries = + cursor.walk_dup(Some(1u64), None).unwrap().collect::, _>>().unwrap(); + assert_eq!( + entries, + vec![( + 1u64, + TrieChangeSetsEntry { + nibbles: account_nibbles_subkey.clone(), + node: Some(node0), + } + )] + ); + } + + // Block 2 changeset should see block 1's update via the overlay. + { + let mut cursor = + provider_rw.tx_ref().cursor_dup_read::().unwrap(); + let entries = + cursor.walk_dup(Some(2u64), None).unwrap().collect::, _>>().unwrap(); + assert_eq!( + entries, + vec![( + 2u64, + TrieChangeSetsEntry { nibbles: account_nibbles_subkey, node: Some(node1) } + )] + ); + } + + // Final trie state should reflect the last update. + { + let mut cursor = provider_rw.tx_ref().cursor_read::().unwrap(); + let entry = cursor.seek_exact(account_nibbles_key).unwrap(); + assert_eq!(entry.map(|e| e.1), Some(node2)); + } + + provider_rw.commit().unwrap(); + } }