From 5bd2b5aa166549b08d3bdac6aca3480230b26983 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Wed, 18 Dec 2024 14:47:19 +0800 Subject: [PATCH 01/18] feat(op-geth): support droppingTxHashes when sendBundle --- core/types/bundle.go | 2 ++ core/types/transaction.go | 6 ++++++ internal/ethapi/api_bundle.go | 1 + miner/worker_builder.go | 28 ++++++++++++++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/core/types/bundle.go b/core/types/bundle.go index 5eb0922b9c..255ff1b49f 100644 --- a/core/types/bundle.go +++ b/core/types/bundle.go @@ -23,6 +23,7 @@ type SendBundleArgs struct { MinTimestamp *uint64 `json:"minTimestamp"` MaxTimestamp *uint64 `json:"maxTimestamp"` RevertingTxHashes []common.Hash `json:"revertingTxHashes"` + DroppingTxHashes []common.Hash `json:"droppingTxHashes"` } type Bundle struct { @@ -31,6 +32,7 @@ type Bundle struct { MinTimestamp uint64 MaxTimestamp uint64 RevertingTxHashes []common.Hash + DroppingTxHashes []common.Hash Price *big.Int // for bundle compare and prune diff --git a/core/types/transaction.go b/core/types/transaction.go index d7860b57bd..d9567b0d37 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -632,6 +632,12 @@ func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) { } } +func (s Transactions) Remove(idx int) Transactions { + copy(s[idx:], s[idx+1:]) + s[len(s)-1] = nil + return s[:len(s)-1] +} + // TxDifference returns a new set which is the difference between a and b. func TxDifference(a, b Transactions) Transactions { keep := make(Transactions, 0, len(a)) diff --git a/internal/ethapi/api_bundle.go b/internal/ethapi/api_bundle.go index d291dc2083..3e2e14c7fe 100644 --- a/internal/ethapi/api_bundle.go +++ b/internal/ethapi/api_bundle.go @@ -116,6 +116,7 @@ func (s *PrivateTxBundleAPI) SendBundle(ctx context.Context, args types.SendBund MinTimestamp: minTimestamp, MaxTimestamp: maxTimestamp, RevertingTxHashes: args.RevertingTxHashes, + DroppingTxHashes: args.DroppingTxHashes, } // If the maxBlockNumber and maxTimestamp are not set, set max ddl of bundle as types.MaxBundleAliveBlock diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 61a5672c2f..c88b613549 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -366,13 +366,25 @@ func (w *worker) simulateBundle( bundleGasFees = new(big.Int) ) + currentState := state.Copy() + for i, tx := range bundle.Txs { state.SetTxContext(tx.Hash(), i+currentTxCount) + prevState := currentState.Copy() + prevGasPool := new(core.GasPool).AddGas(gasPool.Gas()) + receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &w.coinbase, gasPool, state, env.header, tx, &tempGasUsed, *w.chain.GetVMConfig()) if err != nil { log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) + if containsHash(bundle.DroppingTxHashes, tx.Hash()) { + log.Warn("drop tx in bundle", "hash", tx.Hash().String()) + state = prevState + gasPool = prevGasPool + bundle.Txs = bundle.Txs.Remove(i) + continue + } if prune { if errors.Is(err, core.ErrGasLimitReached) && !pruneGasExceed { @@ -387,6 +399,14 @@ func (w *worker) simulateBundle( } if receipt.Status == types.ReceiptStatusFailed && !containsHash(bundle.RevertingTxHashes, receipt.TxHash) { + // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool + if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { + log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) + state = prevState + gasPool = prevGasPool + bundle.Txs = bundle.Txs.Remove(i) + continue + } err = errNonRevertingTxInBundleFailed log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) @@ -412,6 +432,14 @@ func (w *worker) simulateBundle( bundleGasFees.Add(bundleGasFees, txGasFees) } } + + // prune bundle when all txs are dropped + if len(bundle.Txs) == 0 { + log.Warn("prune bundle", "hash", bundle.Hash().String(), "err", "empty bundle") + w.eth.TxPool().PruneBundle(bundle.Hash()) + return nil, errors.New("empty bundle") + } + // if all txs in the bundle are from txpool, we accept the bundle without checking gas price bundleGasPrice := big.NewInt(0) if bundleGasUsed != 0 { From 6bbc128a6f7b9d8bcf6f0b9ceb47e5aa891b48e3 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Fri, 20 Dec 2024 11:28:20 +0800 Subject: [PATCH 02/18] fix: nil map in bundlepool and refine code --- miner/worker_builder.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/miner/worker_builder.go b/miner/worker_builder.go index c88b613549..182d91a7d5 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -366,13 +366,13 @@ func (w *worker) simulateBundle( bundleGasFees = new(big.Int) ) - currentState := state.Copy() - - for i, tx := range bundle.Txs { + txsLen := len(bundle.Txs) + for i := 0; i < txsLen; i++ { + tx := bundle.Txs[i] state.SetTxContext(tx.Hash(), i+currentTxCount) - prevState := currentState.Copy() - prevGasPool := new(core.GasPool).AddGas(gasPool.Gas()) + snap := state.Snapshot() + gp := gasPool.Gas() receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &w.coinbase, gasPool, state, env.header, tx, &tempGasUsed, *w.chain.GetVMConfig()) @@ -380,9 +380,11 @@ func (w *worker) simulateBundle( log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) if containsHash(bundle.DroppingTxHashes, tx.Hash()) { log.Warn("drop tx in bundle", "hash", tx.Hash().String()) - state = prevState - gasPool = prevGasPool + state.RevertToSnapshot(snap) + gasPool.SetGas(gp) bundle.Txs = bundle.Txs.Remove(i) + txsLen = len(bundle.Txs) + i-- continue } @@ -402,9 +404,11 @@ func (w *worker) simulateBundle( // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) - state = prevState - gasPool = prevGasPool + state.RevertToSnapshot(snap) + gasPool.SetGas(gp) bundle.Txs = bundle.Txs.Remove(i) + txsLen = len(bundle.Txs) + i-- continue } err = errNonRevertingTxInBundleFailed From 7012e8ab59090c3fd82c1d4b8a1ffbb4079245bc Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Mon, 23 Dec 2024 16:31:44 +0800 Subject: [PATCH 03/18] fix: fix potential index out of range risk --- core/txpool/bundlepool/bundlepool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index a1b0e1a838..33d420b143 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -375,7 +375,7 @@ func (p *BundlePool) reset(newHead *types.Header) { (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) - } else if txSet.Contains(bundle.Txs[0].Hash()) { + } else if len(bundle.Txs) == 0 || txSet.Contains(bundle.Txs[0].Hash()) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) } From faf00f99e46292f14cd6018c59586d1c3241f8b8 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Mon, 23 Dec 2024 16:50:57 +0800 Subject: [PATCH 04/18] feat: refine prune invalid bundle --- core/txpool/bundlepool/bundlepool.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index 33d420b143..8076c663bb 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -375,7 +375,8 @@ func (p *BundlePool) reset(newHead *types.Header) { (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) - } else if len(bundle.Txs) == 0 || txSet.Contains(bundle.Txs[0].Hash()) { + } else if len(bundle.Txs) == 0 || (txSet.Contains(bundle.Txs[0].Hash()) && + !containsHash(bundle.DroppingTxHashes, bundle.Txs[0].Hash())) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) } @@ -447,6 +448,15 @@ func numSlots(bundle *types.Bundle) uint64 { return (bundle.Size() + bundleSlotSize - 1) / bundleSlotSize } +func containsHash(arr []common.Hash, match common.Hash) bool { + for _, elem := range arr { + if elem == match { + return true + } + } + return false +} + // ===================================================================================================================== type BundleHeap []*types.Bundle From e034bc5d16797a08166461b30592dc7dc991e03f Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Tue, 24 Dec 2024 16:38:18 +0800 Subject: [PATCH 05/18] feat: add log for test --- core/state/statedb.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/state/statedb.go b/core/state/statedb.go index 69b7385a3e..77eccb30f8 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -916,6 +916,10 @@ func (s *StateDB) RevertToSnapshot(revid int) { return s.validRevisions[i].id >= revid }) if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid { + log.Info("idx ", idx) + log.Info("validRevisions length ", len(s.validRevisions)) + log.Info("validRevisions[idx].id ", s.validRevisions[idx].id) + log.Info("revid ", revid) panic(fmt.Errorf("revision id %v cannot be reverted", revid)) } snapshot := s.validRevisions[idx].journalIndex From a7f753020c2b9ed7aa94d65ddbf86a1f4c962a04 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Tue, 24 Dec 2024 16:55:48 +0800 Subject: [PATCH 06/18] fix: fix dump revert issue --- core/state/statedb.go | 4 ---- miner/worker_builder.go | 2 -- 2 files changed, 6 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 77eccb30f8..69b7385a3e 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -916,10 +916,6 @@ func (s *StateDB) RevertToSnapshot(revid int) { return s.validRevisions[i].id >= revid }) if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid { - log.Info("idx ", idx) - log.Info("validRevisions length ", len(s.validRevisions)) - log.Info("validRevisions[idx].id ", s.validRevisions[idx].id) - log.Info("revid ", revid) panic(fmt.Errorf("revision id %v cannot be reverted", revid)) } snapshot := s.validRevisions[idx].journalIndex diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 182d91a7d5..fb57a132a4 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -404,8 +404,6 @@ func (w *worker) simulateBundle( // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) - state.RevertToSnapshot(snap) - gasPool.SetGas(gp) bundle.Txs = bundle.Txs.Remove(i) txsLen = len(bundle.Txs) i-- From a8a1accac735e61e619420181e8fc87801b619c7 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Wed, 25 Dec 2024 15:20:51 +0800 Subject: [PATCH 07/18] feat: refine bundle code --- core/txpool/bundlepool/bundlepool.go | 31 ++++++++++++++++++++-------- core/types/bundle.go | 1 + miner/worker_builder.go | 19 +++++++---------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index 8076c663bb..edcba637fe 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -361,6 +361,10 @@ func (p *BundlePool) reset(newHead *types.Header) { p.mu.Lock() defer p.mu.Unlock() + if len(p.bundles) == 0 { + return + } + // Prune outdated bundles and invalid bundles block := p.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64()) txSet := mapset.NewSet[common.Hash]() @@ -370,17 +374,26 @@ func (p *BundlePool) reset(newHead *types.Header) { txSet.Add(tx.Hash()) } } + var wg sync.WaitGroup for hash, bundle := range p.bundles { - if (bundle.MaxTimestamp != 0 && newHead.Time > bundle.MaxTimestamp) || - (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { - p.slots -= numSlots(p.bundles[hash]) - delete(p.bundles, hash) - } else if len(bundle.Txs) == 0 || (txSet.Contains(bundle.Txs[0].Hash()) && - !containsHash(bundle.DroppingTxHashes, bundle.Txs[0].Hash())) { - p.slots -= numSlots(p.bundles[hash]) - delete(p.bundles, hash) - } + wg.Add(1) + go func(hash common.Hash, bundle *types.Bundle) { + if (bundle.MaxTimestamp != 0 && newHead.Time > bundle.MaxTimestamp) || + (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { + p.slots -= numSlots(p.bundles[hash]) + delete(p.bundles, hash) + } else { + for _, tx := range bundle.Txs { + if txSet.Contains(tx.Hash()) && !containsHash(bundle.DroppingTxHashes, tx.Hash()) { + p.slots -= numSlots(p.bundles[hash]) + delete(p.bundles, hash) + break + } + } + } + }(hash, bundle) } + wg.Wait() bundleGauge.Update(int64(len(p.bundles))) slotsGauge.Update(int64(p.slots)) } diff --git a/core/types/bundle.go b/core/types/bundle.go index 255ff1b49f..513a2bbf49 100644 --- a/core/types/bundle.go +++ b/core/types/bundle.go @@ -43,6 +43,7 @@ type Bundle struct { type SimulatedBundle struct { OriginalBundle *Bundle + SucceedTxs Transactions BundleGasFees *big.Int BundleGasPrice *big.Int diff --git a/miner/worker_builder.go b/miner/worker_builder.go index fb57a132a4..495bfda3fc 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -331,9 +331,9 @@ func (w *worker) mergeBundles( log.Info("included bundle", "gasUsed", simulatedBundle.BundleGasUsed, "gasPrice", simulatedBundle.BundleGasPrice, - "txcount", len(simulatedBundle.OriginalBundle.Txs)) + "txcount", len(simulatedBundle.SucceedTxs)) - includedTxs = append(includedTxs, bundle.OriginalBundle.Txs...) + includedTxs = append(includedTxs, simulatedBundle.SucceedTxs...) mergedBundle.BundleGasFees.Add(mergedBundle.BundleGasFees, simulatedBundle.BundleGasFees) mergedBundle.BundleGasUsed += simulatedBundle.BundleGasUsed @@ -366,9 +366,8 @@ func (w *worker) simulateBundle( bundleGasFees = new(big.Int) ) - txsLen := len(bundle.Txs) - for i := 0; i < txsLen; i++ { - tx := bundle.Txs[i] + succeedTxs := types.Transactions{} + for i, tx := range bundle.Txs { state.SetTxContext(tx.Hash(), i+currentTxCount) snap := state.Snapshot() @@ -382,9 +381,6 @@ func (w *worker) simulateBundle( log.Warn("drop tx in bundle", "hash", tx.Hash().String()) state.RevertToSnapshot(snap) gasPool.SetGas(gp) - bundle.Txs = bundle.Txs.Remove(i) - txsLen = len(bundle.Txs) - i-- continue } @@ -404,9 +400,6 @@ func (w *worker) simulateBundle( // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) - bundle.Txs = bundle.Txs.Remove(i) - txsLen = len(bundle.Txs) - i-- continue } err = errNonRevertingTxInBundleFailed @@ -433,10 +426,11 @@ func (w *worker) simulateBundle( txGasFees := new(big.Int).Mul(txGasUsed, effectiveTip) bundleGasFees.Add(bundleGasFees, txGasFees) } + succeedTxs = append(succeedTxs, tx) } // prune bundle when all txs are dropped - if len(bundle.Txs) == 0 { + if len(succeedTxs) == 0 { log.Warn("prune bundle", "hash", bundle.Hash().String(), "err", "empty bundle") w.eth.TxPool().PruneBundle(bundle.Hash()) return nil, errors.New("empty bundle") @@ -462,6 +456,7 @@ func (w *worker) simulateBundle( return &types.SimulatedBundle{ OriginalBundle: bundle, + SucceedTxs: succeedTxs, BundleGasFees: bundleGasFees, BundleGasPrice: bundleGasPrice, BundleGasUsed: bundleGasUsed, From 20adb95df8321802797e210b4ddedab4c3c39df6 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Wed, 25 Dec 2024 15:51:18 +0800 Subject: [PATCH 08/18] feat: remove unused code --- core/types/transaction.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index d9567b0d37..d7860b57bd 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -632,12 +632,6 @@ func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) { } } -func (s Transactions) Remove(idx int) Transactions { - copy(s[idx:], s[idx+1:]) - s[len(s)-1] = nil - return s[:len(s)-1] -} - // TxDifference returns a new set which is the difference between a and b. func TxDifference(a, b Transactions) Transactions { keep := make(Transactions, 0, len(a)) From bc0cd438691734fed192fa95e22bbc694ac7c1d3 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Wed, 25 Dec 2024 16:10:47 +0800 Subject: [PATCH 09/18] fix: fix concurrent issue --- core/txpool/bundlepool/bundlepool.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index edcba637fe..a94982bb18 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -378,6 +378,7 @@ func (p *BundlePool) reset(newHead *types.Header) { for hash, bundle := range p.bundles { wg.Add(1) go func(hash common.Hash, bundle *types.Bundle) { + defer wg.Done() if (bundle.MaxTimestamp != 0 && newHead.Time > bundle.MaxTimestamp) || (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { p.slots -= numSlots(p.bundles[hash]) From 9a3cc41e9c228763e427cf4d9a84cc3ccbb64e9e Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Thu, 26 Dec 2024 10:23:17 +0800 Subject: [PATCH 10/18] fix: fix setTxContext index --- miner/worker_builder.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 495bfda3fc..9bb3516fb9 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -367,8 +367,9 @@ func (w *worker) simulateBundle( ) succeedTxs := types.Transactions{} - for i, tx := range bundle.Txs { - state.SetTxContext(tx.Hash(), i+currentTxCount) + succeedTxCount := 0 + for _, tx := range bundle.Txs { + state.SetTxContext(tx.Hash(), succeedTxCount+currentTxCount) snap := state.Snapshot() gp := gasPool.Gas() @@ -427,6 +428,7 @@ func (w *worker) simulateBundle( bundleGasFees.Add(bundleGasFees, txGasFees) } succeedTxs = append(succeedTxs, tx) + succeedTxCount++ } // prune bundle when all txs are dropped From 5d9367827be0deb25c68ae67db831bc86e5fbc2a Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Thu, 26 Dec 2024 13:50:05 +0800 Subject: [PATCH 11/18] fix: remove concurrent exec --- core/txpool/bundlepool/bundlepool.go | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index a94982bb18..f0b53da3ae 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -374,27 +374,21 @@ func (p *BundlePool) reset(newHead *types.Header) { txSet.Add(tx.Hash()) } } - var wg sync.WaitGroup for hash, bundle := range p.bundles { - wg.Add(1) - go func(hash common.Hash, bundle *types.Bundle) { - defer wg.Done() - if (bundle.MaxTimestamp != 0 && newHead.Time > bundle.MaxTimestamp) || - (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { - p.slots -= numSlots(p.bundles[hash]) - delete(p.bundles, hash) - } else { - for _, tx := range bundle.Txs { - if txSet.Contains(tx.Hash()) && !containsHash(bundle.DroppingTxHashes, tx.Hash()) { - p.slots -= numSlots(p.bundles[hash]) - delete(p.bundles, hash) - break - } + if (bundle.MaxTimestamp != 0 && newHead.Time > bundle.MaxTimestamp) || + (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { + p.slots -= numSlots(p.bundles[hash]) + delete(p.bundles, hash) + } else { + for _, tx := range bundle.Txs { + if txSet.Contains(tx.Hash()) && !containsHash(bundle.DroppingTxHashes, tx.Hash()) { + p.slots -= numSlots(p.bundles[hash]) + delete(p.bundles, hash) + break } } - }(hash, bundle) + } } - wg.Wait() bundleGauge.Update(int64(len(p.bundles))) slotsGauge.Update(int64(p.slots)) } From f1e1585a20e39553287075f3a810df2929ed8482 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Thu, 26 Dec 2024 14:23:56 +0800 Subject: [PATCH 12/18] fix: status failed, not revert anymore, reset gaspool --- miner/worker_builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 9bb3516fb9..2a42139a92 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -401,6 +401,7 @@ func (w *worker) simulateBundle( // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) + gasPool.SetGas(gp) continue } err = errNonRevertingTxInBundleFailed From a661ba7e7549d0cd227107443b8fca7454a9fcc2 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Thu, 26 Dec 2024 15:13:18 +0800 Subject: [PATCH 13/18] feat: refine code --- core/txpool/bundlepool/bundlepool.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index f0b53da3ae..d3c888efc9 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -362,6 +362,8 @@ func (p *BundlePool) reset(newHead *types.Header) { defer p.mu.Unlock() if len(p.bundles) == 0 { + bundleGauge.Update(int64(len(p.bundles))) + slotsGauge.Update(int64(p.slots)) return } From 3fdd4249a3fbb1c6b6c1b0dc32102bad3db7a34d Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Fri, 27 Dec 2024 10:20:33 +0800 Subject: [PATCH 14/18] fix: test --- miner/worker_builder.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 2a42139a92..86eb58992e 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -402,6 +402,8 @@ func (w *worker) simulateBundle( if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) gasPool.SetGas(gp) + succeedTxs = append(succeedTxs, tx) + succeedTxCount++ continue } err = errNonRevertingTxInBundleFailed From d4c6fefa76e01a852fdc13d2ee0120e5fa5d163e Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Fri, 27 Dec 2024 11:15:15 +0800 Subject: [PATCH 15/18] fix: fix handle status --- miner/worker_builder.go | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 86eb58992e..371b16d645 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -399,22 +399,18 @@ func (w *worker) simulateBundle( if receipt.Status == types.ReceiptStatusFailed && !containsHash(bundle.RevertingTxHashes, receipt.TxHash) { // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool - if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { - log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) - gasPool.SetGas(gp) - succeedTxs = append(succeedTxs, tx) - succeedTxCount++ - continue - } - err = errNonRevertingTxInBundleFailed - log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) + if !containsHash(bundle.DroppingTxHashes, receipt.TxHash) { + err = errNonRevertingTxInBundleFailed + log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) - if prune { - w.eth.TxPool().PruneBundle(bundle.Hash()) - log.Warn("prune bundle", "hash", bundle.Hash().String()) - } + if prune { + w.eth.TxPool().PruneBundle(bundle.Hash()) + log.Warn("prune bundle", "hash", bundle.Hash().String()) + } - return nil, err + return nil, err + } + log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) } if !w.eth.TxPool().Has(tx.Hash()) { bundleGasUsed += receipt.GasUsed From 41fb2c1824215dfbddf0e0ad6d678c4598bf84cf Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Tue, 31 Dec 2024 10:34:03 +0800 Subject: [PATCH 16/18] fix: fix handle status --- miner/worker_builder.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 371b16d645..2a42139a92 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -399,18 +399,20 @@ func (w *worker) simulateBundle( if receipt.Status == types.ReceiptStatusFailed && !containsHash(bundle.RevertingTxHashes, receipt.TxHash) { // for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool - if !containsHash(bundle.DroppingTxHashes, receipt.TxHash) { - err = errNonRevertingTxInBundleFailed - log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) - - if prune { - w.eth.TxPool().PruneBundle(bundle.Hash()) - log.Warn("prune bundle", "hash", bundle.Hash().String()) - } + if containsHash(bundle.DroppingTxHashes, receipt.TxHash) { + log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) + gasPool.SetGas(gp) + continue + } + err = errNonRevertingTxInBundleFailed + log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err) - return nil, err + if prune { + w.eth.TxPool().PruneBundle(bundle.Hash()) + log.Warn("prune bundle", "hash", bundle.Hash().String()) } - log.Warn("drop tx in bundle", "hash", receipt.TxHash.String()) + + return nil, err } if !w.eth.TxPool().Has(tx.Hash()) { bundleGasUsed += receipt.GasUsed From 6c4bf3227b952c9c9f3a47fda1fb0c96cbd97313 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Mon, 6 Jan 2025 17:15:49 +0800 Subject: [PATCH 17/18] fix: fix bundle memory leak --- core/txpool/bundlepool/bundlepool.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index d3c888efc9..f92c083cf6 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -376,20 +376,23 @@ func (p *BundlePool) reset(newHead *types.Header) { txSet.Add(tx.Hash()) } } + p.bundleHeap = make(BundleHeap, 0) for hash, bundle := range p.bundles { if (bundle.MaxTimestamp != 0 && newHead.Time > bundle.MaxTimestamp) || (bundle.MaxBlockNumber != 0 && newHead.Number.Cmp(new(big.Int).SetUint64(bundle.MaxBlockNumber)) > 0) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) + continue } else { for _, tx := range bundle.Txs { if txSet.Contains(tx.Hash()) && !containsHash(bundle.DroppingTxHashes, tx.Hash()) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) - break + continue } } } + p.bundleHeap.Push(bundle) } bundleGauge.Update(int64(len(p.bundles))) slotsGauge.Update(int64(p.slots)) From 97311c9eed8ae42d84a5dce45f54a3f53f43f1a1 Mon Sep 17 00:00:00 2001 From: hongdexiang <1090664234@qq.com> Date: Mon, 6 Jan 2025 22:48:19 +0800 Subject: [PATCH 18/18] fix: fix bundle memory leak --- core/txpool/bundlepool/bundlepool.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index f92c083cf6..0bbaee7536 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -388,11 +388,13 @@ func (p *BundlePool) reset(newHead *types.Header) { if txSet.Contains(tx.Hash()) && !containsHash(bundle.DroppingTxHashes, tx.Hash()) { p.slots -= numSlots(p.bundles[hash]) delete(p.bundles, hash) - continue + break } } } - p.bundleHeap.Push(bundle) + if p.bundles[hash] != nil { + p.bundleHeap.Push(bundle) + } } bundleGauge.Update(int64(len(p.bundles))) slotsGauge.Update(int64(p.slots))