core/txpool: add eip2681 check for incoming transactions #32726 (#1594)

This commit is contained in:
wit liu 2025-10-08 12:51:48 +08:00 committed by GitHub
parent 7c5d2a45da
commit e5c480f234
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 53 additions and 0 deletions

View file

@ -663,6 +663,10 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
if err != nil {
return ErrInvalidSender
}
// Limit nonce to 2^64-1 per EIP-2681
if tx.Nonce()+1 < tx.Nonce() {
return core.ErrNonceMax
}
// Drop non-local transactions under our own minimal accepted gas price or tip
if !local {
isUnderpriced := false

View file

@ -18,7 +18,9 @@ package txpool
import (
"crypto/ecdsa"
"errors"
"fmt"
"math"
"math/big"
"math/rand"
"os"
@ -403,6 +405,53 @@ func TestNegativeValue(t *testing.T) {
}
}
// TestValidateTransactionEIP2681 tests that the pool correctly validates transactions
// according to EIP-2681, which limits the nonce to a maximum value of 2^64 - 1.
func TestValidateTransactionEIP2681(t *testing.T) {
t.Parallel()
pool, key := setupPool()
defer pool.Stop()
addr := crypto.PubkeyToAddress(key.PublicKey)
testAddBalance(pool, addr, big.NewInt(2e18))
to := common.HexToAddress("0x0000000000000000000000000000000000000001")
tests := []struct {
name string
nonce uint64
value *big.Int
gas uint64
gasPrice *big.Int
wantErr error
}{
{"nonce 0", 0, big.NewInt(1e18), 21000, big.NewInt(2e10), nil},
{"nonce 1", 1, big.NewInt(1e18), 21000, big.NewInt(2e10), nil},
{"EIP-2681 overflow", math.MaxUint64, big.NewInt(1e18), 21000, big.NewInt(2e10), core.ErrNonceMax},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tx := types.NewTx(&types.LegacyTx{
Nonce: tt.nonce,
To: &to,
Value: tt.value,
Gas: tt.gas,
GasPrice: tt.gasPrice,
})
signedTx, _ := types.SignTx(tx, types.HomesteadSigner{}, key)
err := pool.validateTx(signedTx, true)
if tt.wantErr == nil && err != nil {
t.Errorf("expected nil, got %v", err)
} else if tt.wantErr != nil && !errors.Is(err, tt.wantErr) {
t.Errorf("expected %v, got %v", tt.wantErr, err)
}
})
}
}
func TestTipAboveFeeCap(t *testing.T) {
t.Parallel()