Skip to content

Commit fd15c95

Browse files
committed
Merge branch 'mpeter/submitted-tx-validations' into mpeter/backport-submitted-tx-validations
2 parents 7a6c8a5 + 0b94bc1 commit fd15c95

5 files changed

Lines changed: 54 additions & 45 deletions

File tree

api/utils.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ func resolveBlockTag(
2929
if number, ok := blockNumberOrHash.Number(); ok {
3030
height, err := resolveBlockNumber(number, blocksDB)
3131
if err != nil {
32-
logger.Error().Err(err).
33-
Stringer("block_number", number).
34-
Msg("failed to resolve block by number")
3532
return 0, err
3633
}
3734
return height, nil
@@ -40,9 +37,6 @@ func resolveBlockTag(
4037
if hash, ok := blockNumberOrHash.Hash(); ok {
4138
height, err := blocksDB.GetHeightByID(hash)
4239
if err != nil {
43-
logger.Error().Err(err).
44-
Stringer("block_hash", hash).
45-
Msg("failed to resolve block by hash")
4640
return 0, err
4741
}
4842
return height, nil

services/requester/batch_tx_pool.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package requester
33
import (
44
"context"
55
"encoding/hex"
6-
"fmt"
76
"slices"
87
"sort"
98
"sync"
@@ -19,13 +18,12 @@ import (
1918
"github.com/onflow/flow-evm-gateway/config"
2019
"github.com/onflow/flow-evm-gateway/metrics"
2120
"github.com/onflow/flow-evm-gateway/models"
22-
errs "github.com/onflow/flow-evm-gateway/models/errors"
2321
"github.com/onflow/flow-evm-gateway/services/requester/keystore"
2422
)
2523

2624
const (
2725
eoaActivityCacheSize = 10_000
28-
maxTrackedTxNoncesPerEOA = 15
26+
maxTrackedTxNoncesPerEOA = 30
2927
)
3028

3129
type pooledEvmTx struct {
@@ -129,14 +127,15 @@ func (t *BatchTxPool) Add(
129127
eoaActivity, found := t.eoaActivityCache.Get(from)
130128
nonce := tx.Nonce()
131129

132-
// Reject transactions that have already been submitted,
130+
// Skip transactions that have been already submitted,
133131
// as they are *likely* to fail.
134132
if found && slices.Contains(eoaActivity.txNonces, nonce) {
135-
return fmt.Errorf(
136-
"%w: a tx with nonce %d has already been submitted",
137-
errs.ErrInvalid,
138-
nonce,
139-
)
133+
t.logger.Info().
134+
Str("evm_tx", tx.Hash().Hex()).
135+
Str("from", from.Hex()).
136+
Uint64("nonce", nonce).
137+
Msg("tx with same nonce has been already submitted")
138+
return nil
140139
}
141140

142141
// Scenarios
@@ -185,16 +184,25 @@ func (t *BatchTxPool) Add(
185184
}
186185

187186
if err != nil {
187+
t.logger.Error().Err(err).Msgf(
188+
"failed to submit single Flow transaction for EOA: %s",
189+
from.Hex(),
190+
)
188191
return err
189192
}
190193

194+
t.txMux.Lock()
195+
defer t.txMux.Unlock()
196+
191197
// Update metadata for the last EOA activity only on successful add/submit.
198+
eoaActivity, _ = t.eoaActivityCache.Get(from)
192199
eoaActivity.lastSubmission = time.Now()
193200
eoaActivity.txNonces = append(eoaActivity.txNonces, nonce)
194201
// To avoid the slice of nonces from growing indefinitely,
195-
// maintain only a handful of the last tx nonces.
202+
// keep only the last `maxTrackedTxNoncesPerEOA` nonces.
196203
if len(eoaActivity.txNonces) > maxTrackedTxNoncesPerEOA {
197-
eoaActivity.txNonces = eoaActivity.txNonces[1:]
204+
firstKeep := len(eoaActivity.txNonces) - maxTrackedTxNoncesPerEOA
205+
eoaActivity.txNonces = eoaActivity.txNonces[firstKeep:]
198206
}
199207

200208
t.eoaActivityCache.Add(from, eoaActivity)
@@ -227,7 +235,7 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
227235
)
228236
if err != nil {
229237
t.logger.Error().Err(err).Msgf(
230-
"failed to submit Flow transaction from BatchTxPool for EOA: %s",
238+
"failed to submit batch Flow transaction for EOA: %s",
231239
address.Hex(),
232240
)
233241
continue
@@ -274,6 +282,9 @@ func (t *BatchTxPool) batchSubmitTransactionsForSameAddress(
274282
}
275283

276284
if err := t.client.SendTransaction(ctx, *flowTx); err != nil {
285+
// If there was any error while sending the transaction,
286+
// we record all transactions as dropped.
287+
t.collector.TransactionsDropped(len(hexEncodedTxs))
277288
return err
278289
}
279290

@@ -305,6 +316,9 @@ func (t *BatchTxPool) submitSingleTransaction(
305316
}
306317

307318
if err := t.client.SendTransaction(ctx, *flowTx); err != nil {
319+
// If there was any error while sending the transaction,
320+
// we record it as a dropped transaction.
321+
t.collector.TransactionsDropped(1)
308322
return err
309323
}
310324

services/requester/requester.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func (e *EVM) SendRawTransaction(ctx context.Context, data []byte) (common.Hash,
238238
}
239239

240240
e.logger.Info().
241-
Str("evm-id", tx.Hash().Hex()).
241+
Str("evm_tx", tx.Hash().Hex()).
242242
Str("to", to).
243243
Str("from", from.Hex()).
244244
Str("value", tx.Value().String()).

services/requester/single_tx_pool.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ func (t *SingleTxPool) Add(
9595
) error {
9696
t.txPublisher.Publish(tx) // publish pending transaction event
9797

98+
from, err := models.DeriveTxSender(tx)
99+
if err != nil {
100+
return err
101+
}
102+
98103
txData, err := tx.MarshalBinary()
99104
if err != nil {
100105
return err
@@ -120,10 +125,21 @@ func (t *SingleTxPool) Add(
120125
// If there was any error during the transaction build
121126
// process, we record it as a dropped transaction.
122127
t.collector.TransactionsDropped(1)
128+
t.logger.Error().Err(err).Msgf(
129+
"failed to build Flow transaction for EOA: %s",
130+
from.Hex(),
131+
)
123132
return err
124133
}
125134

126135
if err := t.client.SendTransaction(ctx, *flowTx); err != nil {
136+
// If there was any error while sending the transaction,
137+
// we record it as a dropped transaction.
138+
t.collector.TransactionsDropped(1)
139+
t.logger.Error().Err(err).Msgf(
140+
"failed to submit Flow transaction for EOA: %s",
141+
from.Hex(),
142+
)
127143
return err
128144
}
129145

@@ -149,8 +165,8 @@ func (t *SingleTxPool) Add(
149165
}
150166

151167
t.logger.Error().Err(res.Error).
152-
Str("flow-id", flowTx.ID().String()).
153-
Str("evm-id", tx.Hash().Hex()).
168+
Str("flow_tx", flowTx.ID().String()).
169+
Str("evm_tx", tx.Hash().Hex()).
154170
Msg("flow transaction error")
155171

156172
// hide specific cause since it's an implementation issue

tests/tx_batching_test.go

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -528,42 +528,27 @@ func Test_TransactionSubmissionWithPreviouslySubmittedTransactions(t *testing.T)
528528
testAddr := common.HexToAddress("0x061B63D29332e4de81bD9F51A48609824CD113a8")
529529
nonces := []uint64{0, 1, 2, 3, 2, 3, 4, 5}
530530

531-
var errors []error
532531
hashes := []common.Hash{}
533532
// transfer some funds to the test address
533+
transferAmount := int64(1_000_000_000)
534534
for _, nonce := range nonces {
535-
signed, _, err := evmSign(big.NewInt(1_000_000_000), 23_500, eoaKey, nonce, &testAddr, nil)
535+
signed, _, err := evmSign(big.NewInt(transferAmount), 23_500, eoaKey, nonce, &testAddr, nil)
536536
require.NoError(t, err)
537537

538538
txHash, err := rpcTester.sendRawTx(signed)
539-
if err != nil {
540-
errors = append(errors, err)
541-
} else {
542-
hashes = append(hashes, txHash)
543-
}
539+
require.NoError(t, err)
540+
hashes = append(hashes, txHash)
544541
}
545542

546-
require.Len(t, errors, 2)
547-
assert.ErrorContains(
548-
t,
549-
errors[0],
550-
"a tx with nonce 2 has already been submitted",
551-
)
552-
assert.ErrorContains(
553-
t,
554-
errors[1],
555-
"a tx with nonce 3 has already been submitted",
556-
)
543+
expectedBalance := big.NewInt(6 * transferAmount)
557544

558545
assert.Eventually(t, func() bool {
559-
for _, h := range hashes {
560-
rcp, err := rpcTester.getReceipt(h.String())
561-
if err != nil || rcp == nil || rcp.Status != 1 {
562-
return false
563-
}
546+
balance, err := rpcTester.getBalance(testAddr)
547+
if err != nil {
548+
return false
564549
}
565550

566-
return true
551+
return balance.Cmp(expectedBalance) == 0
567552
}, time.Second*15, time.Second*1, "all transactions were not executed")
568553
}
569554

0 commit comments

Comments
 (0)