@ -19,8 +19,10 @@ package core
import (
import (
"crypto/ecdsa"
"crypto/ecdsa"
"fmt"
"fmt"
"io/ioutil"
"math/big"
"math/big"
"math/rand"
"math/rand"
"os"
"testing"
"testing"
"time"
"time"
@ -33,6 +35,15 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params"
)
)
// testTxPoolConfig is a transaction pool configuration without stateful disk
// sideeffects used during testing.
var testTxPoolConfig TxPoolConfig
func init ( ) {
testTxPoolConfig = DefaultTxPoolConfig
testTxPoolConfig . Journal = ""
}
func transaction ( nonce uint64 , gaslimit * big . Int , key * ecdsa . PrivateKey ) * types . Transaction {
func transaction ( nonce uint64 , gaslimit * big . Int , key * ecdsa . PrivateKey ) * types . Transaction {
return pricedTransaction ( nonce , gaslimit , big . NewInt ( 1 ) , key )
return pricedTransaction ( nonce , gaslimit , big . NewInt ( 1 ) , key )
}
}
@ -47,8 +58,7 @@ 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 ( )
pool := NewTxPool ( DefaultTxPoolConfig , params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
pool := NewTxPool ( testTxPoolConfig , params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
pool . resetState ( )
return pool , key
return pool , key
}
}
@ -125,9 +135,8 @@ func TestStateChangeDuringPoolReset(t *testing.T) {
gasLimitFunc := func ( ) * big . Int { return big . NewInt ( 1000000000 ) }
gasLimitFunc := func ( ) * big . Int { return big . NewInt ( 1000000000 ) }
pool := NewTxPool ( Defaul tTxPoolConfig, params . TestChainConfig , mux , stateFunc , gasLimitFunc )
pool := NewTxPool ( tes tTxPoolConfig, params . TestChainConfig , mux , stateFunc , gasLimitFunc )
defer pool . Stop ( )
defer pool . Stop ( )
pool . resetState ( )
nonce := pool . State ( ) . GetNonce ( address )
nonce := pool . State ( ) . GetNonce ( address )
if nonce != 0 {
if nonce != 0 {
@ -618,25 +627,25 @@ func TestTransactionQueueAccountLimiting(t *testing.T) {
pool . resetState ( )
pool . resetState ( )
// Keep queuing up transactions and make sure all above a limit are dropped
// Keep queuing up transactions and make sure all above a limit are dropped
for i := uint64 ( 1 ) ; i <= Defaul tTxPoolConfig. AccountQueue + 5 ; i ++ {
for i := uint64 ( 1 ) ; i <= tes tTxPoolConfig. AccountQueue + 5 ; i ++ {
if err := pool . AddRemote ( transaction ( i , big . NewInt ( 100000 ) , key ) ) ; err != nil {
if err := pool . AddRemote ( transaction ( i , big . NewInt ( 100000 ) , key ) ) ; err != nil {
t . Fatalf ( "tx %d: failed to add transaction: %v" , i , err )
t . Fatalf ( "tx %d: failed to add transaction: %v" , i , err )
}
}
if len ( pool . pending ) != 0 {
if len ( pool . pending ) != 0 {
t . Errorf ( "tx %d: pending pool size mismatch: have %d, want %d" , i , len ( pool . pending ) , 0 )
t . Errorf ( "tx %d: pending pool size mismatch: have %d, want %d" , i , len ( pool . pending ) , 0 )
}
}
if i <= Defaul tTxPoolConfig. AccountQueue {
if i <= tes tTxPoolConfig. AccountQueue {
if pool . queue [ account ] . Len ( ) != int ( i ) {
if pool . queue [ account ] . Len ( ) != int ( i ) {
t . Errorf ( "tx %d: queue size mismatch: have %d, want %d" , i , pool . queue [ account ] . Len ( ) , i )
t . Errorf ( "tx %d: queue size mismatch: have %d, want %d" , i , pool . queue [ account ] . Len ( ) , i )
}
}
} else {
} else {
if pool . queue [ account ] . Len ( ) != int ( Defaul tTxPoolConfig. AccountQueue ) {
if pool . queue [ account ] . Len ( ) != int ( tes tTxPoolConfig. AccountQueue ) {
t . Errorf ( "tx %d: queue limit mismatch: have %d, want %d" , i , pool . queue [ account ] . Len ( ) , Defaul tTxPoolConfig. AccountQueue )
t . Errorf ( "tx %d: queue limit mismatch: have %d, want %d" , i , pool . queue [ account ] . Len ( ) , tes tTxPoolConfig. AccountQueue )
}
}
}
}
}
}
if len ( pool . all ) != int ( Defaul tTxPoolConfig. AccountQueue ) {
if len ( pool . all ) != int ( tes tTxPoolConfig. AccountQueue ) {
t . Errorf ( "total transaction mismatch: have %d, want %d" , len ( pool . all ) , Defaul tTxPoolConfig. AccountQueue )
t . Errorf ( "total transaction mismatch: have %d, want %d" , len ( pool . all ) , tes tTxPoolConfig. AccountQueue )
}
}
}
}
@ -657,13 +666,12 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := Defaul tTxPoolConfig
config := tes tTxPoolConfig
config . NoLocals = nolocals
config . NoLocals = nolocals
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 := NewTxPool ( config , params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
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 ( )
defer pool . Stop ( )
pool . resetState ( )
// 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)
state , _ := pool . currentState ( )
state , _ := pool . currentState ( )
@ -748,13 +756,12 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := Defaul tTxPoolConfig
config := tes tTxPoolConfig
config . Lifetime = 250 * time . Millisecond
config . Lifetime = 250 * time . Millisecond
config . NoLocals = nolocals
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 ) } )
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 ( )
defer pool . Stop ( )
pool . resetState ( )
// 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 ( )
@ -817,7 +824,7 @@ func TestTransactionPendingLimiting(t *testing.T) {
pool . resetState ( )
pool . resetState ( )
// Keep queuing up transactions and make sure all above a limit are dropped
// Keep queuing up transactions and make sure all above a limit are dropped
for i := uint64 ( 0 ) ; i < Defaul tTxPoolConfig. AccountQueue + 5 ; i ++ {
for i := uint64 ( 0 ) ; i < tes tTxPoolConfig. AccountQueue + 5 ; i ++ {
if err := pool . AddRemote ( transaction ( i , big . NewInt ( 100000 ) , key ) ) ; err != nil {
if err := pool . AddRemote ( transaction ( i , big . NewInt ( 100000 ) , key ) ) ; err != nil {
t . Fatalf ( "tx %d: failed to add transaction: %v" , i , err )
t . Fatalf ( "tx %d: failed to add transaction: %v" , i , err )
}
}
@ -828,8 +835,8 @@ func TestTransactionPendingLimiting(t *testing.T) {
t . Errorf ( "tx %d: queue size mismatch: have %d, want %d" , i , pool . queue [ account ] . Len ( ) , 0 )
t . Errorf ( "tx %d: queue size mismatch: have %d, want %d" , i , pool . queue [ account ] . Len ( ) , 0 )
}
}
}
}
if len ( pool . all ) != int ( Defaul tTxPoolConfig. AccountQueue + 5 ) {
if len ( pool . all ) != int ( tes tTxPoolConfig. AccountQueue + 5 ) {
t . Errorf ( "total transaction mismatch: have %d, want %d" , len ( pool . all ) , Defaul tTxPoolConfig. AccountQueue + 5 )
t . Errorf ( "total transaction mismatch: have %d, want %d" , len ( pool . all ) , tes tTxPoolConfig. AccountQueue + 5 )
}
}
}
}
@ -845,7 +852,7 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
state1 , _ := pool1 . currentState ( )
state1 , _ := pool1 . currentState ( )
state1 . AddBalance ( account1 , big . NewInt ( 1000000 ) )
state1 . AddBalance ( account1 , big . NewInt ( 1000000 ) )
for i := uint64 ( 0 ) ; i < Defaul tTxPoolConfig. AccountQueue + 5 ; i ++ {
for i := uint64 ( 0 ) ; i < tes tTxPoolConfig. AccountQueue + 5 ; i ++ {
if err := pool1 . AddRemote ( transaction ( origin + i , big . NewInt ( 100000 ) , key1 ) ) ; err != nil {
if err := pool1 . AddRemote ( transaction ( origin + i , big . NewInt ( 100000 ) , key1 ) ) ; err != nil {
t . Fatalf ( "tx %d: failed to add transaction: %v" , i , err )
t . Fatalf ( "tx %d: failed to add transaction: %v" , i , err )
}
}
@ -857,7 +864,7 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
state2 . AddBalance ( account2 , big . NewInt ( 1000000 ) )
state2 . AddBalance ( account2 , big . NewInt ( 1000000 ) )
txns := [ ] * types . Transaction { }
txns := [ ] * types . Transaction { }
for i := uint64 ( 0 ) ; i < Defaul tTxPoolConfig. AccountQueue + 5 ; i ++ {
for i := uint64 ( 0 ) ; i < tes tTxPoolConfig. AccountQueue + 5 ; i ++ {
txns = append ( txns , transaction ( origin + i , big . NewInt ( 100000 ) , key2 ) )
txns = append ( txns , transaction ( origin + i , big . NewInt ( 100000 ) , key2 ) )
}
}
pool2 . AddRemotes ( txns )
pool2 . AddRemotes ( txns )
@ -888,12 +895,11 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := Defaul tTxPoolConfig
config := tes tTxPoolConfig
config . GlobalSlots = config . AccountSlots * 10
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 ) } )
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 ( )
defer pool . Stop ( )
pool . resetState ( )
// Create a number of test accounts and fund them
// Create a number of test accounts and fund them
state , _ := pool . currentState ( )
state , _ := pool . currentState ( )
@ -935,14 +941,13 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := Defaul tTxPoolConfig
config := tes tTxPoolConfig
config . AccountSlots = 2
config . AccountSlots = 2
config . AccountQueue = 2
config . AccountQueue = 2
config . GlobalSlots = 8
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 ) } )
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 ( )
defer pool . Stop ( )
pool . resetState ( )
// Create a number of test accounts and fund them
// Create a number of test accounts and fund them
state , _ := pool . currentState ( )
state , _ := pool . currentState ( )
@ -970,12 +975,11 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := Defaul tTxPoolConfig
config := tes tTxPoolConfig
config . GlobalSlots = 0
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 ) } )
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 ( )
defer pool . Stop ( )
pool . resetState ( )
// Create a number of test accounts and fund them
// Create a number of test accounts and fund them
state , _ := pool . currentState ( )
state , _ := pool . currentState ( )
@ -1019,9 +1023,8 @@ func TestTransactionPoolRepricing(t *testing.T) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
pool := NewTxPool ( Defaul tTxPoolConfig, params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
pool := NewTxPool ( tes tTxPoolConfig, params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
defer pool . Stop ( )
defer pool . Stop ( )
pool . resetState ( )
// Create a number of test accounts and fund them
// Create a number of test accounts and fund them
state , _ := pool . currentState ( )
state , _ := pool . currentState ( )
@ -1104,13 +1107,12 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := Defaul tTxPoolConfig
config := tes tTxPoolConfig
config . GlobalSlots = 2
config . GlobalSlots = 2
config . GlobalQueue = 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 ) } )
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 ( )
defer pool . Stop ( )
pool . resetState ( )
// Create a number of test accounts and fund them
// Create a number of test accounts and fund them
state , _ := pool . currentState ( )
state , _ := pool . currentState ( )
@ -1192,9 +1194,8 @@ func TestTransactionReplacement(t *testing.T) {
db , _ := ethdb . NewMemDatabase ( )
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
pool := NewTxPool ( Defaul tTxPoolConfig, params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
pool := NewTxPool ( tes tTxPoolConfig, params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
defer pool . Stop ( )
defer pool . Stop ( )
pool . resetState ( )
// Create a test account to add transactions with
// Create a test account to add transactions with
key , _ := crypto . GenerateKey ( )
key , _ := crypto . GenerateKey ( )
@ -1204,7 +1205,7 @@ func TestTransactionReplacement(t *testing.T) {
// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
price := int64 ( 100 )
price := int64 ( 100 )
threshold := ( price * ( 100 + int64 ( Defaul tTxPoolConfig. PriceBump ) ) ) / 100
threshold := ( price * ( 100 + int64 ( tes tTxPoolConfig. PriceBump ) ) ) / 100
if err := pool . AddRemote ( pricedTransaction ( 0 , big . NewInt ( 100000 ) , big . NewInt ( 1 ) , key ) ) ; err != nil {
if err := pool . AddRemote ( pricedTransaction ( 0 , big . NewInt ( 100000 ) , big . NewInt ( 1 ) , key ) ) ; err != nil {
t . Fatalf ( "failed to add original cheap pending transaction: %v" , err )
t . Fatalf ( "failed to add original cheap pending transaction: %v" , err )
@ -1250,6 +1251,113 @@ func TestTransactionReplacement(t *testing.T) {
}
}
}
}
// Tests that local transactions are journaled to disk, but remote transactions
// get discarded between restarts.
func TestTransactionJournaling ( t * testing . T ) { testTransactionJournaling ( t , false ) }
func TestTransactionJournalingNoLocals ( t * testing . T ) { testTransactionJournaling ( t , true ) }
func testTransactionJournaling ( t * testing . T , nolocals bool ) {
// Create a temporary file for the journal
file , err := ioutil . TempFile ( "" , "" )
if err != nil {
t . Fatalf ( "failed to create temporary journal: %v" , err )
}
journal := file . Name ( )
defer os . Remove ( journal )
// Clean up the temporary file, we only need the path for now
file . Close ( )
os . Remove ( journal )
// Create the original pool to inject transaction into the journal
db , _ := ethdb . NewMemDatabase ( )
statedb , _ := state . New ( common . Hash { } , state . NewDatabase ( db ) )
config := testTxPoolConfig
config . NoLocals = nolocals
config . Journal = journal
config . Rejournal = time . Second
pool := NewTxPool ( config , params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
// Create two test accounts to ensure remotes expire but locals do not
local , _ := crypto . GenerateKey ( )
remote , _ := crypto . GenerateKey ( )
statedb , _ = pool . currentState ( )
statedb . AddBalance ( crypto . PubkeyToAddress ( local . PublicKey ) , big . NewInt ( 1000000000 ) )
statedb . AddBalance ( crypto . PubkeyToAddress ( remote . PublicKey ) , big . NewInt ( 1000000000 ) )
// Add three local and a remote transactions and ensure they are queued up
if err := pool . AddLocal ( pricedTransaction ( 0 , big . NewInt ( 100000 ) , big . NewInt ( 1 ) , local ) ) ; err != nil {
t . Fatalf ( "failed to add local transaction: %v" , err )
}
if err := pool . AddLocal ( pricedTransaction ( 1 , big . NewInt ( 100000 ) , big . NewInt ( 1 ) , local ) ) ; err != nil {
t . Fatalf ( "failed to add local transaction: %v" , err )
}
if err := pool . AddLocal ( pricedTransaction ( 2 , big . NewInt ( 100000 ) , big . NewInt ( 1 ) , local ) ) ; err != nil {
t . Fatalf ( "failed to add local transaction: %v" , err )
}
if err := pool . AddRemote ( pricedTransaction ( 0 , big . NewInt ( 100000 ) , big . NewInt ( 1 ) , remote ) ) ; err != nil {
t . Fatalf ( "failed to add remote transaction: %v" , err )
}
pending , queued := pool . stats ( )
if pending != 4 {
t . Fatalf ( "pending transactions mismatched: have %d, want %d" , pending , 4 )
}
if queued != 0 {
t . Fatalf ( "queued transactions mismatched: have %d, want %d" , queued , 0 )
}
if err := validateTxPoolInternals ( pool ) ; err != nil {
t . Fatalf ( "pool internal state corrupted: %v" , err )
}
// Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive
pool . Stop ( )
statedb . SetNonce ( crypto . PubkeyToAddress ( local . PublicKey ) , 1 )
pool = NewTxPool ( config , params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
pending , queued = pool . stats ( )
if queued != 0 {
t . Fatalf ( "queued transactions mismatched: have %d, want %d" , queued , 0 )
}
if nolocals {
if pending != 0 {
t . Fatalf ( "pending transactions mismatched: have %d, want %d" , pending , 0 )
}
} else {
if pending != 2 {
t . Fatalf ( "pending transactions mismatched: have %d, want %d" , pending , 2 )
}
}
if err := validateTxPoolInternals ( pool ) ; err != nil {
t . Fatalf ( "pool internal state corrupted: %v" , err )
}
// Bump the nonce temporarily and ensure the newly invalidated transaction is removed
statedb . SetNonce ( crypto . PubkeyToAddress ( local . PublicKey ) , 2 )
pool . resetState ( )
time . Sleep ( 2 * config . Rejournal )
pool . Stop ( )
statedb . SetNonce ( crypto . PubkeyToAddress ( local . PublicKey ) , 1 )
pool = NewTxPool ( config , params . TestChainConfig , new ( event . TypeMux ) , func ( ) ( * state . StateDB , error ) { return statedb , nil } , func ( ) * big . Int { return big . NewInt ( 1000000 ) } )
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 )
}
}
if err := validateTxPoolInternals ( pool ) ; err != nil {
t . Fatalf ( "pool internal state corrupted: %v" , err )
}
}
// Benchmarks the speed of validating the contents of the pending queue of the
// Benchmarks the speed of validating the contents of the pending queue of the
// transaction pool.
// transaction pool.
func BenchmarkPendingDemotion100 ( b * testing . B ) { benchmarkPendingDemotion ( b , 100 ) }
func BenchmarkPendingDemotion100 ( b * testing . B ) { benchmarkPendingDemotion ( b , 100 ) }