mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
legacypool: use uint256 instead of big
This commit is contained in:
parent
cd0770ea68
commit
af03289998
5 changed files with 39 additions and 26 deletions
|
|
@ -34,3 +34,13 @@ var (
|
||||||
|
|
||||||
U2560 = uint256.NewInt(0)
|
U2560 = uint256.NewInt(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Uint1 = uint256.NewInt(1)
|
||||||
|
Uint2 = uint256.NewInt(2)
|
||||||
|
Uint3 = uint256.NewInt(3)
|
||||||
|
Uint0 = uint256.NewInt(0)
|
||||||
|
Uint32 = uint256.NewInt(32)
|
||||||
|
Uint256 = uint256.NewInt(256)
|
||||||
|
Uint257 = uint256.NewInt(257)
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -202,7 +203,7 @@ type LegacyPool struct {
|
||||||
config Config
|
config Config
|
||||||
chainconfig *params.ChainConfig
|
chainconfig *params.ChainConfig
|
||||||
chain BlockChain
|
chain BlockChain
|
||||||
gasTip atomic.Pointer[big.Int]
|
gasTip atomic.Pointer[uint256.Int]
|
||||||
txFeed event.Feed
|
txFeed event.Feed
|
||||||
signer types.Signer
|
signer types.Signer
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
@ -292,7 +293,7 @@ func (pool *LegacyPool) Init(gasTip *big.Int, head *types.Header, reserve txpool
|
||||||
pool.reserve = reserve
|
pool.reserve = reserve
|
||||||
|
|
||||||
// Set the basic pool parameters
|
// Set the basic pool parameters
|
||||||
pool.gasTip.Store(gasTip)
|
pool.gasTip.Store(uint256.MustFromBig(gasTip))
|
||||||
|
|
||||||
// Initialize the state with head block, or fallback to empty one in
|
// Initialize the state with head block, or fallback to empty one in
|
||||||
// case the head state is not available(might occur when node is not
|
// case the head state is not available(might occur when node is not
|
||||||
|
|
@ -434,10 +435,10 @@ func (pool *LegacyPool) SetGasTip(tip *big.Int) {
|
||||||
defer pool.mu.Unlock()
|
defer pool.mu.Unlock()
|
||||||
|
|
||||||
old := pool.gasTip.Load()
|
old := pool.gasTip.Load()
|
||||||
pool.gasTip.Store(new(big.Int).Set(tip))
|
pool.gasTip.Store(uint256.MustFromBig(tip))
|
||||||
|
|
||||||
// If the min miner fee increased, remove transactions below the new threshold
|
// If the min miner fee increased, remove transactions below the new threshold
|
||||||
if tip.Cmp(old) > 0 {
|
if uint256.MustFromBig(tip).Cmp(old) > 0 {
|
||||||
// pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead
|
// pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead
|
||||||
drop := pool.all.RemotesBelowTip(tip)
|
drop := pool.all.RemotesBelowTip(tip)
|
||||||
for _, tx := range drop {
|
for _, tx := range drop {
|
||||||
|
|
@ -532,7 +533,7 @@ func (pool *LegacyPool) Pending(enforceTips bool) map[common.Address][]*txpool.L
|
||||||
// If the miner requests tip enforcement, cap the lists now
|
// If the miner requests tip enforcement, cap the lists now
|
||||||
if enforceTips && !pool.locals.contains(addr) {
|
if enforceTips && !pool.locals.contains(addr) {
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
if tx.EffectiveGasTipIntCmp(pool.gasTip.Load(), pool.priced.urgent.baseFee) < 0 {
|
if tx.EffectiveGasTipIntCmp(pool.gasTip.Load().ToBig(), pool.priced.urgent.baseFee) < 0 {
|
||||||
txs = txs[:i]
|
txs = txs[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -594,7 +595,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
|
||||||
1<<types.AccessListTxType |
|
1<<types.AccessListTxType |
|
||||||
1<<types.DynamicFeeTxType,
|
1<<types.DynamicFeeTxType,
|
||||||
MaxSize: txMaxSize,
|
MaxSize: txMaxSize,
|
||||||
MinTip: pool.gasTip.Load(),
|
MinTip: pool.gasTip.Load().ToBig(),
|
||||||
}
|
}
|
||||||
if local {
|
if local {
|
||||||
opts.MinTip = new(big.Int)
|
opts.MinTip = new(big.Int)
|
||||||
|
|
@ -624,7 +625,7 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error {
|
||||||
},
|
},
|
||||||
ExistingExpenditure: func(addr common.Address) *big.Int {
|
ExistingExpenditure: func(addr common.Address) *big.Int {
|
||||||
if list := pool.pending[addr]; list != nil {
|
if list := pool.pending[addr]; list != nil {
|
||||||
return list.totalcost
|
return list.totalcost.ToBig()
|
||||||
}
|
}
|
||||||
return new(big.Int)
|
return new(big.Int)
|
||||||
},
|
},
|
||||||
|
|
@ -1441,7 +1442,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
||||||
}
|
}
|
||||||
log.Trace("Removed old queued transactions", "count", len(forwards))
|
log.Trace("Removed old queued transactions", "count", len(forwards))
|
||||||
// Drop all transactions that are too costly (low balance or out of gas)
|
// Drop all transactions that are too costly (low balance or out of gas)
|
||||||
drops, _ := list.Filter(pool.currentState.GetBalance(addr).ToBig(), gasLimit)
|
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||||
for _, tx := range drops {
|
for _, tx := range drops {
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
pool.all.Remove(hash)
|
pool.all.Remove(hash)
|
||||||
|
|
@ -1642,7 +1643,7 @@ func (pool *LegacyPool) demoteUnexecutables() {
|
||||||
log.Trace("Removed old pending transaction", "hash", hash)
|
log.Trace("Removed old pending transaction", "hash", hash)
|
||||||
}
|
}
|
||||||
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
|
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
|
||||||
drops, invalids := list.Filter(pool.currentState.GetBalance(addr).ToBig(), gasLimit)
|
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||||
for _, tx := range drops {
|
for _, tx := range drops {
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
log.Trace("Removed unpayable pending transaction", "hash", hash)
|
log.Trace("Removed unpayable pending transaction", "hash", hash)
|
||||||
|
|
|
||||||
|
|
@ -199,9 +199,6 @@ func validatePoolInternals(pool *LegacyPool) error {
|
||||||
if nonce := pool.pendingNonces.get(addr); nonce != last+1 {
|
if nonce := pool.pendingNonces.get(addr); nonce != last+1 {
|
||||||
return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
|
return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
|
||||||
}
|
}
|
||||||
if txs.totalcost.Cmp(common.Big0) < 0 {
|
|
||||||
return fmt.Errorf("totalcost went negative: %v", txs.totalcost)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +346,7 @@ func TestInvalidTransactions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tx = transaction(1, 100000, key)
|
tx = transaction(1, 100000, key)
|
||||||
pool.gasTip.Store(big.NewInt(1000))
|
pool.gasTip.Store(uint256.NewInt(1000))
|
||||||
if err, want := pool.addRemote(tx), txpool.ErrUnderpriced; !errors.Is(err, want) {
|
if err, want := pool.addRemote(tx), txpool.ErrUnderpriced; !errors.Is(err, want) {
|
||||||
t.Errorf("want %v have %v", want, err)
|
t.Errorf("want %v have %v", want, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
|
// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
|
||||||
|
|
@ -271,9 +272,9 @@ type list struct {
|
||||||
strict bool // Whether nonces are strictly continuous or not
|
strict bool // Whether nonces are strictly continuous or not
|
||||||
txs *sortedMap // Heap indexed sorted hash map of the transactions
|
txs *sortedMap // Heap indexed sorted hash map of the transactions
|
||||||
|
|
||||||
costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
|
costcap *uint256.Int // Price of the highest costing transaction (reset only if exceeds balance)
|
||||||
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
|
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
|
||||||
totalcost *big.Int // Total cost of all transactions in the list
|
totalcost *uint256.Int // Total cost of all transactions in the list
|
||||||
}
|
}
|
||||||
|
|
||||||
// newList create a new transaction list for maintaining nonce-indexable fast,
|
// newList create a new transaction list for maintaining nonce-indexable fast,
|
||||||
|
|
@ -282,8 +283,8 @@ func newList(strict bool) *list {
|
||||||
return &list{
|
return &list{
|
||||||
strict: strict,
|
strict: strict,
|
||||||
txs: newSortedMap(),
|
txs: newSortedMap(),
|
||||||
costcap: new(big.Int),
|
costcap: new(uint256.Int),
|
||||||
totalcost: new(big.Int),
|
totalcost: new(uint256.Int),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -325,10 +326,11 @@ func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transa
|
||||||
l.subTotalCost([]*types.Transaction{old})
|
l.subTotalCost([]*types.Transaction{old})
|
||||||
}
|
}
|
||||||
// Add new tx cost to totalcost
|
// Add new tx cost to totalcost
|
||||||
l.totalcost.Add(l.totalcost, tx.Cost())
|
l.totalcost.Add(l.totalcost, uint256.MustFromBig(tx.Cost()))
|
||||||
|
|
||||||
// Otherwise overwrite the old transaction with the current one
|
// Otherwise overwrite the old transaction with the current one
|
||||||
l.txs.Put(tx)
|
l.txs.Put(tx)
|
||||||
if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
|
if cost := uint256.MustFromBig(tx.Cost()); l.costcap.Cmp(cost) < 0 {
|
||||||
l.costcap = cost
|
l.costcap = cost
|
||||||
}
|
}
|
||||||
if gas := tx.Gas(); l.gascap < gas {
|
if gas := tx.Gas(); l.gascap < gas {
|
||||||
|
|
@ -355,17 +357,17 @@ func (l *list) Forward(threshold uint64) types.Transactions {
|
||||||
// a point in calculating all the costs or if the balance covers all. If the threshold
|
// a point in calculating all the costs or if the balance covers all. If the threshold
|
||||||
// is lower than the costgas cap, the caps will be reset to a new high after removing
|
// is lower than the costgas cap, the caps will be reset to a new high after removing
|
||||||
// the newly invalidated transactions.
|
// the newly invalidated transactions.
|
||||||
func (l *list) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
|
func (l *list) Filter(costLimit *uint256.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
|
||||||
// If all transactions are below the threshold, short circuit
|
// If all transactions are below the threshold, short circuit
|
||||||
if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
|
if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds
|
l.costcap = new(uint256.Int).Set(costLimit) // Lower the caps to the thresholds
|
||||||
l.gascap = gasLimit
|
l.gascap = gasLimit
|
||||||
|
|
||||||
// Filter out all the transactions above the account's funds
|
// Filter out all the transactions above the account's funds
|
||||||
removed := l.txs.Filter(func(tx *types.Transaction) bool {
|
removed := l.txs.Filter(func(tx *types.Transaction) bool {
|
||||||
return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit) > 0
|
return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit.ToBig()) > 0
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(removed) == 0 {
|
if len(removed) == 0 {
|
||||||
|
|
@ -456,7 +458,10 @@ func (l *list) LastElement() *types.Transaction {
|
||||||
// total cost of all transactions.
|
// total cost of all transactions.
|
||||||
func (l *list) subTotalCost(txs []*types.Transaction) {
|
func (l *list) subTotalCost(txs []*types.Transaction) {
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
l.totalcost.Sub(l.totalcost, tx.Cost())
|
_, underflow := l.totalcost.SubOverflow(l.totalcost, uint256.MustFromBig(tx.Cost()))
|
||||||
|
if underflow {
|
||||||
|
panic("totalcost underflow")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@
|
||||||
package legacypool
|
package legacypool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tests that transactions can be added to strict lists and list contents and
|
// Tests that transactions can be added to strict lists and list contents and
|
||||||
|
|
@ -60,7 +60,7 @@ func BenchmarkListAdd(b *testing.B) {
|
||||||
txs[i] = transaction(uint64(i), 0, key)
|
txs[i] = transaction(uint64(i), 0, key)
|
||||||
}
|
}
|
||||||
// Insert the transactions in a random order
|
// Insert the transactions in a random order
|
||||||
priceLimit := big.NewInt(int64(DefaultConfig.PriceLimit))
|
priceLimit := uint256.NewInt(DefaultConfig.PriceLimit)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
list := newList(true)
|
list := newList(true)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue