Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions l1/l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type Client struct {
network *networks.Network
resubscribeDelay time.Duration
pollFinalisedInterval time.Duration
// CatchUpChunkSize is the L1 block range per backward eth_getLogs request
// during the startup catch-up scan.
catchUpChunkSize uint64
nonFinalisedLogs map[uint64]*StateUpdate
listener EventListener
Expand All @@ -36,9 +38,8 @@ type options struct {
EventListener EventListener
ResubscribeDelay time.Duration
PollFinalisedInterval time.Duration
// CatchUpChunkSize is the L1 block range per backward eth_getLogs request
// during the startup catch-up scan.
CatchUpChunkSize uint64
CatchUpChunkSize uint64

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove the comment above?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please double-check what your LLM generates. The comment was moved to the wrong field.

Logger log.StructuredLogger
}

// Option is a functional option for configuring l1 client options.
Expand All @@ -64,25 +65,30 @@ func WithCatchUpChunkSize(size uint64) Option {
return func(o *options) { o.CatchUpChunkSize = size }
}

// WithLogger sets the structured logger for the l1 client.
func WithLogger(logger log.StructuredLogger) Option {
return func(o *options) { o.Logger = logger }
}

func NewClient(
provider L1StateProvider,
chain *blockchain.Blockchain,
logger log.StructuredLogger,
opts ...Option,
) *Client {
o := options{
EventListener: SelectiveListener{},
ResubscribeDelay: 10 * time.Second,
PollFinalisedInterval: time.Minute,
CatchUpChunkSize: defaultCatchUpChunkSize,
Logger: log.NewNopZapLogger(),
}
for _, opt := range opts {
opt(&o)
}
return &Client{
provider: provider,
l2Chain: chain,
logger: logger,
logger: o.Logger,
network: chain.Network(),
resubscribeDelay: o.ResubscribeDelay,
pollFinalisedInterval: o.PollFinalisedInterval,
Expand Down
18 changes: 9 additions & 9 deletions l1/l1_pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ func TestClient(t *testing.T) {
client := NewClient(
nil,
chain,
nopLog,
l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Nanosecond),
)
Expand Down Expand Up @@ -447,7 +447,7 @@ func TestUnreliableSubscription(t *testing.T) {
client := NewClient(
nil,
chain,
nopLog,
l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Nanosecond),
)
Expand Down Expand Up @@ -574,7 +574,7 @@ func TestCatchUpSetsL1HeadOnStart(t *testing.T) {
Times(1)

client := NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Hour),
WithCatchUpChunkSize(10),
Expand Down Expand Up @@ -629,7 +629,7 @@ func TestCatchUpMultiChunk(t *testing.T) {
After(secondCall)

client := NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Hour),
WithCatchUpChunkSize(10),
Expand Down Expand Up @@ -668,7 +668,7 @@ func TestCatchUpFilterError(t *testing.T) {
// Best-effort: catch-up error must NOT terminate Run. It logs and falls
// through to the live subscription, which we let idle until ctx expires.
client := NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Hour),
)
Expand Down Expand Up @@ -715,7 +715,7 @@ func TestCatchUpHeadAndCachePartition(t *testing.T) {
Times(1)

client := NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Hour),
)
Expand Down Expand Up @@ -781,7 +781,7 @@ func TestCatchUpPartialProgressPreserved(t *testing.T) {
// Poll interval is 1h so the live loop never ticks setL1Head — the only
// thing that could populate nonFinalisedLogs is the catch-up walk.
client := NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
WithResubscribeDelay(0),
WithPollFinalisedInterval(time.Hour),
)
Expand Down Expand Up @@ -825,7 +825,7 @@ func TestFinalisedHeightReturnsPromptlyOnCancel(t *testing.T) {
Return(uint64(0), errors.New("boom")).
MinTimes(1)

client := NewClient(provider, chain, nopLog, WithResubscribeDelay(time.Hour))
client := NewClient(provider, chain, l1.WithLogger(nopLog), WithResubscribeDelay(time.Hour))

ctx, cancel := context.WithCancel(t.Context())
type result struct {
Expand Down Expand Up @@ -873,7 +873,7 @@ func TestSubscribeToUpdatesReturnsPromptlyOnCancel(t *testing.T) {
Return(nil, errors.New("boom")).
MinTimes(1)

client := NewClient(provider, chain, nopLog, WithResubscribeDelay(time.Hour))
client := NewClient(provider, chain, l1.WithLogger(nopLog), WithResubscribeDelay(time.Hour))

ctx, cancel := context.WithCancel(t.Context())
done := make(chan Subscription, 1)
Expand Down
26 changes: 13 additions & 13 deletions l1/l1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestFailToCreateSubscription(t *testing.T) {
client := l1.NewClient(
provider,
chain,
nopLog,
l1.WithLogger(nopLog),
l1.WithResubscribeDelay(0),
l1.WithPollFinalisedInterval(time.Nanosecond),
)
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestMismatchedChainID(t *testing.T) {
client := l1.NewClient(
provider,
chain,
nopLog,
l1.WithLogger(nopLog),
l1.WithResubscribeDelay(0),
l1.WithPollFinalisedInterval(time.Nanosecond),
)
Expand Down Expand Up @@ -139,7 +139,7 @@ func TestChainIDCheckTimeout(t *testing.T) {
}).
Times(1)

client := l1.NewClient(provider, chain, nopLog)
client := l1.NewClient(provider, chain, l1.WithLogger(nopLog))

err := client.CatchUpL1Head(t.Context())
require.ErrorContains(t, err, "eth_chainId did not respond within")
Expand Down Expand Up @@ -170,7 +170,7 @@ func TestChainIDFetchError(t *testing.T) {
Return(nil, rpcErr).
Times(1)

client := l1.NewClient(provider, chain, nopLog)
client := l1.NewClient(provider, chain, l1.WithLogger(nopLog))

err := client.CatchUpL1Head(t.Context())
require.ErrorContains(t, err, "retrieving Ethereum chain ID")
Expand Down Expand Up @@ -218,7 +218,7 @@ func TestTransientChainIDErrorDoesNotShutDownNode(t *testing.T) {
// entering catch-up or the watch loop, so no other L1StateProvider calls occur.

client := l1.NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
l1.WithResubscribeDelay(0),
l1.WithPollFinalisedInterval(time.Nanosecond),
)
Expand Down Expand Up @@ -258,7 +258,7 @@ func TestFinalisedHeightTimeoutDuringCatchUp(t *testing.T) {
}).
Times(1)

err := l1.NewClient(provider, chain, nopLog).CatchUpL1Head(t.Context())
err := l1.NewClient(provider, chain, l1.WithLogger(nopLog)).CatchUpL1Head(t.Context())
require.ErrorContains(t, err, `eth_getBlockByNumber("finalized")`)
require.ErrorContains(t, err, "did not respond within")
require.ErrorContains(t, err, "--eth-node")
Expand Down Expand Up @@ -291,7 +291,7 @@ func TestLatestHeightTimeoutDuringCatchUp(t *testing.T) {
}).
Times(1)

err := l1.NewClient(provider, chain, nopLog).CatchUpL1Head(t.Context())
err := l1.NewClient(provider, chain, l1.WithLogger(nopLog)).CatchUpL1Head(t.Context())
require.ErrorContains(t, err, "eth_blockNumber did not respond within")
require.ErrorContains(t, err, "--eth-node")
})
Expand Down Expand Up @@ -325,7 +325,7 @@ func TestFilterStateUpdateTimeoutDuringCatchUp(t *testing.T) {
}).
Times(1)

err := l1.NewClient(provider, chain, nopLog).CatchUpL1Head(t.Context())
err := l1.NewClient(provider, chain, l1.WithLogger(nopLog)).CatchUpL1Head(t.Context())
require.ErrorContains(t, err, "eth_getLogs did not respond within")
require.ErrorContains(t, err, "--eth-node")
})
Expand Down Expand Up @@ -400,7 +400,7 @@ func TestFinalisedHeightRetryLoopProgressesPastHang(t *testing.T) {
Return([]*l1.StateUpdate{event}, nil).
Times(1)

client := l1.NewClient(provider, chain, nopLog, l1.WithResubscribeDelay(time.Second))
client := l1.NewClient(provider, chain, l1.WithLogger(nopLog), l1.WithResubscribeDelay(time.Second))
require.NoError(t, client.CatchUpL1Head(t.Context()))

got, err := chain.L1Head()
Expand Down Expand Up @@ -466,7 +466,7 @@ func TestEventListener(t *testing.T) {

var got *core.L1Head
client := l1.NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
l1.WithResubscribeDelay(0),
l1.WithPollFinalisedInterval(time.Nanosecond),
l1.WithEventListener(l1.SelectiveListener{
Expand Down Expand Up @@ -533,7 +533,7 @@ func TestEventListenerCatchUp(t *testing.T) {

var got *core.L1Head
client := l1.NewClient(
provider, chain, nopLog,
provider, chain, l1.WithLogger(nopLog),
l1.WithResubscribeDelay(0),
l1.WithPollFinalisedInterval(time.Hour),
l1.WithEventListener(l1.SelectiveListener{
Expand Down Expand Up @@ -595,7 +595,7 @@ func TestCatchUpL1Head(t *testing.T) {
AnyTimes()
provider.EXPECT().Close().AnyTimes()

client := l1.NewClient(provider, chain, nopLog)
client := l1.NewClient(provider, chain, l1.WithLogger(nopLog))
require.NoError(t, client.CatchUpL1Head(t.Context()))

persisted, err := chain.L1Head()
Expand Down Expand Up @@ -623,7 +623,7 @@ func TestCatchUpL1Head_ChainIDMismatch(t *testing.T) {
provider.EXPECT().ChainID(gomock.Any()).Return(big.NewInt(999), nil)
provider.EXPECT().Close()

err := l1.NewClient(provider, chain, nopLog).CatchUpL1Head(t.Context())
err := l1.NewClient(provider, chain, l1.WithLogger(nopLog)).CatchUpL1Head(t.Context())
require.ErrorContains(t, err, "mismatched network id between L1 and L2")
require.ErrorContains(t, err, "--eth-node")
}
2 changes: 1 addition & 1 deletion node/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func fetchL1HeadIfMissing(
return fmt.Errorf("creating L1 state provider: %w", err)
}

client := l1.NewClient(provider, chain, logger)
client := l1.NewClient(provider, chain, l1.WithLogger(logger))
if err := client.CatchUpL1Head(ctx); err != nil {
return fmt.Errorf("catching up to the latest L1 head: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,8 @@ func newL1Client(
if includeMetrics {
registerL1Metrics(provider)
}

return l1.NewClient(provider, chain, logger, l1Opts...), provider, nil
l1Opts = append(l1Opts, l1.WithLogger(logger))
return l1.NewClient(provider, chain, l1Opts...), provider, nil
}

// newGethL1StateProvider validates the Ethereum endpoint URL and dials the L1
Expand Down