Skip to content

Commit 2800a75

Browse files
committed
feat: expose execution client params to ev-node
1 parent 7d30f97 commit 2800a75

31 files changed

+676
-327
lines changed

apps/evm/cmd/run.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ var RunCmd = &cobra.Command{
8989
}
9090

9191
// Create sequencer based on configuration
92-
sequencer, err := createSequencer(logger, datastore, nodeConfig, genesis, daClient)
92+
sequencer, err := createSequencer(logger, datastore, nodeConfig, genesis, daClient, executor)
9393
if err != nil {
9494
return err
9595
}
@@ -160,6 +160,7 @@ func createSequencer(
160160
nodeConfig config.Config,
161161
genesis genesis.Genesis,
162162
daClient block.FullDAClient,
163+
executor execution.Executor,
163164
) (coresequencer.Sequencer, error) {
164165
if nodeConfig.Node.BasedSequencer {
165166
// Based sequencer mode - fetch transactions only from DA
@@ -193,6 +194,14 @@ func createSequencer(
193194
return nil, fmt.Errorf("failed to create single sequencer: %w", err)
194195
}
195196

197+
// Configure DA transaction filter if executor supports it
198+
if filter, ok := executor.(execution.DATransactionFilter); ok {
199+
if infoProvider, ok := executor.(execution.ExecutionInfoProvider); ok {
200+
sequencer.SetDATransactionFilter(filter, infoProvider)
201+
logger.Info().Msg("DA transaction filter configured for gas-based filtering")
202+
}
203+
}
204+
196205
logger.Info().
197206
Str("forced_inclusion_namespace", nodeConfig.DA.GetForcedInclusionNamespace()).
198207
Msg("single sequencer initialized")

apps/testapp/kv/http_server_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func TestHandleKV_Get(t *testing.T) {
141141
// Create and execute the transaction directly
142142
tx := []byte(fmt.Sprintf("%s=%s", tt.key, tt.value))
143143
ctx := context.Background()
144-
_, _, err := exec.ExecuteTxs(ctx, [][]byte{tx}, 1, time.Now(), []byte(""))
144+
_, err := exec.ExecuteTxs(ctx, [][]byte{tx}, 1, time.Now(), []byte(""))
145145
if err != nil {
146146
t.Fatalf("Failed to execute setup transaction: %v", err)
147147
}
@@ -287,13 +287,13 @@ func TestHTTPIntegration_GetKVWithMultipleHeights(t *testing.T) {
287287

288288
// Execute transactions at different heights for the same key
289289
txsHeight1 := [][]byte{[]byte("testkey=original_value")}
290-
_, _, err = exec.ExecuteTxs(ctx, txsHeight1, 1, time.Now(), []byte(""))
290+
_, err = exec.ExecuteTxs(ctx, txsHeight1, 1, time.Now(), []byte(""))
291291
if err != nil {
292292
t.Fatalf("ExecuteTxs failed for height 1: %v", err)
293293
}
294294

295295
txsHeight2 := [][]byte{[]byte("testkey=updated_value")}
296-
_, _, err = exec.ExecuteTxs(ctx, txsHeight2, 2, time.Now(), []byte(""))
296+
_, err = exec.ExecuteTxs(ctx, txsHeight2, 2, time.Now(), []byte(""))
297297
if err != nil {
298298
t.Fatalf("ExecuteTxs failed for height 2: %v", err)
299299
}

apps/testapp/kv/kvexecutor.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -141,52 +141,52 @@ func (k *KVExecutor) computeStateRoot(ctx context.Context) ([]byte, error) {
141141
// InitChain initializes the chain state with genesis parameters.
142142
// It checks the database to see if genesis was already performed.
143143
// If not, it computes the state root from the current DB state and persists genesis info.
144-
func (k *KVExecutor) InitChain(ctx context.Context, genesisTime time.Time, initialHeight uint64, chainID string) ([]byte, uint64, error) {
144+
func (k *KVExecutor) InitChain(ctx context.Context, genesisTime time.Time, initialHeight uint64, chainID string) ([]byte, error) {
145145
select {
146146
case <-ctx.Done():
147-
return nil, 0, ctx.Err()
147+
return nil, ctx.Err()
148148
default:
149149
}
150150

151151
initialized, err := k.db.Has(ctx, genesisInitializedKey)
152152
if err != nil {
153-
return nil, 0, fmt.Errorf("failed to check genesis initialization status: %w", err)
153+
return nil, fmt.Errorf("failed to check genesis initialization status: %w", err)
154154
}
155155

156156
if initialized {
157157
genesisRoot, err := k.db.Get(ctx, genesisStateRootKey)
158158
if err != nil {
159-
return nil, 0, fmt.Errorf("genesis initialized but failed to retrieve state root: %w", err)
159+
return nil, fmt.Errorf("genesis initialized but failed to retrieve state root: %w", err)
160160
}
161-
return genesisRoot, 1024, nil // Assuming 1024 is a constant gas value
161+
return genesisRoot, nil
162162
}
163163

164164
// Genesis not initialized. Compute state root from the current DB state.
165165
// Note: The DB might not be empty if restarting, this reflects the state *at genesis time*.
166166
stateRoot, err := k.computeStateRoot(ctx)
167167
if err != nil {
168-
return nil, 0, fmt.Errorf("failed to compute initial state root for genesis: %w", err)
168+
return nil, fmt.Errorf("failed to compute initial state root for genesis: %w", err)
169169
}
170170

171171
// Persist genesis state root and initialized flag
172172
batch, err := k.db.Batch(ctx)
173173
if err != nil {
174-
return nil, 0, fmt.Errorf("failed to create batch for genesis persistence: %w", err)
174+
return nil, fmt.Errorf("failed to create batch for genesis persistence: %w", err)
175175
}
176176
err = batch.Put(ctx, genesisStateRootKey, stateRoot)
177177
if err != nil {
178-
return nil, 0, fmt.Errorf("failed to put genesis state root in batch: %w", err)
178+
return nil, fmt.Errorf("failed to put genesis state root in batch: %w", err)
179179
}
180180
err = batch.Put(ctx, genesisInitializedKey, []byte("true")) // Store a marker value
181181
if err != nil {
182-
return nil, 0, fmt.Errorf("failed to put genesis initialized flag in batch: %w", err)
182+
return nil, fmt.Errorf("failed to put genesis initialized flag in batch: %w", err)
183183
}
184184
err = batch.Commit(ctx)
185185
if err != nil {
186-
return nil, 0, fmt.Errorf("failed to commit genesis persistence batch: %w", err)
186+
return nil, fmt.Errorf("failed to commit genesis persistence batch: %w", err)
187187
}
188188

189-
return stateRoot, 1024, nil // Assuming 1024 is a constant gas value
189+
return stateRoot, nil
190190
}
191191

192192
// GetTxs retrieves available transactions from the mempool channel.
@@ -222,16 +222,16 @@ func (k *KVExecutor) GetTxs(ctx context.Context) ([][]byte, error) {
222222
// ExecuteTxs processes each transaction assumed to be in the format "key=value".
223223
// It updates the database accordingly using a batch and removes the executed transactions from the mempool.
224224
// Invalid transactions are filtered out and logged, but execution continues.
225-
func (k *KVExecutor) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight uint64, timestamp time.Time, prevStateRoot []byte) ([]byte, uint64, error) {
225+
func (k *KVExecutor) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight uint64, timestamp time.Time, prevStateRoot []byte) ([]byte, error) {
226226
select {
227227
case <-ctx.Done():
228-
return nil, 0, ctx.Err()
228+
return nil, ctx.Err()
229229
default:
230230
}
231231

232232
batch, err := k.db.Batch(ctx)
233233
if err != nil {
234-
return nil, 0, fmt.Errorf("failed to create database batch: %w", err)
234+
return nil, fmt.Errorf("failed to create database batch: %w", err)
235235
}
236236

237237
validTxCount := 0
@@ -274,7 +274,7 @@ func (k *KVExecutor) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight u
274274
err = batch.Put(ctx, dsKey, []byte(value))
275275
if err != nil {
276276
// This error is unlikely for Put unless the context is cancelled.
277-
return nil, 0, fmt.Errorf("failed to stage put operation in batch for key '%s': %w", key, err)
277+
return nil, fmt.Errorf("failed to stage put operation in batch for key '%s': %w", key, err)
278278
}
279279
validTxCount++
280280
}
@@ -287,18 +287,18 @@ func (k *KVExecutor) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight u
287287
// Commit the batch to apply all changes atomically
288288
err = batch.Commit(ctx)
289289
if err != nil {
290-
return nil, 0, fmt.Errorf("failed to commit transaction batch: %w", err)
290+
return nil, fmt.Errorf("failed to commit transaction batch: %w", err)
291291
}
292292

293293
// Compute the new state root *after* successful commit
294294
stateRoot, err := k.computeStateRoot(ctx)
295295
if err != nil {
296296
// This is problematic, state was changed but root calculation failed.
297297
// May need more robust error handling or recovery logic.
298-
return nil, 0, fmt.Errorf("failed to compute state root after executing transactions: %w", err)
298+
return nil, fmt.Errorf("failed to compute state root after executing transactions: %w", err)
299299
}
300300

301-
return stateRoot, 1024, nil
301+
return stateRoot, nil
302302
}
303303

304304
// SetFinal marks a block as finalized at the specified height.

apps/testapp/kv/kvexecutor_test.go

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,19 @@ func TestInitChain_Idempotency(t *testing.T) {
2020
chainID := "test-chain"
2121

2222
// First call initializes genesis state
23-
stateRoot1, maxBytes1, err := exec.InitChain(ctx, genesisTime, initialHeight, chainID)
23+
stateRoot1, err := exec.InitChain(ctx, genesisTime, initialHeight, chainID)
2424
if err != nil {
2525
t.Fatalf("InitChain failed on first call: %v", err)
2626
}
27-
if maxBytes1 != 1024 {
28-
t.Errorf("Expected maxBytes 1024, got %d", maxBytes1)
29-
}
3027

3128
// Second call should return the same genesis state root
32-
stateRoot2, maxBytes2, err := exec.InitChain(ctx, genesisTime, initialHeight, chainID)
29+
stateRoot2, err := exec.InitChain(ctx, genesisTime, initialHeight, chainID)
3330
if err != nil {
3431
t.Fatalf("InitChain failed on second call: %v", err)
3532
}
3633
if !bytes.Equal(stateRoot1, stateRoot2) {
3734
t.Errorf("Genesis state roots do not match: %s vs %s", stateRoot1, stateRoot2)
3835
}
39-
if maxBytes2 != 1024 {
40-
t.Errorf("Expected maxBytes 1024, got %d", maxBytes2)
41-
}
4236
}
4337

4438
func TestGetTxs(t *testing.T) {
@@ -58,43 +52,34 @@ func TestGetTxs(t *testing.T) {
5852
// though for buffered channels it should be immediate unless full.
5953
time.Sleep(10 * time.Millisecond)
6054

61-
// First call to GetTxs should retrieve the injected transactions
6255
txs, err := exec.GetTxs(ctx)
6356
if err != nil {
64-
t.Fatalf("GetTxs returned error on first call: %v", err)
57+
t.Fatalf("GetTxs returned error: %v", err)
6558
}
6659
if len(txs) != 2 {
67-
t.Errorf("Expected 2 transactions on first call, got %d", len(txs))
60+
t.Errorf("Expected 2 transactions, got %d", len(txs))
6861
}
69-
70-
// Verify the content (order might not be guaranteed depending on channel internals, but likely FIFO here)
71-
foundTx1 := false
72-
foundTx2 := false
73-
for _, tx := range txs {
74-
if reflect.DeepEqual(tx, tx1) {
75-
foundTx1 = true
76-
}
77-
if reflect.DeepEqual(tx, tx2) {
78-
foundTx2 = true
79-
}
62+
if !reflect.DeepEqual(txs[0], tx1) {
63+
t.Errorf("Expected first tx 'a=1', got %s", string(txs[0]))
8064
}
81-
if !foundTx1 || !foundTx2 {
82-
t.Errorf("Did not retrieve expected transactions. Got: %v", txs)
65+
if !reflect.DeepEqual(txs[1], tx2) {
66+
t.Errorf("Expected second tx 'b=2', got %s", string(txs[1]))
8367
}
8468

85-
// Second call to GetTxs should return no transactions as the channel was drained
86-
txsAfterDrain, err := exec.GetTxs(ctx)
69+
// GetTxs should drain the channel, so a second call should return empty or nil
70+
txsAgain, err := exec.GetTxs(ctx)
8771
if err != nil {
88-
t.Fatalf("GetTxs returned error on second call: %v", err)
72+
t.Fatalf("GetTxs (second call) returned error: %v", err)
8973
}
90-
if len(txsAfterDrain) != 0 {
91-
t.Errorf("Expected 0 transactions after drain, got %d", len(txsAfterDrain))
74+
if len(txsAgain) != 0 {
75+
t.Errorf("Expected 0 transactions on second call (drained), got %d", len(txsAgain))
9276
}
9377

94-
// Test injecting again after draining
78+
// Inject another transaction and verify it's available
9579
tx3 := []byte("c=3")
9680
exec.InjectTx(tx3)
9781
time.Sleep(10 * time.Millisecond)
82+
9883
txsAfterReinject, err := exec.GetTxs(ctx)
9984
if err != nil {
10085
t.Fatalf("GetTxs returned error after re-inject: %v", err)
@@ -120,13 +105,10 @@ func TestExecuteTxs_Valid(t *testing.T) {
120105
[]byte("key2=value2"),
121106
}
122107

123-
stateRoot, maxBytes, err := exec.ExecuteTxs(ctx, txs, 1, time.Now(), []byte(""))
108+
stateRoot, err := exec.ExecuteTxs(ctx, txs, 1, time.Now(), []byte(""))
124109
if err != nil {
125110
t.Fatalf("ExecuteTxs failed: %v", err)
126111
}
127-
if maxBytes != 1024 {
128-
t.Errorf("Expected maxBytes 1024, got %d", maxBytes)
129-
}
130112

131113
// Check that stateRoot contains the updated key-value pairs
132114
rootStr := string(stateRoot)
@@ -152,13 +134,10 @@ func TestExecuteTxs_Invalid(t *testing.T) {
152134
[]byte(""),
153135
}
154136

155-
stateRoot, maxBytes, err := exec.ExecuteTxs(ctx, txs, 1, time.Now(), []byte(""))
137+
stateRoot, err := exec.ExecuteTxs(ctx, txs, 1, time.Now(), []byte(""))
156138
if err != nil {
157139
t.Fatalf("ExecuteTxs should handle gibberish gracefully, got error: %v", err)
158140
}
159-
if maxBytes != 1024 {
160-
t.Errorf("Expected maxBytes 1024, got %d", maxBytes)
161-
}
162141

163142
// State root should still be computed (empty block is valid)
164143
if stateRoot == nil {
@@ -173,7 +152,7 @@ func TestExecuteTxs_Invalid(t *testing.T) {
173152
[]byte(""),
174153
}
175154

176-
stateRoot2, _, err := exec.ExecuteTxs(ctx, mixedTxs, 2, time.Now(), stateRoot)
155+
stateRoot2, err := exec.ExecuteTxs(ctx, mixedTxs, 2, time.Now(), stateRoot)
177156
if err != nil {
178157
t.Fatalf("ExecuteTxs should filter invalid transactions and process valid ones, got error: %v", err)
179158
}
@@ -213,7 +192,7 @@ func TestReservedKeysExcludedFromAppHash(t *testing.T) {
213192
ctx := context.Background()
214193

215194
// Initialize chain to set up genesis state (this writes genesis reserved keys)
216-
_, _, err = exec.InitChain(ctx, time.Now(), 1, "test-chain")
195+
_, err = exec.InitChain(ctx, time.Now(), 1, "test-chain")
217196
if err != nil {
218197
t.Fatalf("Failed to initialize chain: %v", err)
219198
}
@@ -223,7 +202,7 @@ func TestReservedKeysExcludedFromAppHash(t *testing.T) {
223202
[]byte("user/key1=value1"),
224203
[]byte("user/key2=value2"),
225204
}
226-
_, _, err = exec.ExecuteTxs(ctx, txs, 1, time.Now(), []byte(""))
205+
_, err = exec.ExecuteTxs(ctx, txs, 1, time.Now(), []byte(""))
227206
if err != nil {
228207
t.Fatalf("Failed to execute transactions: %v", err)
229208
}
@@ -279,7 +258,7 @@ func TestReservedKeysExcludedFromAppHash(t *testing.T) {
279258
moreTxs := [][]byte{
280259
[]byte("user/key3=value3"),
281260
}
282-
_, _, err = exec.ExecuteTxs(ctx, moreTxs, 2, time.Now(), stateRootAfterReservedKeyWrite)
261+
_, err = exec.ExecuteTxs(ctx, moreTxs, 2, time.Now(), stateRootAfterReservedKeyWrite)
283262
if err != nil {
284263
t.Fatalf("Failed to execute more transactions: %v", err)
285264
}

block/components_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ func TestExecutor_RealExecutionClientFailure_StopsNode(t *testing.T) {
201201

202202
// Mock InitChain to succeed initially
203203
mockExec.On("InitChain", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
204-
Return([]byte("state-root"), uint64(1024), nil).Once()
204+
Return([]byte("state-root"), nil).Once()
205205

206206
// Mock SetDAHeight to be called during initialization
207207
mockSeq.On("SetDAHeight", uint64(0)).Return().Once()
@@ -220,7 +220,7 @@ func TestExecutor_RealExecutionClientFailure_StopsNode(t *testing.T) {
220220
// Mock ExecuteTxs to fail with a critical error
221221
criticalError := errors.New("execution client RPC connection failed")
222222
mockExec.On("ExecuteTxs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
223-
Return(nil, uint64(0), criticalError).Maybe()
223+
Return(nil, criticalError).Maybe()
224224

225225
// Create aggregator node
226226
components, err := NewAggregatorComponents(

block/internal/common/replay.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func (s *Replayer) replayBlock(ctx context.Context, height uint64) error {
153153
Int("tx_count", len(rawTxs)).
154154
Msg("executing transactions on execution layer")
155155

156-
newAppHash, _, err := s.exec.ExecuteTxs(ctx, rawTxs, height, header.Time(), prevState.AppHash)
156+
newAppHash, err := s.exec.ExecuteTxs(ctx, rawTxs, height, header.Time(), prevState.AppHash)
157157
if err != nil {
158158
return fmt.Errorf("failed to execute transactions: %w", err)
159159
}

block/internal/common/replay_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func TestReplayer_SyncToHeight_ExecutorBehind(t *testing.T) {
8383

8484
// Expect ExecuteTxs to be called for height 100
8585
mockExec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, []byte("app-hash-99")).
86-
Return([]byte("app-hash-100"), uint64(1000), nil)
86+
Return([]byte("app-hash-100"), nil)
8787

8888
// Execute sync
8989
err := syncer.SyncToHeight(ctx, targetHeight)
@@ -272,7 +272,7 @@ func TestReplayer_SyncToHeight_MultipleBlocks(t *testing.T) {
272272

273273
// ExecuteTxs for current block
274274
mockExec.On("ExecuteTxs", mock.Anything, mock.Anything, height, mock.Anything, mock.Anything).
275-
Return([]byte("app-hash-"+string(rune('0'+height))), uint64(1000), nil).Once()
275+
Return([]byte("app-hash-"+string(rune('0'+height))), nil).Once()
276276
}
277277

278278
// Execute sync
@@ -321,7 +321,7 @@ func TestReplayer_ReplayBlock_FirstBlock(t *testing.T) {
321321

322322
// For first block, ExecuteTxs should be called with genesis app hash
323323
mockExec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(1), mock.Anything, []byte("app-hash-1")).
324-
Return([]byte("app-hash-1"), uint64(1000), nil)
324+
Return([]byte("app-hash-1"), nil)
325325

326326
// Call replayBlock directly (this is a private method, so we test it through SyncToHeight)
327327
mockExec.On("GetLatestHeight", mock.Anything).Return(uint64(0), nil)
@@ -398,7 +398,7 @@ func TestReplayer_AppHashMismatch(t *testing.T) {
398398

399399
// ExecuteTxs returns a different app hash than expected
400400
mockExec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, []byte("app-hash-99")).
401-
Return([]byte("different-app-hash"), uint64(1000), nil)
401+
Return([]byte("different-app-hash"), nil)
402402

403403
// Should fail with mismatch error
404404
err := syncer.SyncToHeight(ctx, targetHeight)

0 commit comments

Comments
 (0)