From 6cc18b8f1bdca69964de911a2e2f4bbab343b9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Tue, 16 Jul 2024 15:53:46 +0300 Subject: [PATCH 1/4] feat: defer txpool reorg until worker fetches txns for the next block --- core/tx_pool.go | 22 +++++++++++++++++++++- miner/scroll_worker.go | 7 +++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/core/tx_pool.go b/core/tx_pool.go index 22ca123244d2..031a88311fc2 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -268,6 +268,7 @@ type TxPool struct { queueTxEventCh chan *types.Transaction reorgDoneCh chan chan struct{} reorgShutdownCh chan struct{} // requests shutdown of scheduleReorgLoop + reorgPauseCh chan bool // requests to pause scheduleReorgLoop wg sync.WaitGroup // tracks loop, scheduleReorgLoop initDoneCh chan struct{} // is closed once the pool is initialized (for tests) @@ -300,6 +301,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block queueTxEventCh: make(chan *types.Transaction), reorgDoneCh: make(chan chan struct{}), reorgShutdownCh: make(chan struct{}), + reorgPauseCh: make(chan bool), initDoneCh: make(chan struct{}), gasPrice: new(big.Int).SetUint64(config.PriceLimit), } @@ -1160,13 +1162,14 @@ func (pool *TxPool) scheduleReorgLoop() { curDone chan struct{} // non-nil while runReorg is active nextDone = make(chan struct{}) launchNextRun bool + reorgsPaused bool reset *txpoolResetRequest dirtyAccounts *accountSet queuedEvents = make(map[common.Address]*txSortedMap) ) for { // Launch next background reorg if needed - if curDone == nil && launchNextRun { + if curDone == nil && launchNextRun && !reorgsPaused { // Run the background reorg and announcements go pool.runReorg(nextDone, reset, dirtyAccounts, queuedEvents) @@ -1218,6 +1221,7 @@ func (pool *TxPool) scheduleReorgLoop() { } close(nextDone) return + case reorgsPaused = <-pool.reorgPauseCh: } } } @@ -1677,6 +1681,22 @@ func (pool *TxPool) demoteUnexecutables() { } } +// PauseReorgs stops any new reorg jobs to be started but doesn't interrupt any existing ones that are in flight +func (pool *TxPool) PauseReorgs() { + select { + case pool.reorgPauseCh <- true: + case <-pool.reorgShutdownCh: + } +} + +// ResumeReorgs allows new reorg jobs to be started +func (pool *TxPool) ResumeReorgs() { + select { + case pool.reorgPauseCh <- false: + case <-pool.reorgShutdownCh: + } +} + // addressByHeartbeat is an account address tagged with its last activity timestamp. type addressByHeartbeat struct { address common.Address diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 036718062a3b..730f25cc149a 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -453,6 +453,9 @@ func (w *worker) startNewPipeline(timestamp int64) { } collectL2Timer.UpdateSince(tidyPendingStart) + // Allow txpool to be reorged as we build current block + w.eth.TxPool().ResumeReorgs() + var nextL1MsgIndex uint64 if dbIndex := rawdb.ReadFirstQueueIndexNotInL2Block(w.chain.Database(), parent.Hash()); dbIndex != nil { nextL1MsgIndex = *dbIndex @@ -718,6 +721,10 @@ func (w *worker) commit(res *pipeline.Result) error { "accRows", res.Rows, ) + // A new block event will trigger a reorg in the txpool, pause reorgs to defer this until we fetch txns for next block. + // We may end up trying to process txns that we already included in the previous block, but they will all fail the nonce check + w.eth.TxPool().PauseReorgs() + rawdb.WriteBlockRowConsumption(w.eth.ChainDb(), blockHash, res.Rows) // Commit block and state to database. _, err = w.chain.WriteBlockWithState(block, res.FinalBlock.Receipts, res.FinalBlock.CoalescedLogs, res.FinalBlock.State, true) From d011a4bf461fc36f9dacc2fb09d12d6c8699e6e4 Mon Sep 17 00:00:00 2001 From: omerfirmak Date: Thu, 18 Jul 2024 11:40:12 +0000 Subject: [PATCH 2/4] =?UTF-8?q?chore:=20auto=20version=20bump=E2=80=89[bot?= =?UTF-8?q?]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index efa00cbde508..6abfdd8406ee 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 5 // Minor version component of the current release - VersionPatch = 13 // Patch version component of the current release + VersionPatch = 14 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) From 5fbff58afaa9181fdf5d90fde43f72b4ec64428f Mon Sep 17 00:00:00 2001 From: omerfirmak Date: Thu, 25 Jul 2024 14:37:03 +0000 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20auto=20version=20bump=E2=80=89[bot?= =?UTF-8?q?]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 1bce01730853..8779b0e64665 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 5 // Minor version component of the current release - VersionPatch = 17 // Patch version component of the current release + VersionPatch = 18 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) From 0bc92c9facf3605cf5832a5f9ae0e31af79bf86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Thu, 25 Jul 2024 17:38:40 +0300 Subject: [PATCH 4/4] Update tx_pool.go --- core/tx_pool.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/tx_pool.go b/core/tx_pool.go index 031a88311fc2..37fd6a7c1c93 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1682,6 +1682,7 @@ func (pool *TxPool) demoteUnexecutables() { } // PauseReorgs stops any new reorg jobs to be started but doesn't interrupt any existing ones that are in flight +// Keep in mind this function might block, although it is not expected to block for any significant amount of time func (pool *TxPool) PauseReorgs() { select { case pool.reorgPauseCh <- true: @@ -1689,7 +1690,8 @@ func (pool *TxPool) PauseReorgs() { } } -// ResumeReorgs allows new reorg jobs to be started +// ResumeReorgs allows new reorg jobs to be started. +// Keep in mind this function might block, although it is not expected to block for any significant amount of time func (pool *TxPool) ResumeReorgs() { select { case pool.reorgPauseCh <- false: