Skip to content

Commit 9089f94

Browse files
eth: add tx to locals only if it has a chance of acceptance (#31618)
This pull request improves error handling for local transaction submissions. Specifically, if a transaction fails with a temporary error but might be accepted later, the error will not be returned to the user; instead, the transaction will be tracked locally for resubmission. However, if the transaction fails with a permanent error (e.g., invalid transaction or insufficient balance), the error will be propagated to the user. These errors returned in the legacyPool are regarded as temporary failure: - `ErrOutOfOrderTxFromDelegated` - `txpool.ErrInflightTxLimitReached` - `ErrAuthorityReserved` - `txpool.ErrUnderpriced` - `ErrTxPoolOverflow` - `ErrFutureReplacePending` Notably, InsufficientBalance is also treated as a permanent error, as it’s highly unlikely that users will transfer funds into the sender account after submitting the transaction. Otherwise, users may be confused—seeing their transaction submitted but unaware that the sender lacks sufficient funds—and continue waiting for it to be included. --------- Co-authored-by: lightclient <[email protected]>
1 parent 074da25 commit 9089f94

File tree

15 files changed

+284
-152
lines changed

15 files changed

+284
-152
lines changed

core/txpool/blobpool/blobpool.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,8 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) {
13911391
switch {
13921392
case errors.Is(err, txpool.ErrUnderpriced):
13931393
addUnderpricedMeter.Mark(1)
1394+
case errors.Is(err, txpool.ErrTxGasPriceTooLow):
1395+
addUnderpricedMeter.Mark(1)
13941396
case errors.Is(err, core.ErrNonceTooLow):
13951397
addStaleMeter.Mark(1)
13961398
case errors.Is(err, core.ErrNonceTooHigh):

core/txpool/blobpool/blobpool_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ func TestAdd(t *testing.T) {
14841484
{ // New account, no previous txs, nonce 0, but blob fee cap too low
14851485
from: "alice",
14861486
tx: makeUnsignedTx(0, 1, 1, 0),
1487-
err: txpool.ErrUnderpriced,
1487+
err: txpool.ErrTxGasPriceTooLow,
14881488
},
14891489
{ // Same as above but blob fee cap equals minimum, should be accepted
14901490
from: "alice",

core/txpool/errors.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
package txpool
1818

19-
import "errors"
19+
import (
20+
"errors"
21+
)
2022

2123
var (
2224
// ErrAlreadyKnown is returned if the transactions is already contained
@@ -26,14 +28,19 @@ var (
2628
// ErrInvalidSender is returned if the transaction contains an invalid signature.
2729
ErrInvalidSender = errors.New("invalid sender")
2830

29-
// ErrUnderpriced is returned if a transaction's gas price is below the minimum
30-
// configured for the transaction pool.
31+
// ErrUnderpriced is returned if a transaction's gas price is too low to be
32+
// included in the pool. If the gas price is lower than the minimum configured
33+
// one for the transaction pool, use ErrTxGasPriceTooLow instead.
3134
ErrUnderpriced = errors.New("transaction underpriced")
3235

3336
// ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced
3437
// with a different one without the required price bump.
3538
ErrReplaceUnderpriced = errors.New("replacement transaction underpriced")
3639

40+
// ErrTxGasPriceTooLow is returned if a transaction's gas price is below the
41+
// minimum configured for the transaction pool.
42+
ErrTxGasPriceTooLow = errors.New("transaction gas price below minimum")
43+
3744
// ErrAccountLimitExceeded is returned if a transaction would exceed the number
3845
// allowed by a pool for a single account.
3946
ErrAccountLimitExceeded = errors.New("account limit exceeded")

core/txpool/legacypool/legacypool2_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,14 @@ func TestTransactionFutureAttack(t *testing.T) {
8282
// Create the pool to test the limit enforcement with
8383
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
8484
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
85+
8586
config := testTxPoolConfig
8687
config.GlobalQueue = 100
8788
config.GlobalSlots = 100
8889
pool := New(config, blockchain)
8990
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
9091
defer pool.Close()
92+
9193
fillPool(t, pool)
9294
pending, _ := pool.Stats()
9395
// Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops
@@ -180,7 +182,9 @@ func TestTransactionZAttack(t *testing.T) {
180182
ivPending := countInvalidPending()
181183
t.Logf("invalid pending: %d\n", ivPending)
182184

183-
// Now, DETER-Z attack starts, let's add a bunch of expensive non-executables (from N accounts) along with balance-overdraft txs (from one account), and see if the pending-count drops
185+
// Now, DETER-Z attack starts, let's add a bunch of expensive non-executables
186+
// (from N accounts) along with balance-overdraft txs (from one account), and
187+
// see if the pending-count drops
184188
for j := 0; j < int(pool.config.GlobalQueue); j++ {
185189
futureTxs := types.Transactions{}
186190
key, _ := crypto.GenerateKey()

core/txpool/legacypool/legacypool_test.go

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ func TestInvalidTransactions(t *testing.T) {
413413

414414
tx = transaction(1, 100000, key)
415415
pool.gasTip.Store(uint256.NewInt(1000))
416-
if err, want := pool.addRemote(tx), txpool.ErrUnderpriced; !errors.Is(err, want) {
416+
if err, want := pool.addRemote(tx), txpool.ErrTxGasPriceTooLow; !errors.Is(err, want) {
417417
t.Errorf("want %v have %v", want, err)
418418
}
419419
}
@@ -484,7 +484,7 @@ func TestNegativeValue(t *testing.T) {
484484
tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key)
485485
from, _ := deriveSender(tx)
486486
testAddBalance(pool, from, big.NewInt(1))
487-
if err := pool.addRemote(tx); err != txpool.ErrNegativeValue {
487+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrNegativeValue) {
488488
t.Error("expected", txpool.ErrNegativeValue, "got", err)
489489
}
490490
}
@@ -497,7 +497,7 @@ func TestTipAboveFeeCap(t *testing.T) {
497497

498498
tx := dynamicFeeTx(0, 100, big.NewInt(1), big.NewInt(2), key)
499499

500-
if err := pool.addRemote(tx); err != core.ErrTipAboveFeeCap {
500+
if err := pool.addRemote(tx); !errors.Is(err, core.ErrTipAboveFeeCap) {
501501
t.Error("expected", core.ErrTipAboveFeeCap, "got", err)
502502
}
503503
}
@@ -512,12 +512,12 @@ func TestVeryHighValues(t *testing.T) {
512512
veryBigNumber.Lsh(veryBigNumber, 300)
513513

514514
tx := dynamicFeeTx(0, 100, big.NewInt(1), veryBigNumber, key)
515-
if err := pool.addRemote(tx); err != core.ErrTipVeryHigh {
515+
if err := pool.addRemote(tx); !errors.Is(err, core.ErrTipVeryHigh) {
516516
t.Error("expected", core.ErrTipVeryHigh, "got", err)
517517
}
518518

519519
tx2 := dynamicFeeTx(0, 100, veryBigNumber, big.NewInt(1), key)
520-
if err := pool.addRemote(tx2); err != core.ErrFeeCapVeryHigh {
520+
if err := pool.addRemote(tx2); !errors.Is(err, core.ErrFeeCapVeryHigh) {
521521
t.Error("expected", core.ErrFeeCapVeryHigh, "got", err)
522522
}
523523
}
@@ -1424,14 +1424,14 @@ func TestRepricing(t *testing.T) {
14241424
t.Fatalf("pool internal state corrupted: %v", err)
14251425
}
14261426
// Check that we can't add the old transactions back
1427-
if err := pool.addRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); !errors.Is(err, txpool.ErrUnderpriced) {
1428-
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced)
1427+
if err := pool.addRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
1428+
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow)
14291429
}
1430-
if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); !errors.Is(err, txpool.ErrUnderpriced) {
1431-
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced)
1430+
if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
1431+
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow)
14321432
}
1433-
if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); !errors.Is(err, txpool.ErrUnderpriced) {
1434-
t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced)
1433+
if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
1434+
t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow)
14351435
}
14361436
if err := validateEvents(events, 0); err != nil {
14371437
t.Fatalf("post-reprice event firing failed: %v", err)
@@ -1476,14 +1476,14 @@ func TestMinGasPriceEnforced(t *testing.T) {
14761476
tx := pricedTransaction(0, 100000, big.NewInt(2), key)
14771477
pool.SetGasTip(big.NewInt(tx.GasPrice().Int64() + 1))
14781478

1479-
if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrUnderpriced) {
1479+
if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
14801480
t.Fatalf("Min tip not enforced")
14811481
}
14821482

14831483
tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), key)
14841484
pool.SetGasTip(big.NewInt(tx.GasTipCap().Int64() + 1))
14851485

1486-
if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrUnderpriced) {
1486+
if err := pool.Add([]*types.Transaction{tx}, true)[0]; !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
14871487
t.Fatalf("Min tip not enforced")
14881488
}
14891489
}
@@ -1560,16 +1560,16 @@ func TestRepricingDynamicFee(t *testing.T) {
15601560
}
15611561
// Check that we can't add the old transactions back
15621562
tx := pricedTransaction(1, 100000, big.NewInt(1), keys[0])
1563-
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) {
1564-
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced)
1563+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
1564+
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow)
15651565
}
15661566
tx = dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1])
1567-
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) {
1568-
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced)
1567+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
1568+
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow)
15691569
}
15701570
tx = dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2])
1571-
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrUnderpriced) {
1572-
t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrUnderpriced)
1571+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrTxGasPriceTooLow) {
1572+
t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, txpool.ErrTxGasPriceTooLow)
15731573
}
15741574
if err := validateEvents(events, 0); err != nil {
15751575
t.Fatalf("post-reprice event firing failed: %v", err)
@@ -1673,7 +1673,7 @@ func TestUnderpricing(t *testing.T) {
16731673
t.Fatalf("failed to add well priced transaction: %v", err)
16741674
}
16751675
// Ensure that replacing a pending transaction with a future transaction fails
1676-
if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != ErrFutureReplacePending {
1676+
if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); !errors.Is(err, ErrFutureReplacePending) {
16771677
t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, ErrFutureReplacePending)
16781678
}
16791679
pending, queued = pool.Stats()
@@ -1995,7 +1995,7 @@ func TestReplacement(t *testing.T) {
19951995
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil {
19961996
t.Fatalf("failed to add original cheap pending transaction: %v", err)
19971997
}
1998-
if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != txpool.ErrReplaceUnderpriced {
1998+
if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
19991999
t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced)
20002000
}
20012001
if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil {
@@ -2008,7 +2008,7 @@ func TestReplacement(t *testing.T) {
20082008
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil {
20092009
t.Fatalf("failed to add original proper pending transaction: %v", err)
20102010
}
2011-
if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != txpool.ErrReplaceUnderpriced {
2011+
if err := pool.addRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
20122012
t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced)
20132013
}
20142014
if err := pool.addRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil {
@@ -2022,7 +2022,7 @@ func TestReplacement(t *testing.T) {
20222022
if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil {
20232023
t.Fatalf("failed to add original cheap queued transaction: %v", err)
20242024
}
2025-
if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != txpool.ErrReplaceUnderpriced {
2025+
if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
20262026
t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced)
20272027
}
20282028
if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil {
@@ -2032,7 +2032,7 @@ func TestReplacement(t *testing.T) {
20322032
if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil {
20332033
t.Fatalf("failed to add original proper queued transaction: %v", err)
20342034
}
2035-
if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != txpool.ErrReplaceUnderpriced {
2035+
if err := pool.addRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
20362036
t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, txpool.ErrReplaceUnderpriced)
20372037
}
20382038
if err := pool.addRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil {
@@ -2096,7 +2096,7 @@ func TestReplacementDynamicFee(t *testing.T) {
20962096
}
20972097
// 2. Don't bump tip or feecap => discard
20982098
tx = dynamicFeeTx(nonce, 100001, big.NewInt(2), big.NewInt(1), key)
2099-
if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced {
2099+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
21002100
t.Fatalf("original cheap %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced)
21012101
}
21022102
// 3. Bump both more than min => accept
@@ -2117,24 +2117,25 @@ func TestReplacementDynamicFee(t *testing.T) {
21172117
if err := pool.addRemoteSync(tx); err != nil {
21182118
t.Fatalf("failed to add original proper %s transaction: %v", stage, err)
21192119
}
2120+
21202121
// 6. Bump tip max allowed so it's still underpriced => discard
21212122
tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold-1), key)
2122-
if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced {
2123+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
21232124
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced)
21242125
}
21252126
// 7. Bump fee cap max allowed so it's still underpriced => discard
21262127
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(gasTipCap), key)
2127-
if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced {
2128+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
21282129
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced)
21292130
}
21302131
// 8. Bump tip min for acceptance => accept
21312132
tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold), key)
2132-
if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced {
2133+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
21332134
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced)
21342135
}
21352136
// 9. Bump fee cap min for acceptance => accept
21362137
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(gasTipCap), key)
2137-
if err := pool.addRemote(tx); err != txpool.ErrReplaceUnderpriced {
2138+
if err := pool.addRemote(tx); !errors.Is(err, txpool.ErrReplaceUnderpriced) {
21382139
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, txpool.ErrReplaceUnderpriced)
21392140
}
21402141
// 10. Check events match expected (3 new executable txs during pending, 0 during queue)

core/txpool/locals/errors.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2025 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package locals
18+
19+
import (
20+
"errors"
21+
22+
"github.com/ethereum/go-ethereum/core/txpool"
23+
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
24+
)
25+
26+
// IsTemporaryReject determines whether the given error indicates a temporary
27+
// reason to reject a transaction from being included in the txpool. The result
28+
// may change if the txpool's state changes later.
29+
func IsTemporaryReject(err error) bool {
30+
switch {
31+
case errors.Is(err, legacypool.ErrOutOfOrderTxFromDelegated):
32+
return true
33+
case errors.Is(err, txpool.ErrInflightTxLimitReached):
34+
return true
35+
case errors.Is(err, legacypool.ErrAuthorityReserved):
36+
return true
37+
case errors.Is(err, txpool.ErrUnderpriced):
38+
return true
39+
case errors.Is(err, legacypool.ErrTxPoolOverflow):
40+
return true
41+
case errors.Is(err, legacypool.ErrFutureReplacePending):
42+
return true
43+
default:
44+
return false
45+
}
46+
}

core/txpool/locals/tx_tracker.go

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -74,32 +74,22 @@ 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) error {
78-
return tracker.TrackAll([]*types.Transaction{tx})[0]
77+
func (tracker *TxTracker) Track(tx *types.Transaction) {
78+
tracker.TrackAll([]*types.Transaction{tx})
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) []error {
83+
func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
8484
tracker.mu.Lock()
8585
defer tracker.mu.Unlock()
8686

87-
var errors []error
8887
for _, tx := range txs {
8988
if tx.Type() == types.BlobTxType {
90-
errors = append(errors, nil)
91-
continue
92-
}
93-
// Ignore the transactions which are failed for fundamental
94-
// validation such as invalid parameters.
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)
9889
continue
9990
}
10091
// If we're already tracking it, it's a no-op
10192
if _, ok := tracker.all[tx.Hash()]; ok {
102-
errors = append(errors, nil)
10393
continue
10494
}
10595
// Theoretically, checking the error here is unnecessary since sender recovery
@@ -108,11 +98,8 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error {
10898
// Therefore, the error is still checked just in case.
10999
addr, err := types.Sender(tracker.signer, tx)
110100
if err != nil {
111-
errors = append(errors, err)
112101
continue
113102
}
114-
errors = append(errors, nil)
115-
116103
tracker.all[tx.Hash()] = tx
117104
if tracker.byAddr[addr] == nil {
118105
tracker.byAddr[addr] = legacypool.NewSortedMap()
@@ -124,7 +111,6 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) []error {
124111
}
125112
}
126113
localGauge.Update(int64(len(tracker.all)))
127-
return errors
128114
}
129115

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

0 commit comments

Comments
 (0)