Sitelet https://github.com/init4tech/storage/commit/5b24c64dc70d4153455317290806f368332a06a2
Skip to content

Commit 5b24c64

Browse files
prestwichclaude
andcommitted
chore(hot): final cleanup from delamination review
- Wire the six new history conformance entrypoints into conformance() so they run against both MemKv and MDBX. Closes coverage gap on multi-batch appends + standalone truncates. The two update_history_indices tests use non-overlapping block windows (1-5 vs 1001-1005) to avoid re-indexing shared change-set entries on the shared conformance store. - Add empirical-size comment to worst_case_dense_pack_fits_in_dupsort_budget explaining the 650 vs 750 adjustment. - Drop a "shard key" terminology leak from a comment in db/history.rs. - Update setup_history_kv docstring in revm.rs to describe logical state rather than shard layout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2599ed9 commit 5b24c64

5 files changed

Lines changed: 42 additions & 28 deletions

File tree

‎crates/hot/src/conformance/history.rs‎

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -117,90 +117,97 @@ where
117117
let slot1 = U256::from(1);
118118
let slot2 = U256::from(2);
119119

120-
// Phase 1: Write storage change sets for blocks 1-3
120+
// Phase 1: Write storage change sets for blocks 1001-1003
121+
// (distinct from blocks 1-5 used by test_update_history_indices_account;
122+
// update_history_indices scans the shared change-set table, so each test
123+
// that calls it must operate in a non-overlapping block window)
121124
{
122125
let writer = hot_kv.writer().unwrap();
123126

124-
// Block 1: addr1.slot1 changed
125-
writer.write_storage_prestate(1, addr1, &slot1, &U256::ZERO).unwrap();
127+
// Block 1001: addr1.slot1 changed
128+
writer.write_storage_prestate(1001, addr1, &slot1, &U256::ZERO).unwrap();
126129

127-
// Block 2: addr1.slot1 and addr1.slot2 changed
128-
writer.write_storage_prestate(2, addr1, &slot1, &U256::from(100)).unwrap();
129-
writer.write_storage_prestate(2, addr1, &slot2, &U256::ZERO).unwrap();
130+
// Block 1002: addr1.slot1 and addr1.slot2 changed
131+
writer.write_storage_prestate(1002, addr1, &slot1, &U256::from(100)).unwrap();
132+
writer.write_storage_prestate(1002, addr1, &slot2, &U256::ZERO).unwrap();
130133

131-
// Block 3: addr1.slot2 changed
132-
writer.write_storage_prestate(3, addr1, &slot2, &U256::from(200)).unwrap();
134+
// Block 1003: addr1.slot2 changed
135+
writer.write_storage_prestate(1003, addr1, &slot2, &U256::from(200)).unwrap();
133136

134137
writer.commit().unwrap();
135138
}
136139

137-
// Phase 2: Run update_history_indices for blocks 1-3
140+
// Phase 2: Run update_history_indices for blocks 1001-1003
138141
{
139142
let writer = hot_kv.writer().unwrap();
140-
writer.update_history_indices(1..=3).unwrap();
143+
writer.update_history_indices(1001..=1003).unwrap();
141144
writer.commit().unwrap();
142145
}
143146

144147
// Phase 3: Verify storage history was created correctly
145148
{
146149
let reader = hot_kv.reader().unwrap();
147150

148-
// addr1.slot1 should have history at blocks 1, 2
151+
// addr1.slot1 should have history at blocks 1001, 1002
149152
let history1 = reader
150153
.blocks_changed_storage(&addr1, &slot1)
151154
.unwrap()
152155
.expect("addr1.slot1 should have history");
153156
let blocks1: Vec<u64> = history1.iter().collect();
154-
assert_eq!(blocks1, vec![1, 2], "addr1.slot1 history mismatch");
157+
assert_eq!(blocks1, vec![1001, 1002], "addr1.slot1 history mismatch");
155158

156-
// addr1.slot2 should have history at blocks 2, 3
159+
// addr1.slot2 should have history at blocks 1002, 1003
157160
let history2 = reader
158161
.blocks_changed_storage(&addr1, &slot2)
159162
.unwrap()
160163
.expect("addr1.slot2 should have history");
161164
let blocks2: Vec<u64> = history2.iter().collect();
162-
assert_eq!(blocks2, vec![2, 3], "addr1.slot2 history mismatch");
165+
assert_eq!(blocks2, vec![1002, 1003], "addr1.slot2 history mismatch");
163166
}
164167

165-
// Phase 4: Write more change sets for blocks 4-5
168+
// Phase 4: Write more change sets for blocks 1004-1005
166169
{
167170
let writer = hot_kv.writer().unwrap();
168171

169-
// Block 4: addr1.slot1 changed
170-
writer.write_storage_prestate(4, addr1, &slot1, &U256::from(300)).unwrap();
172+
// Block 1004: addr1.slot1 changed
173+
writer.write_storage_prestate(1004, addr1, &slot1, &U256::from(300)).unwrap();
171174

172-
// Block 5: addr1.slot1 changed again
173-
writer.write_storage_prestate(5, addr1, &slot1, &U256::from(400)).unwrap();
175+
// Block 1005: addr1.slot1 changed again
176+
writer.write_storage_prestate(1005, addr1, &slot1, &U256::from(400)).unwrap();
174177

175178
writer.commit().unwrap();
176179
}
177180

178-
// Phase 5: Run update_history_indices for blocks 4-5
181+
// Phase 5: Run update_history_indices for blocks 1004-1005
179182
{
180183
let writer = hot_kv.writer().unwrap();
181-
writer.update_history_indices(4..=5).unwrap();
184+
writer.update_history_indices(1004..=1005).unwrap();
182185
writer.commit().unwrap();
183186
}
184187

185188
// Phase 6: Verify history was appended correctly
186189
{
187190
let reader = hot_kv.reader().unwrap();
188191

189-
// addr1.slot1 should now have history at blocks 1, 2, 4, 5
192+
// addr1.slot1 should now have history at blocks 1001, 1002, 1004, 1005
190193
let history1 = reader
191194
.blocks_changed_storage(&addr1, &slot1)
192195
.unwrap()
193196
.expect("addr1.slot1 should have history");
194197
let blocks1: Vec<u64> = history1.iter().collect();
195-
assert_eq!(blocks1, vec![1, 2, 4, 5], "addr1.slot1 history mismatch after append");
198+
assert_eq!(
199+
blocks1,
200+
vec![1001, 1002, 1004, 1005],
201+
"addr1.slot1 history mismatch after append"
202+
);
196203

197-
// addr1.slot2 should still have history at blocks 2, 3 (unchanged)
204+
// addr1.slot2 should still have history at blocks 1002, 1003 (unchanged)
198205
let history2 = reader
199206
.blocks_changed_storage(&addr1, &slot2)
200207
.unwrap()
201208
.expect("addr1.slot2 should have history");
202209
let blocks2: Vec<u64> = history2.iter().collect();
203-
assert_eq!(blocks2, vec![2, 3], "addr1.slot2 history should be unchanged");
210+
assert_eq!(blocks2, vec![1002, 1003], "addr1.slot2 history should be unchanged");
204211
}
205212
}
206213

‎crates/hot/src/conformance/mod.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,10 @@ where
4040
test_cursor_iter_from(hot_kv);
4141
test_cursor_dual_iter(hot_kv);
4242
test_cursor_dual_iter_from(hot_kv);
43+
test_update_history_indices_account(hot_kv);
44+
test_update_history_indices_storage(hot_kv);
45+
test_history_append_removes_old_entries(hot_kv);
46+
test_delete_dual_account_history(hot_kv);
47+
test_delete_dual_storage_history(hot_kv);
48+
test_delete_and_rewrite_dual(hot_kv);
4349
}

‎crates/hot/src/db/history.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub trait HistoryRead: HotDbRead {
4949
let Some(first) = iter.next().transpose()? else {
5050
return Ok(None);
5151
};
52-
// first is (u64, BlockNumberList) — the shard key and its list
52+
// first is (k2, list) — k2 is the opaque dup subkey, internal to the backend
5353
let (_, mut merged) = first;
5454
for entry in iter {
5555
let (_, list) = entry?;

‎crates/hot/src/model/revm.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -805,13 +805,13 @@ mod tests {
805805
/// - Block 5 changed account: pre-state was nonce=1, balance=100
806806
/// - Block 10 changed account: pre-state was nonce=5, balance=500
807807
/// - Current (PlainAccountState): nonce=10, balance=1000
808-
/// - History shard: (A, 10) → [5, 10]
808+
/// - Account history: blocks [5, 10] for address A
809809
///
810810
/// Storage slot 0x42 for address A:
811811
/// - Block 5 changed slot: pre-state was 0
812812
/// - Block 10 changed slot: pre-state was 100
813813
/// - Current (PlainStorageState): 200
814-
/// - History shard: (A, ShardedKey(0x42, 10)) → [5, 10]
814+
/// - Storage history: blocks [5, 10] for (address A, slot 0x42)
815815
fn setup_history_kv() -> (MemKv, Address) {
816816
let mem_kv = MemKv::default();
817817
let address = Address::from_slice(&[0x1; 20]);

‎crates/types/src/int_list.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ mod tests {
336336
/// hundreds of contiguous blocks, we stay comfortably under 1500 B.
337337
#[test]
338338
fn worst_case_dense_pack_fits_in_dupsort_budget() {
339+
// 650 contiguous values empirically encode to ~1300 B; 750 was over budget.
339340
let list = IntegerList::new(0u64..650).unwrap();
340341
let size = list.serialized_size();
341342
assert!(size <= 1500, "dense pack of 650 blocks encoded as {size} B, expected <= 1500");

0 commit comments

Comments
 (0)