core: test locals support in txpool queue limits, fix
The commit reworks the transaction pool queue limitation tests to cater for testing local accounts, also testing the nolocal flag. In addition, it also fixes a panic if local transactions exceeded the global queue allowance (no accounts left to drop from) and also fixes queue eviction to operate on all accounts, not just the one being updated.
This commit is contained in:
parent
88b4fe7d21
commit
34ec9913f6
@ -477,7 +477,7 @@ func (l *txPricedList) Underpriced(tx *types.Transaction, local *accountSet) boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Discard finds a number of most underpriced transactions, removes them from the
|
// Discard finds a number of most underpriced transactions, removes them from the
|
||||||
// priced list and returs them for further removal from the entire pool.
|
// priced list and returns them for further removal from the entire pool.
|
||||||
func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions {
|
func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions {
|
||||||
drop := make(types.Transactions, 0, count) // Remote underpriced transactions to drop
|
drop := make(types.Transactions, 0, count) // Remote underpriced transactions to drop
|
||||||
save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep
|
save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep
|
||||||
|
@ -716,7 +716,6 @@ func (pool *TxPool) promoteExecutables(state *state.StateDB, accounts []common.A
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterate over all accounts and promote any executable transactions
|
// Iterate over all accounts and promote any executable transactions
|
||||||
queued := uint64(0)
|
|
||||||
for _, addr := range accounts {
|
for _, addr := range accounts {
|
||||||
list := pool.queue[addr]
|
list := pool.queue[addr]
|
||||||
if list == nil {
|
if list == nil {
|
||||||
@ -754,8 +753,6 @@ func (pool *TxPool) promoteExecutables(state *state.StateDB, accounts []common.A
|
|||||||
log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
|
log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queued += uint64(list.Len())
|
|
||||||
|
|
||||||
// Delete the entire queue entry if it became empty.
|
// Delete the entire queue entry if it became empty.
|
||||||
if list.Empty() {
|
if list.Empty() {
|
||||||
delete(pool.queue, addr)
|
delete(pool.queue, addr)
|
||||||
@ -833,19 +830,22 @@ func (pool *TxPool) promoteExecutables(state *state.StateDB, accounts []common.A
|
|||||||
pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
|
pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
|
||||||
}
|
}
|
||||||
// If we've queued more transactions than the hard limit, drop oldest ones
|
// If we've queued more transactions than the hard limit, drop oldest ones
|
||||||
|
queued := uint64(0)
|
||||||
|
for _, list := range pool.queue {
|
||||||
|
queued += uint64(list.Len())
|
||||||
|
}
|
||||||
if queued > pool.config.GlobalQueue {
|
if queued > pool.config.GlobalQueue {
|
||||||
// Sort all accounts with queued transactions by heartbeat
|
// Sort all accounts with queued transactions by heartbeat
|
||||||
addresses := make(addresssByHeartbeat, 0, len(pool.queue))
|
addresses := make(addresssByHeartbeat, 0, len(pool.queue))
|
||||||
for addr := range pool.queue {
|
for addr := range pool.queue {
|
||||||
// Don't drop locals
|
if !pool.locals.contains(addr) { // don't drop locals
|
||||||
if !pool.locals.contains(addr) {
|
|
||||||
addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
|
addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Sort(addresses)
|
sort.Sort(addresses)
|
||||||
|
|
||||||
// Drop transactions until the total is below the limit
|
// Drop transactions until the total is below the limit or only locals remain
|
||||||
for drop := queued - pool.config.GlobalQueue; drop > 0; {
|
for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; {
|
||||||
addr := addresses[len(addresses)-1]
|
addr := addresses[len(addresses)-1]
|
||||||
list := pool.queue[addr.address]
|
list := pool.queue[addr.address]
|
||||||
|
|
||||||
|
@ -47,10 +47,10 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
|||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
newPool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
newPool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
return newPool, key
|
return pool, key
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateTxPoolInternals checks various consistency invariants within the pool.
|
// validateTxPoolInternals checks various consistency invariants within the pool.
|
||||||
@ -125,17 +125,18 @@ func TestStateChangeDuringPoolReset(t *testing.T) {
|
|||||||
|
|
||||||
gasLimitFunc := func() *big.Int { return big.NewInt(1000000000) }
|
gasLimitFunc := func() *big.Int { return big.NewInt(1000000000) }
|
||||||
|
|
||||||
txpool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, mux, stateFunc, gasLimitFunc)
|
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, mux, stateFunc, gasLimitFunc)
|
||||||
txpool.resetState()
|
defer pool.Stop()
|
||||||
|
pool.resetState()
|
||||||
|
|
||||||
nonce := txpool.State().GetNonce(address)
|
nonce := pool.State().GetNonce(address)
|
||||||
if nonce != 0 {
|
if nonce != 0 {
|
||||||
t.Fatalf("Invalid nonce, want 0, got %d", nonce)
|
t.Fatalf("Invalid nonce, want 0, got %d", nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
txpool.AddRemotes(types.Transactions{tx0, tx1})
|
pool.AddRemotes(types.Transactions{tx0, tx1})
|
||||||
|
|
||||||
nonce = txpool.State().GetNonce(address)
|
nonce = pool.State().GetNonce(address)
|
||||||
if nonce != 2 {
|
if nonce != 2 {
|
||||||
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
||||||
}
|
}
|
||||||
@ -143,9 +144,9 @@ func TestStateChangeDuringPoolReset(t *testing.T) {
|
|||||||
// trigger state change in the background
|
// trigger state change in the background
|
||||||
trigger = true
|
trigger = true
|
||||||
|
|
||||||
txpool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
pendingTx, err := txpool.Pending()
|
pendingTx, err := pool.Pending()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not fetch pending transactions: %v", err)
|
t.Fatalf("Could not fetch pending transactions: %v", err)
|
||||||
}
|
}
|
||||||
@ -154,7 +155,7 @@ func TestStateChangeDuringPoolReset(t *testing.T) {
|
|||||||
t.Logf("%0x: %d\n", addr, len(txs))
|
t.Logf("%0x: %d\n", addr, len(txs))
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce = txpool.State().GetNonce(address)
|
nonce = pool.State().GetNonce(address)
|
||||||
if nonce != 2 {
|
if nonce != 2 {
|
||||||
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
||||||
}
|
}
|
||||||
@ -162,6 +163,7 @@ func TestStateChangeDuringPoolReset(t *testing.T) {
|
|||||||
|
|
||||||
func TestInvalidTransactions(t *testing.T) {
|
func TestInvalidTransactions(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
tx := transaction(0, big.NewInt(100), key)
|
tx := transaction(0, big.NewInt(100), key)
|
||||||
from, _ := deriveSender(tx)
|
from, _ := deriveSender(tx)
|
||||||
@ -196,6 +198,8 @@ func TestInvalidTransactions(t *testing.T) {
|
|||||||
|
|
||||||
func TestTransactionQueue(t *testing.T) {
|
func TestTransactionQueue(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
tx := transaction(0, big.NewInt(100), key)
|
tx := transaction(0, big.NewInt(100), key)
|
||||||
from, _ := deriveSender(tx)
|
from, _ := deriveSender(tx)
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
@ -246,6 +250,8 @@ func TestTransactionQueue(t *testing.T) {
|
|||||||
|
|
||||||
func TestRemoveTx(t *testing.T) {
|
func TestRemoveTx(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
currentState.AddBalance(addr, big.NewInt(1))
|
currentState.AddBalance(addr, big.NewInt(1))
|
||||||
@ -275,6 +281,7 @@ func TestRemoveTx(t *testing.T) {
|
|||||||
|
|
||||||
func TestNegativeValue(t *testing.T) {
|
func TestNegativeValue(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil), types.HomesteadSigner{}, key)
|
tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil), types.HomesteadSigner{}, key)
|
||||||
from, _ := deriveSender(tx)
|
from, _ := deriveSender(tx)
|
||||||
@ -287,6 +294,8 @@ func TestNegativeValue(t *testing.T) {
|
|||||||
|
|
||||||
func TestTransactionChainFork(t *testing.T) {
|
func TestTransactionChainFork(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
@ -313,6 +322,8 @@ func TestTransactionChainFork(t *testing.T) {
|
|||||||
|
|
||||||
func TestTransactionDoubleNonce(t *testing.T) {
|
func TestTransactionDoubleNonce(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
@ -361,6 +372,8 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
|||||||
|
|
||||||
func TestMissingNonce(t *testing.T) {
|
func TestMissingNonce(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
@ -382,6 +395,8 @@ func TestMissingNonce(t *testing.T) {
|
|||||||
func TestNonceRecovery(t *testing.T) {
|
func TestNonceRecovery(t *testing.T) {
|
||||||
const n = 10
|
const n = 10
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
currentState.SetNonce(addr, n)
|
currentState.SetNonce(addr, n)
|
||||||
@ -401,6 +416,8 @@ func TestNonceRecovery(t *testing.T) {
|
|||||||
|
|
||||||
func TestRemovedTxEvent(t *testing.T) {
|
func TestRemovedTxEvent(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
tx := transaction(0, big.NewInt(1000000), key)
|
tx := transaction(0, big.NewInt(1000000), key)
|
||||||
from, _ := deriveSender(tx)
|
from, _ := deriveSender(tx)
|
||||||
currentState, _ := pool.currentState()
|
currentState, _ := pool.currentState()
|
||||||
@ -421,6 +438,8 @@ func TestRemovedTxEvent(t *testing.T) {
|
|||||||
func TestTransactionDropping(t *testing.T) {
|
func TestTransactionDropping(t *testing.T) {
|
||||||
// Create a test account and fund it
|
// Create a test account and fund it
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
|
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
@ -514,6 +533,8 @@ func TestTransactionDropping(t *testing.T) {
|
|||||||
func TestTransactionPostponing(t *testing.T) {
|
func TestTransactionPostponing(t *testing.T) {
|
||||||
// Create a test account and fund it
|
// Create a test account and fund it
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
|
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
@ -588,6 +609,8 @@ func TestTransactionPostponing(t *testing.T) {
|
|||||||
func TestTransactionQueueAccountLimiting(t *testing.T) {
|
func TestTransactionQueueAccountLimiting(t *testing.T) {
|
||||||
// Create a test account and fund it
|
// Create a test account and fund it
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
|
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
@ -619,19 +642,30 @@ func TestTransactionQueueAccountLimiting(t *testing.T) {
|
|||||||
|
|
||||||
// Tests that if the transaction count belonging to multiple accounts go above
|
// Tests that if the transaction count belonging to multiple accounts go above
|
||||||
// some threshold, the higher transactions are dropped to prevent DOS attacks.
|
// some threshold, the higher transactions are dropped to prevent DOS attacks.
|
||||||
|
//
|
||||||
|
// This logic should not hold for local transactions, unless the local tracking
|
||||||
|
// mechanism is disabled.
|
||||||
func TestTransactionQueueGlobalLimiting(t *testing.T) {
|
func TestTransactionQueueGlobalLimiting(t *testing.T) {
|
||||||
// Reduce the queue limits to shorten test time
|
testTransactionQueueGlobalLimiting(t, false)
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.GlobalQueue = old }(DefaultTxPoolConfig.GlobalQueue)
|
}
|
||||||
DefaultTxPoolConfig.GlobalQueue = DefaultTxPoolConfig.AccountQueue * 3
|
func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) {
|
||||||
|
testTransactionQueueGlobalLimiting(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
config := DefaultTxPoolConfig
|
||||||
|
config.NoLocals = nolocals
|
||||||
|
config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible)
|
||||||
|
|
||||||
|
pool := NewTxPool(config, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them (last one will be the local)
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
|
|
||||||
keys := make([]*ecdsa.PrivateKey, 5)
|
keys := make([]*ecdsa.PrivateKey, 5)
|
||||||
@ -639,12 +673,14 @@ func TestTransactionQueueGlobalLimiting(t *testing.T) {
|
|||||||
keys[i], _ = crypto.GenerateKey()
|
keys[i], _ = crypto.GenerateKey()
|
||||||
state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
|
state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
|
||||||
}
|
}
|
||||||
|
local := keys[len(keys)-1]
|
||||||
|
|
||||||
// Generate and queue a batch of transactions
|
// Generate and queue a batch of transactions
|
||||||
nonces := make(map[common.Address]uint64)
|
nonces := make(map[common.Address]uint64)
|
||||||
|
|
||||||
txs := make(types.Transactions, 0, 3*DefaultTxPoolConfig.GlobalQueue)
|
txs := make(types.Transactions, 0, 3*config.GlobalQueue)
|
||||||
for len(txs) < cap(txs) {
|
for len(txs) < cap(txs) {
|
||||||
key := keys[rand.Intn(len(keys))]
|
key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
||||||
txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key))
|
txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key))
|
||||||
@ -655,43 +691,114 @@ func TestTransactionQueueGlobalLimiting(t *testing.T) {
|
|||||||
|
|
||||||
queued := 0
|
queued := 0
|
||||||
for addr, list := range pool.queue {
|
for addr, list := range pool.queue {
|
||||||
if list.Len() > int(DefaultTxPoolConfig.AccountQueue) {
|
if list.Len() > int(config.AccountQueue) {
|
||||||
t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), DefaultTxPoolConfig.AccountQueue)
|
t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue)
|
||||||
}
|
}
|
||||||
queued += list.Len()
|
queued += list.Len()
|
||||||
}
|
}
|
||||||
if queued > int(DefaultTxPoolConfig.GlobalQueue) {
|
if queued > int(config.GlobalQueue) {
|
||||||
t.Fatalf("total transactions overflow allowance: %d > %d", queued, DefaultTxPoolConfig.GlobalQueue)
|
t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue)
|
||||||
|
}
|
||||||
|
// Generate a batch of transactions from the local account and import them
|
||||||
|
txs = txs[:0]
|
||||||
|
for i := uint64(0); i < 3*config.GlobalQueue; i++ {
|
||||||
|
txs = append(txs, transaction(i+1, big.NewInt(100000), local))
|
||||||
|
}
|
||||||
|
pool.AddLocals(txs)
|
||||||
|
|
||||||
|
// If locals are disabled, the previous eviction algorithm should apply here too
|
||||||
|
if nolocals {
|
||||||
|
queued := 0
|
||||||
|
for addr, list := range pool.queue {
|
||||||
|
if list.Len() > int(config.AccountQueue) {
|
||||||
|
t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue)
|
||||||
|
}
|
||||||
|
queued += list.Len()
|
||||||
|
}
|
||||||
|
if queued > int(config.GlobalQueue) {
|
||||||
|
t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Local exemptions are enabled, make sure the local account owned the queue
|
||||||
|
if len(pool.queue) != 1 {
|
||||||
|
t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1)
|
||||||
|
}
|
||||||
|
// Also ensure no local transactions are ever dropped, even if above global limits
|
||||||
|
if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue {
|
||||||
|
t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that if an account remains idle for a prolonged amount of time, any
|
// Tests that if an account remains idle for a prolonged amount of time, any
|
||||||
// non-executable transactions queued up are dropped to prevent wasting resources
|
// non-executable transactions queued up are dropped to prevent wasting resources
|
||||||
// on shuffling them around.
|
// on shuffling them around.
|
||||||
func TestTransactionQueueTimeLimiting(t *testing.T) {
|
//
|
||||||
// Reduce the queue limits to shorten test time
|
// This logic should not hold for local transactions, unless the local tracking
|
||||||
defer func(old time.Duration) { DefaultTxPoolConfig.Lifetime = old }(DefaultTxPoolConfig.Lifetime)
|
// mechanism is disabled.
|
||||||
defer func(old time.Duration) { evictionInterval = old }(evictionInterval)
|
func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) }
|
||||||
DefaultTxPoolConfig.Lifetime = time.Second
|
func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) }
|
||||||
evictionInterval = time.Second
|
|
||||||
|
|
||||||
// Create a test account and fund it
|
func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
|
||||||
pool, key := setupTxPool()
|
// Reduce the eviction interval to a testable amount
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
defer func(old time.Duration) { evictionInterval = old }(evictionInterval)
|
||||||
|
evictionInterval = 250 * time.Millisecond
|
||||||
|
|
||||||
|
// Create the pool to test the non-expiration enforcement
|
||||||
|
db, _ := ethdb.NewMemDatabase()
|
||||||
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
|
config := DefaultTxPoolConfig
|
||||||
|
config.Lifetime = 250 * time.Millisecond
|
||||||
|
config.NoLocals = nolocals
|
||||||
|
|
||||||
|
pool := NewTxPool(config, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
|
pool.resetState()
|
||||||
|
|
||||||
|
// Create two test accounts to ensure remotes expire but locals do not
|
||||||
|
local, _ := crypto.GenerateKey()
|
||||||
|
remote, _ := crypto.GenerateKey()
|
||||||
|
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
state.AddBalance(account, big.NewInt(1000000))
|
state.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
|
||||||
|
state.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
|
||||||
|
|
||||||
// Queue up a batch of transactions
|
// Add the two transactions and ensure they both are queued up
|
||||||
for i := uint64(1); i <= DefaultTxPoolConfig.AccountQueue; i++ {
|
if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil {
|
||||||
if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil {
|
t.Fatalf("failed to add local transaction: %v", err)
|
||||||
t.Fatalf("tx %d: failed to add transaction: %v", i, err)
|
}
|
||||||
|
if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), remote)); err != nil {
|
||||||
|
t.Fatalf("failed to add remote transaction: %v", err)
|
||||||
|
}
|
||||||
|
pending, queued := pool.stats()
|
||||||
|
if pending != 0 {
|
||||||
|
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
|
||||||
|
}
|
||||||
|
if queued != 2 {
|
||||||
|
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
|
||||||
|
}
|
||||||
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
|
}
|
||||||
|
// Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
|
||||||
|
time.Sleep(2 * config.Lifetime)
|
||||||
|
|
||||||
|
pending, queued = pool.stats()
|
||||||
|
if pending != 0 {
|
||||||
|
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
|
||||||
|
}
|
||||||
|
if nolocals {
|
||||||
|
if queued != 0 {
|
||||||
|
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if queued != 1 {
|
||||||
|
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Wait until at least two expiration cycles hit and make sure the transactions are gone
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
time.Sleep(2 * evictionInterval)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
if len(pool.queue) > 0 {
|
|
||||||
t.Fatalf("old transactions remained after eviction")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,6 +808,8 @@ func TestTransactionQueueTimeLimiting(t *testing.T) {
|
|||||||
func TestTransactionPendingLimiting(t *testing.T) {
|
func TestTransactionPendingLimiting(t *testing.T) {
|
||||||
// Create a test account and fund it
|
// Create a test account and fund it
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
|
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
@ -775,15 +884,15 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
|
|||||||
// some hard threshold, the higher transactions are dropped to prevent DOS
|
// some hard threshold, the higher transactions are dropped to prevent DOS
|
||||||
// attacks.
|
// attacks.
|
||||||
func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
||||||
// Reduce the queue limits to shorten test time
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.GlobalSlots = old }(DefaultTxPoolConfig.GlobalSlots)
|
|
||||||
DefaultTxPoolConfig.GlobalSlots = DefaultTxPoolConfig.AccountSlots * 10
|
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
config := DefaultTxPoolConfig
|
||||||
|
config.GlobalSlots = config.AccountSlots * 10
|
||||||
|
|
||||||
|
pool := NewTxPool(config, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
@ -800,7 +909,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
|||||||
txs := types.Transactions{}
|
txs := types.Transactions{}
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
for j := 0; j < int(DefaultTxPoolConfig.GlobalSlots)/len(keys)*2; j++ {
|
for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ {
|
||||||
txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
|
txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
|
||||||
nonces[addr]++
|
nonces[addr]++
|
||||||
}
|
}
|
||||||
@ -812,8 +921,8 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
|||||||
for _, list := range pool.pending {
|
for _, list := range pool.pending {
|
||||||
pending += list.Len()
|
pending += list.Len()
|
||||||
}
|
}
|
||||||
if pending > int(DefaultTxPoolConfig.GlobalSlots) {
|
if pending > int(config.GlobalSlots) {
|
||||||
t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, DefaultTxPoolConfig.GlobalSlots)
|
t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots)
|
||||||
}
|
}
|
||||||
if err := validateTxPoolInternals(pool); err != nil {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
@ -822,20 +931,17 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
|
|||||||
|
|
||||||
// Tests that if transactions start being capped, transasctions are also removed from 'all'
|
// Tests that if transactions start being capped, transasctions are also removed from 'all'
|
||||||
func TestTransactionCapClearsFromAll(t *testing.T) {
|
func TestTransactionCapClearsFromAll(t *testing.T) {
|
||||||
// Reduce the queue limits to shorten test time
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.AccountSlots = old }(DefaultTxPoolConfig.AccountSlots)
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.AccountQueue = old }(DefaultTxPoolConfig.AccountQueue)
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.GlobalSlots = old }(DefaultTxPoolConfig.GlobalSlots)
|
|
||||||
|
|
||||||
DefaultTxPoolConfig.AccountSlots = 2
|
|
||||||
DefaultTxPoolConfig.AccountQueue = 2
|
|
||||||
DefaultTxPoolConfig.GlobalSlots = 8
|
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
config := DefaultTxPoolConfig
|
||||||
|
config.AccountSlots = 2
|
||||||
|
config.AccountQueue = 2
|
||||||
|
config.GlobalSlots = 8
|
||||||
|
|
||||||
|
pool := NewTxPool(config, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
@ -846,7 +952,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
|
|||||||
state.AddBalance(addr, big.NewInt(1000000))
|
state.AddBalance(addr, big.NewInt(1000000))
|
||||||
|
|
||||||
txs := types.Transactions{}
|
txs := types.Transactions{}
|
||||||
for j := 0; j < int(DefaultTxPoolConfig.GlobalSlots)*2; j++ {
|
for j := 0; j < int(config.GlobalSlots)*2; j++ {
|
||||||
txs = append(txs, transaction(uint64(j), big.NewInt(100000), key))
|
txs = append(txs, transaction(uint64(j), big.NewInt(100000), key))
|
||||||
}
|
}
|
||||||
// Import the batch and verify that limits have been enforced
|
// Import the batch and verify that limits have been enforced
|
||||||
@ -860,15 +966,15 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
|
|||||||
// some hard threshold, if they are under the minimum guaranteed slot count then
|
// some hard threshold, if they are under the minimum guaranteed slot count then
|
||||||
// the transactions are still kept.
|
// the transactions are still kept.
|
||||||
func TestTransactionPendingMinimumAllowance(t *testing.T) {
|
func TestTransactionPendingMinimumAllowance(t *testing.T) {
|
||||||
// Reduce the queue limits to shorten test time
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.GlobalSlots = old }(DefaultTxPoolConfig.GlobalSlots)
|
|
||||||
DefaultTxPoolConfig.GlobalSlots = 0
|
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
config := DefaultTxPoolConfig
|
||||||
|
config.GlobalSlots = 0
|
||||||
|
|
||||||
|
pool := NewTxPool(config, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
@ -885,7 +991,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
|
|||||||
txs := types.Transactions{}
|
txs := types.Transactions{}
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
for j := 0; j < int(DefaultTxPoolConfig.AccountSlots)*2; j++ {
|
for j := 0; j < int(config.AccountSlots)*2; j++ {
|
||||||
txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
|
txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
|
||||||
nonces[addr]++
|
nonces[addr]++
|
||||||
}
|
}
|
||||||
@ -894,8 +1000,8 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
|
|||||||
pool.AddRemotes(txs)
|
pool.AddRemotes(txs)
|
||||||
|
|
||||||
for addr, list := range pool.pending {
|
for addr, list := range pool.pending {
|
||||||
if list.Len() != int(DefaultTxPoolConfig.AccountSlots) {
|
if list.Len() != int(config.AccountSlots) {
|
||||||
t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), DefaultTxPoolConfig.AccountSlots)
|
t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := validateTxPoolInternals(pool); err != nil {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
@ -914,6 +1020,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
@ -993,18 +1100,16 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||||||
//
|
//
|
||||||
// Note, local transactions are never allowed to be dropped.
|
// Note, local transactions are never allowed to be dropped.
|
||||||
func TestTransactionPoolUnderpricing(t *testing.T) {
|
func TestTransactionPoolUnderpricing(t *testing.T) {
|
||||||
// Reduce the queue limits to shorten test time
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.GlobalSlots = old }(DefaultTxPoolConfig.GlobalSlots)
|
|
||||||
DefaultTxPoolConfig.GlobalSlots = 2
|
|
||||||
|
|
||||||
defer func(old uint64) { DefaultTxPoolConfig.GlobalQueue = old }(DefaultTxPoolConfig.GlobalQueue)
|
|
||||||
DefaultTxPoolConfig.GlobalQueue = 2
|
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
config := DefaultTxPoolConfig
|
||||||
|
config.GlobalSlots = 2
|
||||||
|
config.GlobalQueue = 2
|
||||||
|
|
||||||
|
pool := NewTxPool(config, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a number of test accounts and fund them
|
// Create a number of test accounts and fund them
|
||||||
@ -1088,9 +1193,10 @@ func TestTransactionReplacement(t *testing.T) {
|
|||||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||||
|
|
||||||
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
defer pool.Stop()
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
|
|
||||||
// Create a a test account to add transactions with
|
// Create a test account to add transactions with
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
@ -1153,6 +1259,8 @@ func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 1
|
|||||||
func benchmarkPendingDemotion(b *testing.B, size int) {
|
func benchmarkPendingDemotion(b *testing.B, size int) {
|
||||||
// Add a batch of transactions to a pool one by one
|
// Add a batch of transactions to a pool one by one
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
state.AddBalance(account, big.NewInt(1000000))
|
state.AddBalance(account, big.NewInt(1000000))
|
||||||
@ -1177,6 +1285,8 @@ func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 1
|
|||||||
func benchmarkFuturePromotion(b *testing.B, size int) {
|
func benchmarkFuturePromotion(b *testing.B, size int) {
|
||||||
// Add a batch of transactions to a pool one by one
|
// Add a batch of transactions to a pool one by one
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
state.AddBalance(account, big.NewInt(1000000))
|
state.AddBalance(account, big.NewInt(1000000))
|
||||||
@ -1196,6 +1306,8 @@ func benchmarkFuturePromotion(b *testing.B, size int) {
|
|||||||
func BenchmarkPoolInsert(b *testing.B) {
|
func BenchmarkPoolInsert(b *testing.B) {
|
||||||
// Generate a batch of transactions to enqueue into the pool
|
// Generate a batch of transactions to enqueue into the pool
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
state.AddBalance(account, big.NewInt(1000000))
|
state.AddBalance(account, big.NewInt(1000000))
|
||||||
@ -1219,6 +1331,8 @@ func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 1
|
|||||||
func benchmarkPoolBatchInsert(b *testing.B, size int) {
|
func benchmarkPoolBatchInsert(b *testing.B, size int) {
|
||||||
// Generate a batch of transactions to enqueue into the pool
|
// Generate a batch of transactions to enqueue into the pool
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
|
defer pool.Stop()
|
||||||
|
|
||||||
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
account, _ := deriveSender(transaction(0, big.NewInt(0), key))
|
||||||
state, _ := pool.currentState()
|
state, _ := pool.currentState()
|
||||||
state.AddBalance(account, big.NewInt(1000000))
|
state.AddBalance(account, big.NewInt(1000000))
|
||||||
|
Loading…
Reference in New Issue
Block a user