Skip to content

Commit

Permalink
feat(nodebuilder/prune)!: Enable sampling window for light nodes (#2991)
Browse files Browse the repository at this point in the history
This PR enforces a sampling window of 30 days' worth of seconds for
light nodes. The DASer will now skip over sampling headers that fall
outside this range.

I've labeled this PR as breaking as it contains a behavioural break
(sampling constrained to a 30-day window rather than all historical
headers).
  • Loading branch information
renaynay authored Jan 4, 2024
1 parent f75e255 commit 45e1847
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
2 changes: 2 additions & 0 deletions das/daser.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ func (d *DASer) sample(ctx context.Context, h *header.ExtendedHeader) error {
// short-circuit if pruning is enabled and the header is outside the
// availability window
if !d.isWithinSamplingWindow(h) {
log.Debugw("skipping header outside sampling window", "height", h.Height(),
"time", h.Time())
return nil
}

Expand Down
37 changes: 37 additions & 0 deletions das/daser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package das

import (
"context"
"strconv"
"testing"
"time"

Expand Down Expand Up @@ -244,6 +245,42 @@ func TestDASerSampleTimeout(t *testing.T) {
}
}

// TestDASer_SamplingWindow tests the sampling window determination
// for headers.
func TestDASer_SamplingWindow(t *testing.T) {
ds := ds_sync.MutexWrap(datastore.NewMapDatastore())
sub := new(headertest.Subscriber)
fserv := &fraudtest.DummyService[*header.ExtendedHeader]{}
getter := getterStub{}
avail := mocks.NewMockAvailability(gomock.NewController(t))

// create and start DASer
daser, err := NewDASer(avail, sub, getter, ds, fserv, newBroadcastMock(1),
WithSamplingWindow(time.Second))
require.NoError(t, err)

var tests = []struct {
timestamp time.Time
withinWindow bool
}{
{timestamp: time.Now().Add(-(time.Second * 5)), withinWindow: false},
{timestamp: time.Now().Add(-(time.Millisecond * 800)), withinWindow: true},
{timestamp: time.Now().Add(-(time.Hour)), withinWindow: false},
{timestamp: time.Now().Add(-(time.Hour * 24 * 30)), withinWindow: false},
{timestamp: time.Now(), withinWindow: true},
}

for i, tt := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
eh := headertest.RandExtendedHeader(t)
eh.RawHeader.Time = tt.timestamp

assert.Equal(t, tt.withinWindow, daser.isWithinSamplingWindow(eh))
})
}

}

// createDASerSubcomponents takes numGetter (number of headers
// to store in mockGetter) and numSub (number of headers to store
// in the mock header.Subscriber), returning a newly instantiated
Expand Down
2 changes: 1 addition & 1 deletion nodebuilder/prune/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func ConstructModule(tp node.Type) fx.Option {
fx.Provide(func() pruner.Pruner {
return light.NewPruner()
}),
fx.Supply(archival.Window), // TODO @renaynay: turn this into light.Window in following PR
fx.Supply(light.Window),
)
default:
panic("unknown node type")
Expand Down
2 changes: 2 additions & 0 deletions pruner/light/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ import (
"github.com/celestiaorg/celestia-node/pruner"
)

// Window is the availability window for light nodes in the Celestia
// network (30 days).
const Window = pruner.AvailabilityWindow(time.Second * 86400 * 30)

0 comments on commit 45e1847

Please sign in to comment.