Skip to content

Commit 74e8ec3

Browse files
Copilotjulienrbrt
andcommitted
Implement PR #3075 review comments: update test context usage and add regression test
Co-authored-by: julienrbrt <29894366+julienrbrt@users.noreply.github.com>
1 parent 1e83b77 commit 74e8ec3

1 file changed

Lines changed: 79 additions & 3 deletions

File tree

block/internal/pruner/pruner_test.go

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package pruner
22

33
import (
44
"context"
5+
"encoding/binary"
56
"testing"
67
"time"
78

@@ -32,7 +33,7 @@ func (e *execMetaAdapter) PruneExec(ctx context.Context, height uint64) error {
3233
func TestPrunerPruneMetadata(t *testing.T) {
3334
t.Parallel()
3435

35-
ctx := context.Background()
36+
ctx := t.Context()
3637
kv := dssync.MutexWrap(ds.NewMapDatastore())
3738
stateStore := store.New(kv)
3839

@@ -67,7 +68,7 @@ func TestPrunerPruneMetadata(t *testing.T) {
6768
func TestPrunerPruneBlocksWithoutDA(t *testing.T) {
6869
t.Parallel()
6970

70-
ctx := context.Background()
71+
ctx := t.Context()
7172
kv := dssync.MutexWrap(ds.NewMapDatastore())
7273
stateStore := store.New(kv)
7374

@@ -128,7 +129,7 @@ func TestPrunerPruneBlocksWithoutDA(t *testing.T) {
128129
func TestPrunerPruneBlocksWithDAEnabled(t *testing.T) {
129130
t.Parallel()
130131

131-
ctx := context.Background()
132+
ctx := t.Context()
132133
kv := dssync.MutexWrap(ds.NewMapDatastore())
133134
stateStore := store.New(kv)
134135

@@ -163,3 +164,78 @@ func TestPrunerPruneBlocksWithDAEnabled(t *testing.T) {
163164
require.NoError(t, err, "expected block data at height %d to still exist (no pruning should have happened)", h)
164165
}
165166
}
167+
168+
// TestPrunerPruneBlocksWithDAWhenStoreHeightLessThanDAHeight is a regression test that verifies
169+
// pruning behavior when DA is enabled and store height is less than DA inclusion height.
170+
// This ensures the pruner uses min(storeHeight, daInclusionHeight) as the upper bound.
171+
func TestPrunerPruneBlocksWithDAWhenStoreHeightLessThanDAHeight(t *testing.T) {
172+
t.Parallel()
173+
174+
ctx := t.Context()
175+
kv := dssync.MutexWrap(ds.NewMapDatastore())
176+
stateStore := store.New(kv)
177+
178+
// Create blocks up to height 100
179+
for height := uint64(1); height <= 100; height++ {
180+
header := &types.SignedHeader{Header: types.Header{BaseHeader: types.BaseHeader{Height: height}}}
181+
data := &types.Data{}
182+
sig := types.Signature([]byte{byte(height)})
183+
184+
batch, err := stateStore.NewBatch(ctx)
185+
require.NoError(t, err)
186+
require.NoError(t, batch.SaveBlockData(header, data, &sig))
187+
require.NoError(t, batch.SetHeight(height))
188+
require.NoError(t, batch.UpdateState(types.State{LastBlockHeight: height}))
189+
require.NoError(t, batch.Commit())
190+
}
191+
192+
// Set DA inclusion height to 150 (higher than store height of 100)
193+
// This simulates the case where DA has confirmed blocks beyond what's in the local store
194+
daInclusionHeight := uint64(150)
195+
daInclusionHeightBz := make([]byte, 8)
196+
binary.LittleEndian.PutUint64(daInclusionHeightBz, daInclusionHeight)
197+
require.NoError(t, stateStore.SetMetadata(ctx, store.DAIncludedHeightKey, daInclusionHeightBz))
198+
199+
execAdapter := &execMetaAdapter{existing: make(map[uint64]struct{})}
200+
for h := uint64(1); h <= 100; h++ {
201+
execAdapter.existing[h] = struct{}{}
202+
}
203+
204+
// Test with DA enabled - should use min(storeHeight=100, daInclusionHeight=150) = 100
205+
cfg := config.PruningConfig{
206+
Mode: config.PruningModeAll,
207+
Interval: config.DurationWrapper{Duration: 1 * time.Second},
208+
KeepRecent: 10,
209+
}
210+
211+
pruner := New(zerolog.New(zerolog.NewTestWriter(t)), stateStore, execAdapter, cfg, 100*time.Millisecond, "localhost:1234") // DA enabled
212+
require.NoError(t, pruner.pruneBlocks())
213+
214+
// Verify blocks were pruned correctly
215+
// Upper bound should be min(100, 150) = 100
216+
// Target height = 100 - 10 (KeepRecent) = 90
217+
// Batch size = 40 blocks (1s interval / 100ms block time * 4)
218+
// So we expect to prune from height 1 up to min(0 + 40, 90) = 40
219+
220+
height, err := stateStore.Height(ctx)
221+
require.NoError(t, err)
222+
require.Equal(t, uint64(100), height)
223+
224+
// Verify old blocks were pruned (up to height 40)
225+
for h := uint64(1); h <= 40; h++ {
226+
_, _, err := stateStore.GetBlockData(ctx, h)
227+
require.Error(t, err, "expected block data at height %d to be pruned", h)
228+
}
229+
230+
// Verify blocks after batch were kept
231+
for h := uint64(41); h <= 100; h++ {
232+
_, _, err := stateStore.GetBlockData(ctx, h)
233+
require.NoError(t, err, "expected block data at height %d to be kept", h)
234+
}
235+
236+
// Verify exec metadata was also pruned (strictly less than 40)
237+
for h := uint64(1); h < 40; h++ {
238+
_, exists := execAdapter.existing[h]
239+
require.False(t, exists, "expected exec metadata at height %d to be pruned", h)
240+
}
241+
}

0 commit comments

Comments
 (0)