Skip to content

Commit 1103e7b

Browse files
committed
cache evm execution info
1 parent 7b7f387 commit 1103e7b

File tree

17 files changed

+58
-80
lines changed

17 files changed

+58
-80
lines changed

apps/testapp/kv/kvexecutor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ func getTxKey(height uint64, txKey string) ds.Key {
426426

427427
// GetExecutionInfo returns execution layer parameters.
428428
// For KVExecutor, returns MaxGas=0 indicating no gas-based filtering.
429-
func (k *KVExecutor) GetExecutionInfo(ctx context.Context, height uint64) (execution.ExecutionInfo, error) {
429+
func (k *KVExecutor) GetExecutionInfo(ctx context.Context) (execution.ExecutionInfo, error) {
430430
return execution.ExecutionInfo{MaxGas: 0}, nil
431431
}
432432

block/internal/syncing/syncer.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,12 +905,17 @@ func (s *Syncer) VerifyForcedInclusionTxs(ctx context.Context, currentState type
905905
return fmt.Errorf("failed to retrieve forced included txs from DA: %w", err)
906906
}
907907

908+
executionInfo, err := s.exec.GetExecutionInfo(ctx)
909+
if err != nil {
910+
return fmt.Errorf("failed to get execution info: %w", err)
911+
}
912+
908913
// Filter out invalid forced inclusion transactions using the executor's FilterTxs.
909914
// This ensures we don't mark the sequencer as malicious for not including txs that
910915
// were legitimately filtered (e.g., malformed, unparseable, or otherwise invalid).
911916
validForcedTxs := forcedIncludedTxsEvent.Txs
912917
if len(forcedIncludedTxsEvent.Txs) > 0 {
913-
filterStatuses, filterErr := s.exec.FilterTxs(ctx, forcedIncludedTxsEvent.Txs, 0, 0, true)
918+
filterStatuses, filterErr := s.exec.FilterTxs(ctx, forcedIncludedTxsEvent.Txs, executionInfo.MaxGas, common.DefaultMaxBlobSize, true)
914919
if filterErr != nil {
915920
s.logger.Warn().Err(filterErr).Msg("failed to filter forced inclusion txs, checking no txs")
916921
validForcedTxs = [][]byte{}

core/execution/dummy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (e *DummyExecutor) GetStateRoot() []byte {
105105

106106
// GetExecutionInfo returns execution layer parameters.
107107
// For DummyExecutor, returns MaxGas=0 indicating no gas-based filtering.
108-
func (e *DummyExecutor) GetExecutionInfo(ctx context.Context, height uint64) (ExecutionInfo, error) {
108+
func (e *DummyExecutor) GetExecutionInfo(ctx context.Context) (ExecutionInfo, error) {
109109
return ExecutionInfo{MaxGas: 0}, nil
110110
}
111111

core/execution/execution.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,14 @@ type Executor interface {
8484
SetFinal(ctx context.Context, blockHeight uint64) error
8585

8686
// GetExecutionInfo returns current execution layer parameters.
87-
// The height parameter allows querying info for a specific block height.
88-
// Use height=0 to get parameters for the next block (based on latest state).
89-
//
90-
// For non-gas-based execution layers, return ExecutionInfo{MaxGas: 0}.
9187
//
9288
// Parameters:
9389
// - ctx: Context for timeout/cancellation control
94-
// - height: Block height to query (0 for next block parameters)
9590
//
9691
// Returns:
9792
// - info: Current execution parameters
9893
// - error: Any errors during retrieval
99-
GetExecutionInfo(ctx context.Context, height uint64) (ExecutionInfo, error)
94+
GetExecutionInfo(ctx context.Context) (ExecutionInfo, error)
10095

10196
// FilterTxs validates force-included transactions and applies gas and size filtering for all passed txs.
10297
//

execution/evm/execution.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net/http"
1212
"strings"
1313
"sync"
14+
"sync/atomic"
1415
"time"
1516

1617
"github.com/ethereum/go-ethereum/beacon/engine"
@@ -178,6 +179,8 @@ type EngineClient struct {
178179
currentFinalizedBlockHash common.Hash // Store last finalized block hash
179180
blockHashCache map[uint64]common.Hash // height -> hash cache for safe block lookups
180181

182+
cachedExecutionInfo atomic.Pointer[execution.ExecutionInfo] // Cached execution info (gas limit)
183+
181184
logger zerolog.Logger
182185
}
183186

@@ -814,22 +817,20 @@ func (c *EngineClient) filterTransactions(txs [][]byte) []string {
814817
}
815818

816819
// GetExecutionInfo returns current execution layer parameters.
817-
// Implements the ExecutionInfoProvider interface.
818-
func (c *EngineClient) GetExecutionInfo(ctx context.Context, height uint64) (execution.ExecutionInfo, error) {
819-
// If height is 0, get the latest block's gas limit (for next block)
820-
if height == 0 {
821-
header, err := c.ethClient.HeaderByNumber(ctx, nil) // nil = latest
822-
if err != nil {
823-
return execution.ExecutionInfo{}, fmt.Errorf("failed to get latest block: %w", err)
824-
}
825-
return execution.ExecutionInfo{MaxGas: header.GasLimit}, nil
820+
func (c *EngineClient) GetExecutionInfo(ctx context.Context) (execution.ExecutionInfo, error) {
821+
if cached := c.cachedExecutionInfo.Load(); cached != nil {
822+
return *cached, nil
826823
}
827824

828-
_, _, gasLimit, _, err := c.getBlockInfo(ctx, height)
825+
header, err := c.ethClient.HeaderByNumber(ctx, nil) // nil = latest
829826
if err != nil {
830-
return execution.ExecutionInfo{}, fmt.Errorf("failed to get block info at height %d: %w", height, err)
827+
return execution.ExecutionInfo{}, fmt.Errorf("failed to get latest block: %w", err)
831828
}
832-
return execution.ExecutionInfo{MaxGas: gasLimit}, nil
829+
830+
info := execution.ExecutionInfo{MaxGas: header.GasLimit}
831+
c.cachedExecutionInfo.Store(&info)
832+
833+
return info, nil
833834
}
834835

835836
// FilterTxs validates force-included transactions and applies gas and size filtering for all passed txs.

execution/grpc/client.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,8 @@ func (c *Client) SetFinal(ctx context.Context, blockHeight uint64) error {
117117
//
118118
// This method retrieves execution parameters such as the block gas limit
119119
// from the remote execution service.
120-
func (c *Client) GetExecutionInfo(ctx context.Context, height uint64) (execution.ExecutionInfo, error) {
121-
req := connect.NewRequest(&pb.GetExecutionInfoRequest{
122-
Height: height,
123-
})
120+
func (c *Client) GetExecutionInfo(ctx context.Context) (execution.ExecutionInfo, error) {
121+
req := connect.NewRequest(&pb.GetExecutionInfoRequest{})
124122

125123
resp, err := c.client.GetExecutionInfo(ctx, req)
126124
if err != nil {

execution/grpc/client_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type mockExecutor struct {
1515
getTxsFunc func(ctx context.Context) ([][]byte, error)
1616
executeTxsFunc func(ctx context.Context, txs [][]byte, blockHeight uint64, timestamp time.Time, prevStateRoot []byte) ([]byte, error)
1717
setFinalFunc func(ctx context.Context, blockHeight uint64) error
18-
getExecutionInfoFunc func(ctx context.Context, height uint64) (execution.ExecutionInfo, error)
18+
getExecutionInfoFunc func(ctx context.Context) (execution.ExecutionInfo, error)
1919
filterTxsFunc func(ctx context.Context, txs [][]byte, maxBytes, maxGas uint64, hasForceIncludedTransaction bool) ([]execution.FilterStatus, error)
2020
}
2121

@@ -47,9 +47,9 @@ func (m *mockExecutor) SetFinal(ctx context.Context, blockHeight uint64) error {
4747
return nil
4848
}
4949

50-
func (m *mockExecutor) GetExecutionInfo(ctx context.Context, height uint64) (execution.ExecutionInfo, error) {
50+
func (m *mockExecutor) GetExecutionInfo(ctx context.Context) (execution.ExecutionInfo, error) {
5151
if m.getExecutionInfoFunc != nil {
52-
return m.getExecutionInfoFunc(ctx, height)
52+
return m.getExecutionInfoFunc(ctx)
5353
}
5454
return execution.ExecutionInfo{MaxGas: 0}, nil
5555
}

execution/grpc/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (s *Server) GetExecutionInfo(
144144
ctx context.Context,
145145
req *connect.Request[pb.GetExecutionInfoRequest],
146146
) (*connect.Response[pb.GetExecutionInfoResponse], error) {
147-
info, err := s.executor.GetExecutionInfo(ctx, req.Msg.Height)
147+
info, err := s.executor.GetExecutionInfo(ctx)
148148
if err != nil {
149149
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to get execution info: %w", err))
150150
}

pkg/sequencers/based/sequencer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ doneProcessing:
193193

194194
// getMaxGas retrieves the gas limit from the execution layer.
195195
func (s *BasedSequencer) getMaxGas(ctx context.Context) uint64 {
196-
info, err := s.executor.GetExecutionInfo(ctx, 0)
196+
info, err := s.executor.GetExecutionInfo(ctx)
197197
if err != nil {
198198
s.logger.Warn().Err(err).Msg("failed to get execution info, proceeding without gas limit")
199199
return 0

pkg/sequencers/based/sequencer_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type MockFullDAClient struct {
3232
// It implements proper size filtering based on maxBytes parameter.
3333
func createDefaultMockExecutor(t *testing.T) *mocks.MockExecutor {
3434
mockExec := mocks.NewMockExecutor(t)
35-
mockExec.On("GetExecutionInfo", mock.Anything, mock.Anything).Return(execution.ExecutionInfo{MaxGas: 1000000}, nil).Maybe()
35+
mockExec.On("GetExecutionInfo", mock.Anything).Return(execution.ExecutionInfo{MaxGas: 1000000}, nil).Maybe()
3636
mockExec.On("FilterTxs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(
3737
func(ctx context.Context, txs [][]byte, maxBytes, maxGas uint64, hasForceIncludedTransaction bool) []execution.FilterStatus {
3838
result := make([]execution.FilterStatus, len(txs))
@@ -545,7 +545,7 @@ func TestBasedSequencer_CrashRecoveryMidEpoch(t *testing.T) {
545545
// Create mock executor that postpones tx2 on first call
546546
filterCallCount := 0
547547
mockExec := mocks.NewMockExecutor(t)
548-
mockExec.On("GetExecutionInfo", mock.Anything, mock.Anything).Return(execution.ExecutionInfo{MaxGas: 1000000}, nil).Maybe()
548+
mockExec.On("GetExecutionInfo", mock.Anything).Return(execution.ExecutionInfo{MaxGas: 1000000}, nil).Maybe()
549549
mockExec.On("FilterTxs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(
550550
func(ctx context.Context, txs [][]byte, maxBytes, maxGas uint64, hasForceIncludedTransaction bool) []execution.FilterStatus {
551551
filterCallCount++
@@ -881,7 +881,7 @@ func TestBasedSequencer_GetNextBatch_GasFilteringPreservesUnprocessedTxs(t *test
881881
// - tx2: valid but doesn't fit due to gas limit (returned as remaining)
882882
gasFilterCallCount := 0
883883
mockExec := mocks.NewMockExecutor(t)
884-
mockExec.On("GetExecutionInfo", mock.Anything, mock.Anything).Return(execution.ExecutionInfo{MaxGas: 1000000}, nil).Maybe()
884+
mockExec.On("GetExecutionInfo", mock.Anything).Return(execution.ExecutionInfo{MaxGas: 1000000}, nil).Maybe()
885885
mockExec.On("FilterTxs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(
886886
func(ctx context.Context, txs [][]byte, maxBytes, maxGas uint64, hasForceIncludedTransaction bool) []execution.FilterStatus {
887887
gasFilterCallCount++

0 commit comments

Comments
 (0)