From 19ff6ac42956b5dcbecedad55a1c000553a2f298 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 28 Oct 2025 12:51:20 +0100 Subject: [PATCH 1/3] Ensure mempool always closes stale forkers --- ...ier.sagredo_fix_mempool_dangling_forker.md | 25 ++++++++ .../Ouroboros/Consensus/Mempool/Update.hs | 59 +++++++++++-------- 2 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 ouroboros-consensus/changelog.d/20251029_113014_javier.sagredo_fix_mempool_dangling_forker.md diff --git a/ouroboros-consensus/changelog.d/20251029_113014_javier.sagredo_fix_mempool_dangling_forker.md b/ouroboros-consensus/changelog.d/20251029_113014_javier.sagredo_fix_mempool_dangling_forker.md new file mode 100644 index 0000000000..34b35458d7 --- /dev/null +++ b/ouroboros-consensus/changelog.d/20251029_113014_javier.sagredo_fix_mempool_dangling_forker.md @@ -0,0 +1,25 @@ + + +### Patch + +- Ensure Mempool always deallocates stale forkers, or rather that it does not + try to allocate a new one unless completely necessary and closes the old one + in the process. + + + diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Mempool/Update.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Mempool/Update.hs index 3953750861..37f599f251 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Mempool/Update.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Mempool/Update.hs @@ -405,31 +405,44 @@ implSyncWithLedger mpEnv = -- For that reason, we read the state again here in the same STM -- transaction in which we acquire the internal state of the mempool. -- - -- This implies that the watcher might be triggered again with the same - -- state from the point of view of the mempool, if after the watcher saw a - -- new state and this read for re-syncing, the state has changed. The - -- watcher will see it once again and trigger re-validation again. Just - -- for performance reasons, we will avoid re-validating the mempool if the - -- state didn't change. + -- The following interleaving could happen: + -- + -- - [ChainSel thread] We adopt a new block B at the tip of our selection. + -- + -- - [Mempool sync thread] The Watcher wakes up, seeing that the tip has + -- changed to B, records it as the fingerprint, and invokes + -- implSyncWithLedger, but doesn't reach withTMVarAnd here. + -- + -- - [ChainSel thread] Adopt a new block C. + -- + -- - [Mempool thread] Execute withTMVarAnd here, obtaining the ledger + -- state for C and syncing the mempool with C. + -- + -- - [Mempool thread] The Watcher wakes up again, seeing that the tip has + -- changed from B to C, and invokes implSyncWithLedger. This time, + -- nothing needs to be done, resulting in TraceMempoolSyncNotNeeded. + -- + -- Just for performance reasons, we will avoid re-validating the mempool + -- if the state didn't change. withTMVarAnd istate (const $ getCurrentLedgerState ldgrInterface registry) $ \is (MempoolLedgerDBView ls meFrk) -> do - eFrk <- meFrk - case eFrk of - -- This case should happen only if the tip has moved again, this time - -- to a separate fork, since the background thread saw a change in the - -- tip, which should happen very rarely - Left{} -> do - traceWith trcr TraceMempoolTipMovedBetweenSTMBlocks - pure (Nothing, is) - Right frk -> do - let (slot, ls') = tickLedgerState cfg $ ForgeInUnknownSlot ls - if pointHash (isTip is) == castHash (getTipHash ls) && isSlotNo is == slot - then do - -- The tip didn't change, put the same state. - traceWith trcr $ TraceMempoolSyncNotNeeded (isTip is) - pure (Just (snapshotFromIS is), is) - else do - -- The tip changed, we have to revalidate + let (slot, ls') = tickLedgerState cfg $ ForgeInUnknownSlot ls + if pointHash (isTip is) == castHash (getTipHash ls) && isSlotNo is == slot + then do + -- The tip didn't change, put the same state. + traceWith trcr $ TraceMempoolSyncNotNeeded (isTip is) + pure (Just (snapshotFromIS is), is) + else do + -- The tip changed, we have to revalidate + eFrk <- meFrk + case eFrk of + -- This case should happen only if the tip has moved again, this time + -- to a separate fork, since the background thread saw a change in the + -- tip, which should happen very rarely + Left{} -> do + traceWith trcr TraceMempoolTipMovedBetweenSTMBlocks + pure (Nothing, is) + Right frk -> do modifyMVar_ forkerMVar ( \oldFrk -> do From bc5ae327db1fcb52b2d78e1f87c1367f7e8d680c Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 29 Oct 2025 23:16:16 +0100 Subject: [PATCH 2/3] Downgrade optparse-applicative to 0.18 --- .../app/snapshot-converter.hs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ouroboros-consensus-cardano/app/snapshot-converter.hs b/ouroboros-consensus-cardano/app/snapshot-converter.hs index 13edc2c73f..2f17605647 100644 --- a/ouroboros-consensus-cardano/app/snapshot-converter.hs +++ b/ouroboros-consensus-cardano/app/snapshot-converter.hs @@ -103,10 +103,6 @@ programDescription = data InOut = In | Out -inoutForGroup :: InOut -> String -inoutForGroup In = "Input arguments:" -inoutForGroup Out = "Output arguments:" - inoutForHelp :: InOut -> String -> Bool -> String inoutForHelp In s b = mconcat $ @@ -134,14 +130,10 @@ inoutForCommand Out = (++ "-out") parseConfig :: InOut -> Parser Format parseConfig io = ( Mem - <$> parserOptionGroup - (inoutForGroup io) - (parsePath (inoutForCommand io "mem") (inoutForHelp io "snapshot dir" True)) + <$> (parsePath (inoutForCommand io "mem") (inoutForHelp io "snapshot dir" True)) ) <|> ( LMDB - <$> parserOptionGroup - (inoutForGroup io) - (parsePath (inoutForCommand io "lmdb") (inoutForHelp io "snapshot dir" True)) + <$> (parsePath (inoutForCommand io "lmdb") (inoutForHelp io "snapshot dir" True)) ) parsePath :: String -> String -> Parser FilePath From 9d98526ea87cd0c86f65e5fb30ea9b3c352b9e18 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 29 Oct 2025 23:18:22 +0100 Subject: [PATCH 3/3] Add changelog --- ...ier.sagredo_fix_mempool_dangling_forker.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ouroboros-consensus-cardano/changelog.d/20251029_231756_javier.sagredo_fix_mempool_dangling_forker.md diff --git a/ouroboros-consensus-cardano/changelog.d/20251029_231756_javier.sagredo_fix_mempool_dangling_forker.md b/ouroboros-consensus-cardano/changelog.d/20251029_231756_javier.sagredo_fix_mempool_dangling_forker.md new file mode 100644 index 0000000000..3f01cf5660 --- /dev/null +++ b/ouroboros-consensus-cardano/changelog.d/20251029_231756_javier.sagredo_fix_mempool_dangling_forker.md @@ -0,0 +1,23 @@ + + +### Patch + +- Downgrade optparse-applicative to 0.18. + + +