From 81c3f1e0359e1b08865da770dd8ae200dd33bce8 Mon Sep 17 00:00:00 2001 From: marcello33 Date: Tue, 13 Jun 2023 10:01:12 +0200 Subject: [PATCH] dev: chg: txpool_test regression changes after merge --- core/txpool/txpool2_test_BOR.go | 231 -------------------------------- core/txpool/txpool_test.go | 11 +- 2 files changed, 4 insertions(+), 238 deletions(-) delete mode 100644 core/txpool/txpool2_test_BOR.go diff --git a/core/txpool/txpool2_test_BOR.go b/core/txpool/txpool2_test_BOR.go deleted file mode 100644 index 5e2298a5a3..0000000000 --- a/core/txpool/txpool2_test_BOR.go +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . -package txpool - -import ( - "crypto/ecdsa" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" -) - -// TODO marcello merge this file with txpool2_test.go - -func pricedValuedTransaction(nonce uint64, value int64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { - tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(value), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) - return tx -} - -func count(t *testing.T, pool *TxPool) (pending int, queued int) { - t.Helper() - - pending, queued = pool.Stats() - - if err := validatePoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - return pending, queued -} - -func fillPool(t *testing.T, pool *TxPool) { - t.Helper() - // Create a number of test accounts, fund them and make transactions - executableTxs := types.Transactions{} - nonExecutableTxs := types.Transactions{} - - for i := 0; i < 384; i++ { - key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(10000000000)) - // Add executable ones - for j := 0; j < int(pool.config().AccountSlots); j++ { - executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key)) - } - } - // Import the batch and verify that limits have been enforced - pool.AddRemotesSync(executableTxs) - pool.AddRemotesSync(nonExecutableTxs) - pending, queued := pool.Stats() - slots := pool.all.Slots() - // sanity-check that the test prerequisites are ok (pending full) - if have, want := pending, slots; have != want { - t.Fatalf("have %d, want %d", have, want) - } - - if have, want := queued, 0; have != want { - t.Fatalf("have %d, want %d", have, want) - } - - t.Logf("pool.config: GlobalSlots=%d, GlobalQueue=%d\n", pool.config.GlobalSlots, pool.config.GlobalQueue) - t.Logf("pending: %d queued: %d, all: %d\n", pending, queued, slots) -} - -// Tests that if a batch high-priced of non-executables arrive, they do not kick out -// executable transactions -func TestTransactionFutureAttack(t *testing.T) { - t.Parallel() - - // Create the pool to test the limit enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{1000000, statedb, new(event.Feed)} - config := testTxPoolConfig - config.GlobalQueue = 100 - config.GlobalSlots = 100 - pool := NewTxPool(config, eip1559Config, blockchain) - - defer pool.Stop() - fillPool(t, pool) - pending, _ := pool.Stats() - // Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops - { - key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000)) - futureTxs := types.Transactions{} - for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ { - futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 100000, big.NewInt(500), key)) - } - for i := 0; i < 5; i++ { - pool.AddRemotesSync(futureTxs) - newPending, newQueued := count(t, pool) - t.Logf("pending: %d queued: %d, all: %d\n", newPending, newQueued, pool.all.Slots()) - } - } - - newPending, _ := pool.Stats() - // Pending should not have been touched - if have, want := newPending, pending; have < want { - t.Errorf("wrong pending-count, have %d, want %d (GlobalSlots: %d)", - have, want, pool.config.GlobalSlots) - } -} - -// Tests that if a batch high-priced of non-executables arrive, they do not kick out -// executable transactions -func TestTransactionFuture1559(t *testing.T) { - t.Parallel() - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{1000000, statedb, new(event.Feed)} - pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain) - - defer pool.Stop() - - // Create a number of test accounts, fund them and make transactions - fillPool(t, pool) - pending, _ := pool.Stats() - - // Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops - { - key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000)) - futureTxs := types.Transactions{} - for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ { - futureTxs = append(futureTxs, dynamicFeeTx(1000+uint64(j), 100000, big.NewInt(200), big.NewInt(101), key)) - } - pool.AddRemotesSync(futureTxs) - } - - newPending, _ := pool.Stats() - // Pending should not have been touched - if have, want := newPending, pending; have != want { - t.Errorf("Wrong pending-count, have %d, want %d (GlobalSlots: %d)", - have, want, pool.config.GlobalSlots) - } -} - -// Tests that if a batch of balance-overdraft txs arrive, they do not kick out -// executable transactions -func TestTransactionZAttack(t *testing.T) { - t.Parallel() - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{1000000, statedb, new(event.Feed)} - pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain) - - defer pool.Stop() - - // Create a number of test accounts, fund them and make transactions - fillPool(t, pool) - - countInvalidPending := func() int { - t.Helper() - - var ivpendingNum int - - pendingtxs, _ := pool.Content() - - for account, txs := range pendingtxs { - cur_balance := new(big.Int).Set(pool.currentState.GetBalance(account)) - for _, tx := range txs { - if cur_balance.Cmp(tx.Value()) <= 0 { - ivpendingNum++ - } else { - cur_balance.Sub(cur_balance, tx.Value()) - } - } - } - - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - return ivpendingNum - } - ivPending := countInvalidPending() - t.Logf("invalid pending: %d\n", ivPending) - - // Now, DETER-Z attack starts, let's add a bunch of expensive non-executables (from N accounts) along with balance-overdraft txs (from one account), and see if the pending-count drops - for j := 0; j < int(pool.config.GlobalQueue); j++ { - futureTxs := types.Transactions{} - key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000)) - futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 21000, big.NewInt(500), key)) - pool.AddRemotesSync(futureTxs) - } - - overDraftTxs := types.Transactions{} - { - key, _ := crypto.GenerateKey() - pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000)) - for j := 0; j < int(pool.config.GlobalSlots); j++ { - overDraftTxs = append(overDraftTxs, pricedValuedTransaction(uint64(j), 60000000000, 21000, big.NewInt(500), key)) - } - } - pool.AddRemotesSync(overDraftTxs) - pool.AddRemotesSync(overDraftTxs) - pool.AddRemotesSync(overDraftTxs) - pool.AddRemotesSync(overDraftTxs) - pool.AddRemotesSync(overDraftTxs) - - newPending, newQueued := count(t, pool) - newIvPending := countInvalidPending() - - t.Logf("pool.all.Slots(): %d\n", pool.all.Slots()) - t.Logf("pending: %d queued: %d, all: %d\n", newPending, newQueued, pool.all.Slots()) - t.Logf("invalid pending: %d\n", newIvPending) - - // Pending should not have been touched - if newIvPending != ivPending { - t.Errorf("Wrong invalid pending-count, have %d, want %d (GlobalSlots: %d, queued: %d)", - newIvPending, ivPending, pool.config.GlobalSlots, newQueued) - } -} diff --git a/core/txpool/txpool_test.go b/core/txpool/txpool_test.go index b1a32e359b..30f7cb23cd 100644 --- a/core/txpool/txpool_test.go +++ b/core/txpool/txpool_test.go @@ -33,6 +33,7 @@ import ( "time" "github.com/holiman/uint256" + "github.com/maticnetwork/crand" "go.uber.org/goleak" "gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/stat" @@ -49,12 +50,8 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" - - "github.com/JekaMas/crand" ) -// TODO marcello merge this file with txpool2_test_BOR.go - var ( // testTxPoolConfig is a transaction pool configuration without stateful disk // sideeffects used during testing. @@ -120,7 +117,7 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction { data := make([]byte, bytes) - crand.Read(data) + rand.Read(data) tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key) return tx @@ -145,7 +142,7 @@ func setupPool() (*TxPool, *ecdsa.PrivateKey) { return setupPoolWithConfig(params.TestChainConfig, testTxPoolConfig, txPoolGasLimit) } -func setupPoolWithConfig(config *params.ChainConfig, txPoolConfig TxPoolConfig, gasLimit uint64, options ...func(pool *TxPool)) (*TxPool, *ecdsa.PrivateKey) { +func setupPoolWithConfig(config *params.ChainConfig, txPoolConfig Config, gasLimit uint64, options ...func(pool *TxPool)) (*TxPool, *ecdsa.PrivateKey) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) blockchain := newTestBlockChain(10000000, statedb, new(event.Feed)) @@ -4458,7 +4455,7 @@ func apiWithMining(tb testing.TB, balanceStr string, batchesSize int, singleCase }() runWithTicker(tb, func(c chan struct{}) { - ch := make(chan NewTxsEvent, 10) + ch := make(chan core.NewTxsEvent, 10) sub := pool.SubscribeNewTxsEvent(ch) if sub == nil {