mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
Merge 53ba5182ce into 406a852ec8
This commit is contained in:
commit
49f619fe36
2 changed files with 45 additions and 67 deletions
|
|
@ -571,10 +571,14 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error {
|
|||
FirstNonceGap: nil, // Pool allows arbitrary arrival order, don't invalidate nonce gaps
|
||||
UsedAndLeftSlots: nil, // Pool has own mechanism to limit the number of transactions
|
||||
ExistingExpenditure: func(addr common.Address) *big.Int {
|
||||
result := new(big.Int)
|
||||
if list := pool.pending[addr]; list != nil {
|
||||
return list.totalcost.ToBig()
|
||||
result.Add(result, list.totalcost.ToBig())
|
||||
}
|
||||
return new(big.Int)
|
||||
if queue, ok := pool.queue.get(addr); ok {
|
||||
result.Add(result, queue.totalcost.ToBig())
|
||||
}
|
||||
return result
|
||||
},
|
||||
ExistingCost: func(addr common.Address, nonce uint64) *big.Int {
|
||||
if list := pool.pending[addr]; list != nil {
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@ func TestPostponing(t *testing.T) {
|
|||
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), newReserver())
|
||||
defer pool.Close()
|
||||
|
||||
// Create two test accounts to produce different gap profiles with
|
||||
// Create two test accounts with different cost transactions
|
||||
keys := make([]*ecdsa.PrivateKey, 2)
|
||||
accs := make([]common.Address, len(keys))
|
||||
|
||||
|
|
@ -800,27 +800,24 @@ func TestPostponing(t *testing.T) {
|
|||
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100))
|
||||
}
|
||||
// Add a batch consecutive pending transactions for validation
|
||||
txs := []*types.Transaction{}
|
||||
for i, key := range keys {
|
||||
for j := 0; j < 100; j++ {
|
||||
var tx *types.Transaction
|
||||
if (i+j)%2 == 0 {
|
||||
tx = transaction(uint64(j), 25000, key)
|
||||
} else {
|
||||
tx = transaction(uint64(j), 50000, key)
|
||||
}
|
||||
txs = append(txs, tx)
|
||||
}
|
||||
// Add one transaction per account with different costs
|
||||
// Account 0: cost 50100 (will be removed after balance -1)
|
||||
// Account 1: cost 20100 (will remain after balance -1)
|
||||
txs := []*types.Transaction{
|
||||
transaction(uint64(0), 50000, keys[0]), // cost: 50000*1 + 100 = 50100
|
||||
transaction(uint64(0), 25000, keys[1]), // cost: 25000*1 + 100 = 25100
|
||||
}
|
||||
for i, err := range pool.addRemotesSync(txs) {
|
||||
if err != nil {
|
||||
t.Fatalf("tx %d: failed to add transactions: %v", i, err)
|
||||
}
|
||||
}
|
||||
// Check that pre and post validations leave the pool as is
|
||||
if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) {
|
||||
t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs))
|
||||
// Check that both transactions are in pending pool
|
||||
if pool.pending[accs[0]].Len() != 1 {
|
||||
t.Errorf("account 0 pending transaction mismatch: have %d, want %d", pool.pending[accs[0]].Len(), 1)
|
||||
}
|
||||
if pool.pending[accs[1]].Len() != 1 {
|
||||
t.Errorf("account 1 pending transaction mismatch: have %d, want %d", pool.pending[accs[1]].Len(), 1)
|
||||
}
|
||||
if len(pool.queue.addresses()) != 0 {
|
||||
t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue.addresses()), 0)
|
||||
|
|
@ -829,66 +826,43 @@ func TestPostponing(t *testing.T) {
|
|||
t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs))
|
||||
}
|
||||
<-pool.requestReset(nil, nil)
|
||||
if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) {
|
||||
t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs))
|
||||
if pool.pending[accs[0]].Len() != 1 {
|
||||
t.Errorf("account 0 pending transaction mismatch after reset: have %d, want %d", pool.pending[accs[0]].Len(), 1)
|
||||
}
|
||||
if pool.pending[accs[1]].Len() != 1 {
|
||||
t.Errorf("account 1 pending transaction mismatch after reset: have %d, want %d", pool.pending[accs[1]].Len(), 1)
|
||||
}
|
||||
if len(pool.queue.addresses()) != 0 {
|
||||
t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue.addresses()), 0)
|
||||
t.Errorf("queued accounts mismatch after reset: have %d, want %d", len(pool.queue.addresses()), 0)
|
||||
}
|
||||
if pool.all.Count() != len(txs) {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs))
|
||||
t.Errorf("total transaction mismatch after reset: have %d, want %d", pool.all.Count(), len(txs))
|
||||
}
|
||||
// Reduce the balance of the account, and check that transactions are reorganised
|
||||
// Reduce the balance of both accounts by 1, and check that transactions are reorganised
|
||||
for _, addr := range accs {
|
||||
testAddBalance(pool, addr, big.NewInt(-1))
|
||||
}
|
||||
<-pool.requestReset(nil, nil)
|
||||
|
||||
// The first account's first transaction remains valid, check that subsequent
|
||||
// ones are either filtered out, or queued up for later.
|
||||
if _, ok := pool.pending[accs[0]].txs.items[txs[0].Nonce()]; !ok {
|
||||
t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txs[0])
|
||||
// Account 0 (balance: 50099): transaction cost 50100 should be removed (insufficient funds)
|
||||
if pool.pending[accs[0]] != nil && pool.pending[accs[0]].Len() > 0 {
|
||||
t.Errorf("account 0: out-of-fund transaction still present in pending pool")
|
||||
}
|
||||
list, _ := pool.queue.get(accs[0])
|
||||
if _, ok := list.txs.items[txs[0].Nonce()]; ok {
|
||||
t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txs[0])
|
||||
if list, ok := pool.queue.get(accs[0]); ok && list.Len() > 0 {
|
||||
t.Errorf("account 0: out-of-fund transaction present in queue")
|
||||
}
|
||||
for i, tx := range txs[1:100] {
|
||||
if i%2 == 1 {
|
||||
if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
|
||||
}
|
||||
if _, ok := list.txs.items[tx.Nonce()]; !ok {
|
||||
t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
|
||||
}
|
||||
} else {
|
||||
if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
|
||||
}
|
||||
if _, ok := list.txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
|
||||
}
|
||||
}
|
||||
|
||||
// Account 1 (balance: 50099): transaction cost 20100 should remain (sufficient funds)
|
||||
if pool.pending[accs[1]] == nil || pool.pending[accs[1]].Len() != 1 {
|
||||
t.Errorf("account 1: valid and funded transaction missing from pending pool")
|
||||
}
|
||||
// The second account's first transaction got invalid, check that all transactions
|
||||
// are either filtered out, or queued up for later.
|
||||
if pool.pending[accs[1]] != nil {
|
||||
t.Errorf("invalidated account still has pending transactions")
|
||||
if _, ok := pool.pending[accs[1]].txs.items[txs[1].Nonce()]; !ok {
|
||||
t.Errorf("account 1: valid and funded transaction missing from pending pool: %v", txs[1])
|
||||
}
|
||||
list, _ = pool.queue.get(accs[1])
|
||||
for i, tx := range txs[100:] {
|
||||
if i%2 == 1 {
|
||||
if _, ok := list.txs.items[tx.Nonce()]; !ok {
|
||||
t.Errorf("tx %d: valid but future transaction missing from future queue: %v", 100+i, tx)
|
||||
}
|
||||
} else {
|
||||
if _, ok := list.txs.items[tx.Nonce()]; ok {
|
||||
t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", 100+i, tx)
|
||||
}
|
||||
}
|
||||
}
|
||||
if pool.all.Count() != len(txs)/2 {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)/2)
|
||||
|
||||
// Total transaction count should be 1 (only account 1's transaction remains)
|
||||
if pool.all.Count() != 1 {
|
||||
t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -957,7 +931,7 @@ func TestQueueAccountLimiting(t *testing.T) {
|
|||
defer pool.Close()
|
||||
|
||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||
testAddBalance(pool, account, big.NewInt(1000000))
|
||||
testAddBalance(pool, account, big.NewInt(int64(testTxPoolConfig.AccountQueue+5)*100100))
|
||||
|
||||
// Keep queuing up transactions and make sure all above a limit are dropped
|
||||
for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ {
|
||||
|
|
@ -1352,7 +1326,7 @@ func TestPendingMinimumAllowance(t *testing.T) {
|
|||
keys := make([]*ecdsa.PrivateKey, 5)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i], _ = crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(int64(config.AccountSlots)*100100))
|
||||
}
|
||||
// Generate and queue a batch of transactions
|
||||
nonces := make(map[common.Address]uint64)
|
||||
|
|
@ -1745,7 +1719,7 @@ func TestStableUnderpricing(t *testing.T) {
|
|||
keys := make([]*ecdsa.PrivateKey, 2)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i], _ = crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(int64(config.GlobalSlots*100100)))
|
||||
}
|
||||
// Fill up the entire queue with the same transaction price points
|
||||
txs := types.Transactions{}
|
||||
|
|
|
|||
Loading…
Reference in a new issue