From d91e0c9fc58c917284a6b70b6468fc1ccf3312f3 Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 22 Oct 2024 19:56:59 +0800 Subject: [PATCH] fix(taiko-geth): stop using `RevertToSnapshot` when fetching mempool (#336) --- core/state/statedb.go | 5 ----- miner/taiko_worker.go | 41 ++++++++++++++++++++++---------------- miner/taiko_worker_test.go | 4 ++-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index ca7e94834d5c..b2b4f8fb97b1 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -702,11 +702,6 @@ func (s *StateDB) Copy() *StateDB { return state } -// CHANGE(taiko): RevisionId returns the latest snapshot id. -func (s *StateDB) RevisionId() int { - return s.journal.nextRevisionId -} - // Snapshot returns an identifier for the current revision of the state. func (s *StateDB) Snapshot() int { return s.journal.snapshot() diff --git a/miner/taiko_worker.go b/miner/taiko_worker.go index 7a311c62cd21..bdf766cba31b 100644 --- a/miner/taiko_worker.go +++ b/miner/taiko_worker.go @@ -5,6 +5,7 @@ import ( "compress/zlib" "errors" "fmt" + "maps" "math/big" "time" @@ -17,8 +18,8 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" - "golang.org/x/exp/maps" ) // BuildTransactionsLists builds multiple transactions lists which satisfy all the given conditions @@ -71,14 +72,15 @@ func (w *Miner) buildTransactionsLists( localTxs, remoteTxs = w.getPendingTxs(localAccounts, baseFee) ) - commitTxs := func() (*PreBuiltTxList, error) { + commitTxs := func(firstTransaction *types.Transaction) (*types.Transaction, *PreBuiltTxList, error) { env.tcount = 0 env.txs = []*types.Transaction{} env.gasPool = new(core.GasPool).AddGas(blockMaxGasLimit) env.header.GasLimit = blockMaxGasLimit - w.commitL2Transactions( + lastTransaction := w.commitL2Transactions( env, + firstTransaction, newTransactionsByPriceAndNonce(signer, maps.Clone(localTxs), baseFee), newTransactionsByPriceAndNonce(signer, maps.Clone(remoteTxs), baseFee), maxBytesPerTxList, @@ -87,19 +89,22 @@ func (w *Miner) buildTransactionsLists( b, err := encodeAndCompressTxList(env.txs) if err != nil { - return nil, err + return nil, nil, err } - return &PreBuiltTxList{ + return lastTransaction, &PreBuiltTxList{ TxList: env.txs, EstimatedGasUsed: env.header.GasLimit - env.gasPool.Gas(), BytesLength: uint64(len(b)), }, nil } + var ( + lastTx *types.Transaction + res *PreBuiltTxList + ) for i := 0; i < int(maxTransactionsLists); i++ { - res, err := commitTxs() - if err != nil { + if lastTx, res, err = commitTxs(lastTx); err != nil { return nil, err } @@ -227,16 +232,22 @@ func (w *Miner) getPendingTxs(localAccounts []string, baseFee *big.Int) ( // commitL2Transactions tries to commit the transactions into the given state. func (w *Miner) commitL2Transactions( env *environment, + firstTransaction *types.Transaction, txsLocal *transactionsByPriceAndNonce, txsRemote *transactionsByPriceAndNonce, maxBytesPerTxList uint64, minTip uint64, -) { +) *types.Transaction { var ( - txs = txsLocal - isLocal = true + txs = txsLocal + isLocal = true + lastTransaction *types.Transaction ) + if firstTransaction != nil { + env.txs = append(env.txs, firstTransaction) + } + loop: for { // If we don't have enough gas for any further transactions then we're done. @@ -284,8 +295,6 @@ loop: // Start executing the transaction env.state.SetTxContext(tx.Hash(), env.tcount) - snap := env.state.RevisionId() - gasPool := env.gasPool.Gas() err := w.commitTransaction(env, tx) switch { case errors.Is(err, core.ErrNonceTooLow): @@ -303,7 +312,6 @@ loop: txs.Pop() continue } - if len(data) >= int(maxBytesPerTxList) { // Encode and compress the txList, if the byte length is > maxBytesPerTxList, remove the latest tx and break. b, err := compress(data) @@ -313,15 +321,12 @@ loop: continue } if len(b) > int(maxBytesPerTxList) { + lastTransaction = env.txs[env.tcount-1] env.txs = env.txs[0 : env.tcount-1] - env.state.RevertToSnapshot(snap) - env.gasPool.SetGas(gasPool) break loop } } - env.tcount++ - default: // Transaction is regarded as invalid, drop all consecutive transactions from // the same sender because of `nonce-too-high` clause. @@ -329,6 +334,8 @@ loop: txs.Pop() } } + + return lastTransaction } // encodeAndCompressTxList encodes and compresses the given transactions list. diff --git a/miner/taiko_worker_test.go b/miner/taiko_worker_test.go index e978b7bc75cd..f5d7040961a8 100644 --- a/miner/taiko_worker_test.go +++ b/miner/taiko_worker_test.go @@ -54,14 +54,14 @@ func testGenerateWorker(t *testing.T, txCount int) *Miner { } func TestBuildTransactionsLists(t *testing.T) { - w := testGenerateWorker(t, 1000) + w := testGenerateWorker(t, 2000) maxBytesPerTxList := (params.BlobTxBytesPerFieldElement - 1) * params.BlobTxFieldElementsPerBlob txList, err := w.BuildTransactionsLists( testBankAddress, nil, 240_000_000, - uint64(maxBytesPerTxList), + uint64(maxBytesPerTxList)/10, nil, 1, )