aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMartin Holst Swende <martin@swende.se>2017-09-04 17:48:36 +0800
committerPéter Szilágyi <peterke@gmail.com>2017-09-04 17:48:36 +0800
commit1901521ed0423a5feaadd3635b10783c5a998151 (patch)
treef0fce9b8b2ab34a94b684f6e74f8b4318e674978 /core
parent23b51a68cbdd637824be906c9354a0b59c57491b (diff)
downloaddexon-1901521ed0423a5feaadd3635b10783c5a998151.tar
dexon-1901521ed0423a5feaadd3635b10783c5a998151.tar.gz
dexon-1901521ed0423a5feaadd3635b10783c5a998151.tar.bz2
dexon-1901521ed0423a5feaadd3635b10783c5a998151.tar.lz
dexon-1901521ed0423a5feaadd3635b10783c5a998151.tar.xz
dexon-1901521ed0423a5feaadd3635b10783c5a998151.tar.zst
dexon-1901521ed0423a5feaadd3635b10783c5a998151.zip
core: Fix flaw where underpriced locals were removed (#15081)
* core: Fix flaw where underpriced locals were removed * core: minor code cleanups for tx pool tests
Diffstat (limited to 'core')
-rw-r--r--core/tx_list.go1
-rw-r--r--core/tx_pool_test.go62
2 files changed, 62 insertions, 1 deletions
diff --git a/core/tx_list.go b/core/tx_list.go
index 0d87c20bc..1087970fa 100644
--- a/core/tx_list.go
+++ b/core/tx_list.go
@@ -435,6 +435,7 @@ func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transact
}
// Stop the discards if we've reached the threshold
if tx.GasPrice().Cmp(threshold) >= 0 {
+ save = append(save, tx)
break
}
// Non stale transaction found, discard unless local
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index ee1ddd4bb..c1bcb1b2d 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -976,7 +976,7 @@ 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, transactions are also removed from 'all'
func TestTransactionCapClearsFromAll(t *testing.T) {
// Create the pool to test the limit enforcement with
db, _ := ethdb.NewMemDatabase()
@@ -1141,6 +1141,66 @@ func TestTransactionPoolRepricing(t *testing.T) {
}
}
+// Tests that setting the transaction pool gas price to a higher value does not
+// remove local transactions.
+func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
+ // Create the pool to test the pricing enforcement with
+ db, _ := ethdb.NewMemDatabase()
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
+ blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed), new(event.Feed)}
+
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
+ defer pool.Stop()
+
+ // Create a number of test accounts and fund them
+ state, _ := pool.blockChain.State()
+
+ keys := make([]*ecdsa.PrivateKey, 3)
+ for i := 0; i < len(keys); i++ {
+ keys[i], _ = crypto.GenerateKey()
+ state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000))
+ }
+ // Create transaction (both pending and queued) with a linearly growing gasprice
+ for i := uint64(0); i < 500; i++ {
+ // Add pending
+ p_tx := pricedTransaction(i, big.NewInt(100000), big.NewInt(int64(i)), keys[2])
+ if err := pool.AddLocal(p_tx); err != nil {
+ t.Fatal(err)
+ }
+ // Add queued
+ q_tx := pricedTransaction(i+501, big.NewInt(100000), big.NewInt(int64(i)), keys[2])
+ if err := pool.AddLocal(q_tx); err != nil {
+ t.Fatal(err)
+ }
+ }
+ pending, queued := pool.Stats()
+ expPending, expQueued := 500, 500
+ validate := func() {
+ pending, queued = pool.Stats()
+ if pending != expPending {
+ t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending)
+ }
+ if queued != expQueued {
+ t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued)
+ }
+
+ if err := validateTxPoolInternals(pool); err != nil {
+ t.Fatalf("pool internal state corrupted: %v", err)
+ }
+ }
+ validate()
+
+ // Reprice the pool and check that nothing is dropped
+ pool.SetGasPrice(big.NewInt(2))
+ validate()
+
+ pool.SetGasPrice(big.NewInt(2))
+ pool.SetGasPrice(big.NewInt(4))
+ pool.SetGasPrice(big.NewInt(8))
+ pool.SetGasPrice(big.NewInt(100))
+ validate()
+}
+
// Tests that when the pool reaches its global transaction limit, underpriced
// transactions are gradually shifted out for more expensive ones and any gapped
// pending transactions are moved into te queue.