|
|
|
@ -23,6 +23,7 @@ import ( |
|
|
|
|
"math/big" |
|
|
|
|
"math/rand" |
|
|
|
|
"os" |
|
|
|
|
"sync/atomic" |
|
|
|
|
"testing" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
@ -69,9 +70,13 @@ type testBlockChain struct { |
|
|
|
|
chainHeadFeed *event.Feed |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (bc *testBlockChain) SetGasLimit(value uint64) { |
|
|
|
|
atomic.StoreUint64(&bc.gasLimit, value) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (bc *testBlockChain) CurrentBlock() *types.Block { |
|
|
|
|
return types.NewBlock(blockfactory.NewTestHeader().With(). |
|
|
|
|
GasLimit(bc.gasLimit). |
|
|
|
|
GasLimit(atomic.LoadUint64(&bc.gasLimit)). |
|
|
|
|
Header(), nil, nil, nil, nil, nil) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -162,12 +167,14 @@ func createBlockChain() *BlockChainImpl { |
|
|
|
|
return blockchain |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { |
|
|
|
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase())) |
|
|
|
|
blockchain := &testBlockChain{statedb, 1e18, new(event.Feed)} |
|
|
|
|
func setupTxPool(chain blockChain) (*TxPool, *ecdsa.PrivateKey) { |
|
|
|
|
if chain == nil { |
|
|
|
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase())) |
|
|
|
|
chain = &testBlockChain{statedb, 1e18, new(event.Feed)} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
key, _ := crypto.GenerateKey() |
|
|
|
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, dummyErrorSink) |
|
|
|
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, chain, dummyErrorSink) |
|
|
|
|
|
|
|
|
|
return pool, key |
|
|
|
|
} |
|
|
|
@ -282,7 +289,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { |
|
|
|
|
func TestInvalidTransactions(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
tx := transaction(0, 0, 100, key) |
|
|
|
@ -324,8 +331,7 @@ func TestInvalidTransactions(t *testing.T) { |
|
|
|
|
func TestErrorSink(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool.chain = createBlockChain() |
|
|
|
|
pool, key := setupTxPool(createBlockChain()) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
testTxErrorSink := types.NewTransactionErrorSink() |
|
|
|
@ -396,8 +402,7 @@ func TestErrorSink(t *testing.T) { |
|
|
|
|
func TestCreateValidatorTransaction(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, _ := setupTxPool() |
|
|
|
|
pool.chain = createBlockChain() |
|
|
|
|
pool, _ := setupTxPool(createBlockChain()) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
fromKey, _ := crypto.GenerateKey() |
|
|
|
@ -422,8 +427,7 @@ func TestCreateValidatorTransaction(t *testing.T) { |
|
|
|
|
func TestMixedTransactions(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, _ := setupTxPool() |
|
|
|
|
pool.chain = createBlockChain() |
|
|
|
|
pool, _ := setupTxPool(createBlockChain()) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
fromKey, _ := crypto.GenerateKey() |
|
|
|
@ -457,7 +461,7 @@ func TestBlacklistedTransactions(t *testing.T) { |
|
|
|
|
// DO NOT parallelize, test will add accounts to tx pool config.
|
|
|
|
|
|
|
|
|
|
// Create the pool
|
|
|
|
|
pool, _ := setupTxPool() |
|
|
|
|
pool, _ := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
// Create testing keys
|
|
|
|
@ -501,7 +505,7 @@ func TestBlacklistedTransactions(t *testing.T) { |
|
|
|
|
func TestTransactionQueue(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
tx := transaction(0, 0, 100, key) |
|
|
|
@ -528,7 +532,7 @@ func TestTransactionQueue(t *testing.T) { |
|
|
|
|
t.Error("expected transaction queue to be empty. is", len(pool.queue)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pool, key = setupTxPool() |
|
|
|
|
pool, key = setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
tx1 := transaction(0, 0, 100, key) |
|
|
|
@ -555,7 +559,7 @@ func TestTransactionQueue(t *testing.T) { |
|
|
|
|
func TestTransactionNegativeValue(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
tx, _ := types.SignTx( |
|
|
|
@ -569,9 +573,10 @@ func TestTransactionNegativeValue(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestTransactionChainFork(t *testing.T) { |
|
|
|
|
t.Skip("This test doesn't work with race detector") |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
addr := crypto.PubkeyToAddress(key.PublicKey) |
|
|
|
@ -600,18 +605,13 @@ func TestTransactionChainFork(t *testing.T) { |
|
|
|
|
func TestTransactionDoubleNonce(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
key, _ := crypto.GenerateKey() |
|
|
|
|
addr := crypto.PubkeyToAddress(key.PublicKey) |
|
|
|
|
resetState := func() { |
|
|
|
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase())) |
|
|
|
|
statedb.AddBalance(addr, big.NewInt(1000000000000000000)) |
|
|
|
|
|
|
|
|
|
pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} |
|
|
|
|
pool.lockedReset(nil, nil) |
|
|
|
|
} |
|
|
|
|
resetState() |
|
|
|
|
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase())) |
|
|
|
|
statedb.AddBalance(addr, big.NewInt(1000000000000000000)) |
|
|
|
|
pool, _ := setupTxPool(&testBlockChain{statedb, 1000000, new(event.Feed)}) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
pool.lockedReset(nil, nil) |
|
|
|
|
|
|
|
|
|
signer := types.HomesteadSigner{} |
|
|
|
|
tx1, _ := types.SignTx( |
|
|
|
@ -656,7 +656,7 @@ func TestTransactionDoubleNonce(t *testing.T) { |
|
|
|
|
func TestTransactionMissingNonce(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
addr := crypto.PubkeyToAddress(key.PublicKey) |
|
|
|
@ -680,7 +680,7 @@ func TestTransactionNonceRecovery(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
const n = 10 |
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
addr := crypto.PubkeyToAddress(key.PublicKey) |
|
|
|
@ -706,7 +706,7 @@ func TestTransactionDropping(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
// Create a test account and fund it
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
account, _ := deriveSender(transaction(0, 0, 0, key)) |
|
|
|
@ -774,7 +774,7 @@ func TestTransactionDropping(t *testing.T) { |
|
|
|
|
t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4) |
|
|
|
|
} |
|
|
|
|
// Reduce the block gas limit, check that invalidated transactions are dropped
|
|
|
|
|
pool.chain.(*testBlockChain).gasLimit = 100 |
|
|
|
|
pool.chain.(*testBlockChain).SetGasLimit(100) |
|
|
|
|
pool.lockedReset(nil, nil) |
|
|
|
|
|
|
|
|
|
if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { |
|
|
|
@ -918,7 +918,7 @@ func TestTransactionQueueAccountLimiting(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
// Create a test account and fund it
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
account, _ := deriveSender(transaction(0, 0, 0, key)) |
|
|
|
@ -1119,7 +1119,7 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
// Add a batch of transactions to a pool one by one
|
|
|
|
|
pool1, key1 := setupTxPool() |
|
|
|
|
pool1, key1 := setupTxPool(nil) |
|
|
|
|
defer pool1.Stop() |
|
|
|
|
|
|
|
|
|
account1, _ := deriveSender(transaction(0, 0, 0, key1)) |
|
|
|
@ -1131,7 +1131,7 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Add a batch of transactions to a pool in one big batch
|
|
|
|
|
pool2, key2 := setupTxPool() |
|
|
|
|
pool2, key2 := setupTxPool(nil) |
|
|
|
|
defer pool2.Stop() |
|
|
|
|
|
|
|
|
|
account2, _ := deriveSender(transaction(0, 0, 0, key2)) |
|
|
|
@ -1523,7 +1523,7 @@ func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 1 |
|
|
|
|
|
|
|
|
|
func benchmarkPendingDemotion(b *testing.B, size int) { |
|
|
|
|
// Add a batch of transactions to a pool one by one
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
account, _ := deriveSender(transaction(0, 0, 0, key)) |
|
|
|
@ -1548,7 +1548,7 @@ func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 1 |
|
|
|
|
|
|
|
|
|
func benchmarkFuturePromotion(b *testing.B, size int) { |
|
|
|
|
// Add a batch of transactions to a pool one by one
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
account, _ := deriveSender(transaction(0, 0, 0, key)) |
|
|
|
@ -1568,7 +1568,7 @@ func benchmarkFuturePromotion(b *testing.B, size int) { |
|
|
|
|
// Benchmarks the speed of iterative transaction insertion.
|
|
|
|
|
func BenchmarkPoolInsert(b *testing.B) { |
|
|
|
|
// Generate a batch of transactions to enqueue into the pool
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
account, _ := deriveSender(transaction(0, 0, 0, key)) |
|
|
|
@ -1592,7 +1592,7 @@ func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 1 |
|
|
|
|
|
|
|
|
|
func benchmarkPoolBatchInsert(b *testing.B, size int) { |
|
|
|
|
// Generate a batch of transactions to enqueue into the pool
|
|
|
|
|
pool, key := setupTxPool() |
|
|
|
|
pool, key := setupTxPool(nil) |
|
|
|
|
defer pool.Stop() |
|
|
|
|
|
|
|
|
|
account, _ := deriveSender(transaction(0, 0, 0, key)) |
|
|
|
|