mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
This commit is contained in:
parent
f5e2d16f50
commit
9d6e8fc83f
8 changed files with 86 additions and 57 deletions
|
|
@ -40,6 +40,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/metrics"
|
"github.com/XinFinOrg/XDPoSChain/metrics"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -245,7 +246,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
|
||||||
|
|
@ -334,12 +335,12 @@ func (pool *LegacyPool) Filter(tx *types.Transaction) bool {
|
||||||
// head to allow balance / nonce checks. The transaction journal will be loaded
|
// head to allow balance / nonce checks. The transaction journal will be loaded
|
||||||
// from disk and filtered based on the provided starting settings. The internal
|
// from disk and filtered based on the provided starting settings. The internal
|
||||||
// goroutines will be spun up and the pool deemed operational afterwards.
|
// goroutines will be spun up and the pool deemed operational afterwards.
|
||||||
func (pool *LegacyPool) Init(gasTip *big.Int, head *types.Header, reserver *txpool.Reserver) error {
|
func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserver *txpool.Reserver) error {
|
||||||
// Set the address reserver to request exclusive access to pooled accounts
|
// Set the address reserver to request exclusive access to pooled accounts
|
||||||
pool.reserver = reserver
|
pool.reserver = reserver
|
||||||
|
|
||||||
// Set the basic pool parameters
|
// Set the basic pool parameters
|
||||||
pool.gasTip.Store(gasTip)
|
pool.gasTip.Store(uint256.NewInt(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
|
||||||
|
|
@ -491,11 +492,13 @@ func (pool *LegacyPool) SetGasTip(tip *big.Int) error {
|
||||||
return fmt.Errorf("reject too high gas tip: %v, maximum: %v", tip, defaultMaxTip)
|
return fmt.Errorf("reject too high gas tip: %v, maximum: %v", tip, defaultMaxTip)
|
||||||
}
|
}
|
||||||
|
|
||||||
old := pool.gasTip.Load()
|
var (
|
||||||
pool.gasTip.Store(new(big.Int).Set(tip))
|
newTip = uint256.MustFromBig(tip)
|
||||||
|
old = pool.gasTip.Load()
|
||||||
|
)
|
||||||
|
pool.gasTip.Store(newTip)
|
||||||
// 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 newTip.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 {
|
||||||
|
|
@ -503,7 +506,7 @@ func (pool *LegacyPool) SetGasTip(tip *big.Int) error {
|
||||||
}
|
}
|
||||||
pool.priced.Removed(len(drop))
|
pool.priced.Removed(len(drop))
|
||||||
}
|
}
|
||||||
log.Info("Legacy pool tip threshold updated", "tip", tip)
|
log.Info("Legacy pool tip threshold updated", "tip", newTip)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -591,7 +594,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.IsSpecialTransaction() && tx.EffectiveGasTipIntCmp(pool.gasTip.Load(), pool.priced.urgent.baseFee) < 0 {
|
if !tx.IsSpecialTransaction() && tx.EffectiveGasTipIntCmp(pool.gasTip.Load().ToBig(), pool.priced.urgent.baseFee) < 0 {
|
||||||
txs = txs[:i]
|
txs = txs[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -653,7 +656,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
|
||||||
1<<types.DynamicFeeTxType |
|
1<<types.DynamicFeeTxType |
|
||||||
1<<types.SetCodeTxType,
|
1<<types.SetCodeTxType,
|
||||||
MaxSize: txMaxSize,
|
MaxSize: txMaxSize,
|
||||||
MinTip: pool.gasTip.Load(),
|
MinTip: pool.gasTip.Load().ToBig(),
|
||||||
NotSigner: func(from common.Address) bool {
|
NotSigner: func(from common.Address) bool {
|
||||||
return pool.isSigner != nil && !pool.isSigner(from)
|
return pool.isSigner != nil && !pool.isSigner(from)
|
||||||
},
|
},
|
||||||
|
|
@ -677,7 +680,7 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error {
|
||||||
UsedAndLeftSlots: nil, // Pool has own mechanism to limit the number of transactions
|
UsedAndLeftSlots: nil, // Pool has own mechanism to limit the number of transactions
|
||||||
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)
|
||||||
},
|
},
|
||||||
|
|
@ -1079,7 +1082,7 @@ func (pool *LegacyPool) promoteSpecialTx(addr common.Address, tx *types.Transact
|
||||||
pendingGauge.Inc(1)
|
pendingGauge.Inc(1)
|
||||||
}
|
}
|
||||||
list.txs.Put(tx)
|
list.txs.Put(tx)
|
||||||
if cost := tx.Cost(); list.costcap.Cmp(cost) < 0 {
|
if cost := uint256.MustFromBig(tx.Cost()); list.costcap.Cmp(cost) < 0 {
|
||||||
list.costcap = cost
|
list.costcap = cost
|
||||||
}
|
}
|
||||||
if gas := tx.Gas(); list.gascap < gas {
|
if gas := tx.Gas(); list.gascap < gas {
|
||||||
|
|
@ -1631,7 +1634,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
||||||
if pool.chain.CurrentHeader() != nil {
|
if pool.chain.CurrentHeader() != nil {
|
||||||
number = pool.chain.CurrentHeader().Number
|
number = pool.chain.CurrentHeader().Number
|
||||||
}
|
}
|
||||||
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit, pool.trc21FeeCapacity, number)
|
drops, _ := list.Filter(uint256.MustFromBig(pool.currentState.GetBalance(addr)), gasLimit, pool.trc21FeeCapacity, number)
|
||||||
for _, tx := range drops {
|
for _, tx := range drops {
|
||||||
pool.all.Remove(tx.Hash())
|
pool.all.Remove(tx.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -1836,7 +1839,7 @@ func (pool *LegacyPool) demoteUnexecutables() {
|
||||||
if pool.chain.CurrentHeader() != nil {
|
if pool.chain.CurrentHeader() != nil {
|
||||||
number = pool.chain.CurrentHeader().Number
|
number = pool.chain.CurrentHeader().Number
|
||||||
}
|
}
|
||||||
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit, pool.trc21FeeCapacity, number)
|
drops, invalids := list.Filter(uint256.MustFromBig(pool.currentState.GetBalance(addr)), gasLimit, pool.trc21FeeCapacity, number)
|
||||||
for _, tx := range drops {
|
for _, tx := range drops {
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
pool.all.Remove(hash)
|
pool.all.Remove(hash)
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ func TestTransactionFutureAttack(t *testing.T) {
|
||||||
config.GlobalQueue = 100
|
config.GlobalQueue = 100
|
||||||
config.GlobalSlots = 100
|
config.GlobalSlots = 100
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
fillPool(t, pool)
|
fillPool(t, pool)
|
||||||
pending, _ := pool.Stats()
|
pending, _ := pool.Stats()
|
||||||
|
|
@ -119,7 +119,7 @@ func TestTransactionFuture1559(t *testing.T) {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a number of test accounts, fund them and make transactions
|
// Create a number of test accounts, fund them and make transactions
|
||||||
|
|
@ -152,7 +152,7 @@ func TestTransactionZAttack(t *testing.T) {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
// Create a number of test accounts, fund them and make transactions
|
// Create a number of test accounts, fund them and make transactions
|
||||||
fillPool(t, pool)
|
fillPool(t, pool)
|
||||||
|
|
@ -226,7 +226,7 @@ func BenchmarkFutureAttack(b *testing.B) {
|
||||||
config.GlobalQueue = 100
|
config.GlobalQueue = 100
|
||||||
config.GlobalSlots = 100
|
config.GlobalSlots = 100
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
fillPool(b, pool)
|
fillPool(b, pool)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.Privat
|
||||||
|
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
if err := pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver()); err != nil {
|
if err := pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver()); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// wait for the pool to initialize
|
// wait for the pool to initialize
|
||||||
|
|
@ -233,7 +233,7 @@ func validatePoolInternals(pool *LegacyPool) error {
|
||||||
if nonce := pool.Nonce(addr); nonce != last+1 {
|
if nonce := pool.Nonce(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 {
|
if txs.totalcost.Sign() < 0 {
|
||||||
return fmt.Errorf("totalcost went negative: %v", txs.totalcost)
|
return fmt.Errorf("totalcost went negative: %v", txs.totalcost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -318,7 +318,7 @@ func TestStateChangeDuringReset(t *testing.T) {
|
||||||
tx1 := pricedTransaction(1, 100000, big.NewInt(250000000), key)
|
tx1 := pricedTransaction(1, 100000, big.NewInt(250000000), key)
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
nonce := pool.Nonce(address)
|
nonce := pool.Nonce(address)
|
||||||
|
|
@ -386,7 +386,7 @@ func TestInvalidTransactions(t *testing.T) {
|
||||||
// Test underpriced: set pool gasTip first, then create transaction with lower gas price
|
// Test underpriced: set pool gasTip first, then create transaction with lower gas price
|
||||||
// MinGasPrice is 250000000 (0.25 Gwei), so use gas price 300000000 (0.3 Gwei)
|
// MinGasPrice is 250000000 (0.25 Gwei), so use gas price 300000000 (0.3 Gwei)
|
||||||
// which is higher than MinGasPrice but lower than pool's gasTip (1 Gwei)
|
// which is higher than MinGasPrice but lower than pool's gasTip (1 Gwei)
|
||||||
pool.gasTip.Store(big.NewInt(1000000000)) // Set pool gasTip to 1 Gwei (1000000000)
|
pool.gasTip.Store(uint256.NewInt(1000000000)) // Set pool gasTip to 1 Gwei (1000000000)
|
||||||
tx = pricedTransaction(1, 100000, big.NewInt(300000000), key)
|
tx = pricedTransaction(1, 100000, big.NewInt(300000000), key)
|
||||||
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)
|
||||||
|
|
@ -813,7 +813,7 @@ func TestPostponing(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create two test accounts to produce different gap profiles with
|
// Create two test accounts to produce different gap profiles with
|
||||||
|
|
@ -1031,7 +1031,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) {
|
||||||
config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible)
|
config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible)
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them (last one will be the local)
|
// Create a number of test accounts and fund them (last one will be the local)
|
||||||
|
|
@ -1122,7 +1122,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) {
|
||||||
config.NoLocals = nolocals
|
config.NoLocals = nolocals
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create two test accounts to ensure remotes expire but locals do not
|
// Create two test accounts to ensure remotes expire but locals do not
|
||||||
|
|
@ -1308,7 +1308,7 @@ func TestPendingGlobalLimiting(t *testing.T) {
|
||||||
config.GlobalSlots = config.AccountSlots * 10
|
config.GlobalSlots = config.AccountSlots * 10
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
|
|
@ -1412,7 +1412,7 @@ func TestCapClearsFromAll(t *testing.T) {
|
||||||
config.GlobalSlots = 8
|
config.GlobalSlots = 8
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
|
|
@ -1446,7 +1446,7 @@ func TestPendingMinimumAllowance(t *testing.T) {
|
||||||
config.GlobalSlots = 1
|
config.GlobalSlots = 1
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
|
|
@ -1492,7 +1492,7 @@ func TestRepricing(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Keep track of transaction events to ensure all executables get announced
|
// Keep track of transaction events to ensure all executables get announced
|
||||||
|
|
@ -1741,7 +1741,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
|
|
@ -1820,7 +1820,7 @@ func TestUnderpricing(t *testing.T) {
|
||||||
config.GlobalQueue = 2
|
config.GlobalQueue = 2
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Keep track of transaction events to ensure all executables get announced
|
// Keep track of transaction events to ensure all executables get announced
|
||||||
|
|
@ -1939,7 +1939,7 @@ func TestStableUnderpricing(t *testing.T) {
|
||||||
config.AccountSlots = config.GlobalSlots - 1
|
config.AccountSlots = config.GlobalSlots - 1
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Keep track of transaction events to ensure all executables get announced
|
// Keep track of transaction events to ensure all executables get announced
|
||||||
|
|
@ -2168,7 +2168,7 @@ func TestDeduplication(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create a test account to add transactions with
|
// Create a test account to add transactions with
|
||||||
|
|
@ -2235,7 +2235,7 @@ func TestReplacement(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Keep track of transaction events to ensure all executables get announced
|
// Keep track of transaction events to ensure all executables get announced
|
||||||
|
|
@ -2447,7 +2447,7 @@ func testJournaling(t *testing.T, nolocals bool) {
|
||||||
config.Rejournal = time.Second
|
config.Rejournal = time.Second
|
||||||
|
|
||||||
pool := New(config, blockchain)
|
pool := New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
|
|
||||||
// Create two test accounts to ensure remotes expire but locals do not
|
// Create two test accounts to ensure remotes expire but locals do not
|
||||||
local, _ := crypto.GenerateKey()
|
local, _ := crypto.GenerateKey()
|
||||||
|
|
@ -2485,7 +2485,7 @@ func testJournaling(t *testing.T, nolocals bool) {
|
||||||
blockchain = newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain = newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool = New(config, blockchain)
|
pool = New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
|
|
||||||
pending, queued = pool.Stats()
|
pending, queued = pool.Stats()
|
||||||
if queued != 0 {
|
if queued != 0 {
|
||||||
|
|
@ -2512,7 +2512,7 @@ func testJournaling(t *testing.T, nolocals bool) {
|
||||||
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
|
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
|
||||||
blockchain = newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain = newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
pool = New(config, blockchain)
|
pool = New(config, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(config.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(config.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
|
|
||||||
pending, queued = pool.Stats()
|
pending, queued = pool.Stats()
|
||||||
if pending != 0 {
|
if pending != 0 {
|
||||||
|
|
@ -2543,7 +2543,7 @@ func TestStatusCheck(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create the test accounts to check various transaction statuses with
|
// Create the test accounts to check various transaction statuses with
|
||||||
|
|
@ -2616,7 +2616,7 @@ func TestSetCodeTransactions(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create the test accounts
|
// Create the test accounts
|
||||||
|
|
@ -2820,7 +2820,7 @@ func TestSetCodeTransactionsReorg(t *testing.T) {
|
||||||
blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), newReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
// Create the test accounts
|
// Create the test accounts
|
||||||
|
|
@ -3120,7 +3120,7 @@ func TestSetGasPrice(t *testing.T) {
|
||||||
if haveErr != nil {
|
if haveErr != nil {
|
||||||
t.Errorf("%s: Expected no error, got: %v", tc.description, haveErr)
|
t.Errorf("%s: Expected no error, got: %v", tc.description, haveErr)
|
||||||
}
|
}
|
||||||
if newPrice.Cmp(tc.tip) != 0 {
|
if newPrice.ToBig().Cmp(tc.tip) != 0 {
|
||||||
t.Errorf("%s: Expected gas price to be set to %v, got %v", tc.description, tc.tip, newPrice)
|
t.Errorf("%s: Expected gas price to be set to %v, got %v", tc.description, tc.tip, newPrice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/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
|
||||||
|
|
@ -273,9 +274,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,
|
||||||
|
|
@ -284,8 +285,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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -330,10 +331,15 @@ 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())
|
cost, overflow := uint256.FromBig(tx.Cost())
|
||||||
|
if overflow {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
l.totalcost.Add(l.totalcost, 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 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 {
|
||||||
|
|
@ -360,12 +366,12 @@ 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, trc21Issuers map[common.Address]*big.Int, number *big.Int) (types.Transactions, types.Transactions) {
|
func (l *list) Filter(costLimit *uint256.Int, gasLimit uint64, trc21Issuers map[common.Address]*big.Int, number *big.Int) (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
|
||||||
|
|
@ -373,10 +379,10 @@ func (l *list) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[comm
|
||||||
maximum := costLimit
|
maximum := costLimit
|
||||||
if tx.To() != nil {
|
if tx.To() != nil {
|
||||||
if feeCapacity, ok := trc21Issuers[*tx.To()]; ok {
|
if feeCapacity, ok := trc21Issuers[*tx.To()]; ok {
|
||||||
return tx.Gas() > gasLimit || new(big.Int).Add(costLimit, feeCapacity).Cmp(tx.TxCost(number)) < 0
|
return tx.Gas() > gasLimit || new(big.Int).Add(costLimit.ToBig(), feeCapacity).Cmp(tx.TxCost(number)) < 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tx.Gas() > gasLimit || tx.Cost().Cmp(maximum) > 0
|
return tx.Gas() > gasLimit || tx.Cost().Cmp(maximum.ToBig()) > 0
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(removed) == 0 {
|
if len(removed) == 0 {
|
||||||
|
|
@ -467,7 +473,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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,10 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/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
|
||||||
|
|
@ -51,6 +53,21 @@ func TestStrictListAdd(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestListAddVeryExpensive tests adding txs which exceed 256 bits in cost. It is
|
||||||
|
// expected that the list does not panic.
|
||||||
|
func TestListAddVeryExpensive(t *testing.T) {
|
||||||
|
key, _ := crypto.GenerateKey()
|
||||||
|
list := newList(true)
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
value := big.NewInt(100)
|
||||||
|
gasprice, _ := new(big.Int).SetString("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0)
|
||||||
|
gaslimit := uint64(i)
|
||||||
|
tx, _ := types.SignTx(types.NewTransaction(uint64(i), common.Address{}, value, gaslimit, gasprice, nil), types.HomesteadSigner{}, key)
|
||||||
|
t.Logf("cost: %x bitlen: %d\n", tx.Cost(), tx.Cost().BitLen())
|
||||||
|
list.Add(tx, DefaultConfig.PriceBump)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkListAdd(t *testing.B) {
|
func BenchmarkListAdd(t *testing.B) {
|
||||||
// Generate a list of transactions to insert
|
// Generate a list of transactions to insert
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
@ -61,7 +78,7 @@ func BenchmarkListAdd(t *testing.B) {
|
||||||
}
|
}
|
||||||
// Insert the transactions in a random order
|
// Insert the transactions in a random order
|
||||||
list := newList(true)
|
list := newList(true)
|
||||||
priceLimit := big.NewInt(int64(DefaultConfig.PriceLimit))
|
priceLimit := uint256.NewInt(DefaultConfig.PriceLimit)
|
||||||
t.ResetTimer()
|
t.ResetTimer()
|
||||||
for _, v := range rand.Perm(len(txs)) {
|
for _, v := range rand.Perm(len(txs)) {
|
||||||
list.Add(txs[v], DefaultConfig.PriceBump)
|
list.Add(txs[v], DefaultConfig.PriceBump)
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ type SubPool interface {
|
||||||
// These should not be passed as a constructor argument - nor should the pools
|
// These should not be passed as a constructor argument - nor should the pools
|
||||||
// start by themselves - in order to keep multiple subpools in lockstep with
|
// start by themselves - in order to keep multiple subpools in lockstep with
|
||||||
// one another.
|
// one another.
|
||||||
Init(gasTip *big.Int, head *types.Header, reserver *Reserver) error
|
Init(gasTip uint64, head *types.Header, reserver *Reserver) error
|
||||||
|
|
||||||
// Close terminates any background processing threads and releases any held
|
// Close terminates any background processing threads and releases any held
|
||||||
// resources.
|
// resources.
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ type TxPool struct {
|
||||||
|
|
||||||
// New creates a new transaction pool to gather, sort and filter inbound
|
// New creates a new transaction pool to gather, sort and filter inbound
|
||||||
// transactions from the network.
|
// transactions from the network.
|
||||||
func New(gasTip *big.Int, chain BlockChain, subpools []SubPool) (*TxPool, error) {
|
func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) {
|
||||||
// Retrieve the current head so that all subpools and this main coordinator
|
// Retrieve the current head so that all subpools and this main coordinator
|
||||||
// pool will have the same starting state, even if the chain moves forward
|
// pool will have the same starting state, even if the chain moves forward
|
||||||
// during initialization.
|
// during initialization.
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
||||||
}
|
}
|
||||||
legacyPool := legacypool.New(config.TxPool, eth.blockchain)
|
legacyPool := legacypool.New(config.TxPool, eth.blockchain)
|
||||||
|
|
||||||
eth.txPool, err = txpool.New(new(big.Int).SetUint64(config.TxPool.PriceLimit), eth.blockchain, []txpool.SubPool{legacyPool})
|
eth.txPool, err = txpool.New(config.TxPool.PriceLimit, eth.blockchain, []txpool.SubPool{legacyPool})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue