Skip to content

Commit 159ee7d

Browse files
committed
core/txpool/local, eth: return no error if transaction fails stateful check
1 parent c6aae24 commit 159ee7d

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

core/txpool/locals/tx_tracker.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,31 +74,41 @@ func New(journalPath string, journalTime time.Duration, chainConfig *params.Chai
7474

7575
// Track adds a transaction to the tracked set.
7676
// Note: blob-type transactions are ignored.
77-
func (tracker *TxTracker) Track(tx *types.Transaction) {
78-
tracker.TrackAll([]*types.Transaction{tx})
77+
func (tracker *TxTracker) Track(tx *types.Transaction) error {
78+
return tracker.TrackAll([]*types.Transaction{tx})[0]
7979
}
8080

8181
// TrackAll adds a list of transactions to the tracked set.
8282
// Note: blob-type transactions are ignored.
83-
func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
83+
func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error {
8484
tracker.mu.Lock()
8585
defer tracker.mu.Unlock()
8686

87+
var errors []error
8788
for _, tx := range txs {
8889
if tx.Type() == types.BlobTxType {
90+
errors = append(errors, nil)
8991
continue
9092
}
9193
// Ignore the transactions which are failed for fundamental
9294
// validation such as invalid parameters.
93-
if tracker.pool.ValidateTxBasics(tx) != nil {
95+
if err := tracker.pool.ValidateTxBasics(tx); err != nil {
96+
log.Debug("Invalid transaction submitted", "hash", tx.Hash(), "err", err)
97+
errors = append(errors, err)
9498
continue
9599
}
96100
// If we're already tracking it, it's a no-op
97101
if _, ok := tracker.all[tx.Hash()]; ok {
102+
errors = append(errors, nil)
98103
continue
99104
}
105+
// Theoretically, checking the error here is unnecessary since sender recovery
106+
// is already part of basic validation. However, retrieving the sender address
107+
// from the transaction cache is effectively a no-op if it was previously verified.
108+
// Therefore, the error is still checked just in case.
100109
addr, err := types.Sender(tracker.signer, tx)
101-
if err != nil { // Ignore this tx
110+
if err != nil {
111+
errors = append(errors, err)
102112
continue
103113
}
104114
tracker.all[tx.Hash()] = tx
@@ -112,6 +122,7 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
112122
}
113123
}
114124
localGauge.Update(int64(len(tracker.all)))
125+
return errors
115126
}
116127

117128
// recheck checks and returns any transactions that needs to be resubmitted.

eth/api_backend.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,15 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri
273273

274274
func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
275275
if locals := b.eth.localTxTracker; locals != nil {
276-
locals.Track(signedTx)
276+
if err := locals.Track(signedTx); err != nil {
277+
return err
278+
}
277279
}
278-
// TODO(rjl493456442): If a transaction fails stateful validation (e.g., no
279-
// available slot), an error will be returned to the user. However, locally
280-
// submitted transactions may be resubmitted later via the local tracker, which
281-
// could cause confusion that a previously "rejected" transaction is later
282-
// accepted.
283-
return b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0]
280+
// No error will be returned to user if the transaction fails stateful
281+
// validation (e.g., no available slot), as the locally submitted transactions
282+
// may be resubmitted later via the local tracker.
283+
b.eth.txPool.Add([]*types.Transaction{signedTx}, false)
284+
return nil
284285
}
285286

286287
func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {

0 commit comments

Comments
 (0)