瀏覽代碼

core: add testcase for txpool

Martin Holst Swende 8 年之前
父節點
當前提交
b0b3cf2eeb
共有 2 個文件被更改,包括 79 次插入0 次删除
  1. 13 0
      core/tx_pool.go
  2. 66 0
      core/tx_pool_test.go

+ 13 - 0
core/tx_pool.go

@@ -301,6 +301,19 @@ func (pool *TxPool) Stats() (int, int) {
 	return pool.stats()
 }
 
+// validateInternals checks if the content in pool.all
+// is consistent with the numbers reported in pending and queued
+func (pool *TxPool) validateInternals() error {
+	pool.mu.RLock()
+	defer pool.mu.RUnlock()
+	p, q := pool.stats()
+	a := len(pool.all)
+	if a != p+q {
+		return fmt.Errorf("Pool.all size %d != %d pending + %d queued", a, p, q)
+	}
+	return nil
+}
+
 // stats retrieves the current pool stats, namely the number of pending and the
 // number of queued (non-executable) transactions.
 func (pool *TxPool) stats() (int, int) {

+ 66 - 0
core/tx_pool_test.go

@@ -719,6 +719,12 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
 		txns = append(txns, transaction(origin+i, big.NewInt(100000), key2))
 	}
 	pool2.AddBatch(txns)
+	if err := pool2.validateInternals(); err != nil {
+		t.Error(err)
+	}
+	if err := pool1.validateInternals(); err != nil {
+		t.Error(err)
+	}
 
 	// Ensure the batch optimization honors the same pool mechanics
 	if len(pool1.pending) != len(pool2.pending) {
@@ -769,6 +775,9 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
 	// Import the batch and verify that limits have been enforced
 	pool.AddBatch(txs)
 
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
 	pending := 0
 	for _, list := range pool.pending {
 		pending += list.Len()
@@ -778,6 +787,42 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
 	}
 }
 
+// Tests that if transactions start being capped, transasctions are also removed from 'all'
+func TestTransactionCapClearsFromAll(t *testing.T) {
+	// Reduce the queue limits to shorten test time
+	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
+	db, _ := ethdb.NewMemDatabase()
+	statedb, _ := state.New(common.Hash{}, db)
+
+	pool := NewTxPool(DefaultTxPoolConfig, params.TestChainConfig, new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
+	pool.resetState()
+
+	// Create a number of test accounts and fund them
+	state, _ := pool.currentState()
+
+	key, _ := crypto.GenerateKey()
+	addr := crypto.PubkeyToAddress(key.PublicKey)
+	state.AddBalance(addr, big.NewInt(1000000))
+
+	txs := types.Transactions{}
+	nonce := uint64(0)
+	for j := 0; j < int(DefaultTxPoolConfig.GlobalSlots)*2; j++ {
+		tx := transaction(nonce, big.NewInt(100000), key)
+		txs = append(txs, tx)
+		nonce++
+	}
+	// Import the batch and verify that limits have been enforced
+	pool.AddBatch(txs)
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
+}
+
 // Tests that if the transaction count belonging to multiple accounts go above
 // some hard threshold, if they are under the minimum guaranteed slot count then
 // the transactions are still kept.
@@ -815,6 +860,10 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
 	// Import the batch and verify that limits have been enforced
 	pool.AddBatch(txs)
 
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
+
 	for addr, list := range pool.pending {
 		if list.Len() != int(DefaultTxPoolConfig.AccountSlots) {
 			t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), DefaultTxPoolConfig.AccountSlots)
@@ -860,6 +909,10 @@ func TestTransactionPoolRepricing(t *testing.T) {
 	// Import the batch and that both pending and queued transactions match up
 	pool.AddBatch(txs)
 
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
+
 	pending, queued := pool.stats()
 	if pending != 4 {
 		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4)
@@ -894,6 +947,10 @@ func TestTransactionPoolRepricing(t *testing.T) {
 	if pending, _ = pool.stats(); pending != 3 {
 		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
 	}
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
+
 }
 
 // Tests that when the pool reaches its global transaction limit, underpriced
@@ -937,6 +994,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
 
 	// Import the batch and that both pending and queued transactions match up
 	pool.AddBatch(txs)
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
 
 	pending, queued := pool.stats()
 	if pending != 3 {
@@ -980,6 +1040,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
 	if queued != 2 {
 		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
 	}
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
 }
 
 // Tests that the pool rejects replacement transactions that don't meet the minimum
@@ -1041,6 +1104,9 @@ func TestTransactionReplacement(t *testing.T) {
 	if err := pool.Add(pricedTransaction(2, big.NewInt(100000), big.NewInt(threshold+1), key)); err != nil {
 		t.Fatalf("failed to replace original queued transaction: %v", err)
 	}
+	if err := pool.validateInternals(); err != nil {
+		t.Error(err)
+	}
 }
 
 // Benchmarks the speed of validating the contents of the pending queue of the