Skip to content

Commit 2369c86

Browse files
committed
Ensure mempool always closes stale forkers
1 parent 91c8a1b commit 2369c86

File tree

2 files changed

+61
-23
lines changed

2 files changed

+61
-23
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
For top level release notes, leave all the headers commented out.
6+
-->
7+
8+
### Patch
9+
10+
- Ensure Mempool always deallocates stale forkers, or rather that it does not
11+
try to allocate a new one unless completely necessary and closes the old one
12+
in the process.
13+
14+
<!--
15+
### Non-Breaking
16+
17+
- A bullet item for the Non-Breaking category.
18+
19+
-->
20+
<!--
21+
### Breaking
22+
23+
- A bullet item for the Breaking category.
24+
25+
-->

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Mempool/Update.hs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -405,31 +405,44 @@ implSyncWithLedger mpEnv =
405405
-- For that reason, we read the state again here in the same STM
406406
-- transaction in which we acquire the internal state of the mempool.
407407
--
408-
-- This implies that the watcher might be triggered again with the same
409-
-- state from the point of view of the mempool, if after the watcher saw a
410-
-- new state and this read for re-syncing, the state has changed. The
411-
-- watcher will see it once again and trigger re-validation again. Just
412-
-- for performance reasons, we will avoid re-validating the mempool if the
413-
-- state didn't change.
408+
-- The following interleaving could happen:
409+
--
410+
-- - [ChainSel thread] We adopt a new block B at the tip of our selection.
411+
--
412+
-- - [Mempool sync thread] The Watcher wakes up, seeing that the tip has
413+
-- changed to B, records it as the fingerprint, and invokes
414+
-- implSyncWithLedger, but doesn't reach withTMVarAnd here.
415+
--
416+
-- - [ChainSel thread] Adopt a new block C.
417+
--
418+
-- - [Mempool thread] Execute withTMVarAnd here, obtaining the ledger
419+
-- state for C and syncing the mempool with C.
420+
--
421+
-- - [Mempool thread] The Watcher wakes up again, seeing that the tip has
422+
-- changed from B to C, and invokes implSyncWithLedger. This time,
423+
-- nothing needs to be done, resulting in TraceMempoolSyncNotNeeded.
424+
--
425+
-- Just for performance reasons, we will avoid re-validating the mempool
426+
-- if the state didn't change.
414427
withTMVarAnd istate (const $ getCurrentLedgerState ldgrInterface registry) $
415428
\is (MempoolLedgerDBView ls meFrk) -> do
416-
eFrk <- meFrk
417-
case eFrk of
418-
-- This case should happen only if the tip has moved again, this time
419-
-- to a separate fork, since the background thread saw a change in the
420-
-- tip, which should happen very rarely
421-
Left{} -> do
422-
traceWith trcr TraceMempoolTipMovedBetweenSTMBlocks
423-
pure (Nothing, is)
424-
Right frk -> do
425-
let (slot, ls') = tickLedgerState cfg $ ForgeInUnknownSlot ls
426-
if pointHash (isTip is) == castHash (getTipHash ls) && isSlotNo is == slot
427-
then do
428-
-- The tip didn't change, put the same state.
429-
traceWith trcr $ TraceMempoolSyncNotNeeded (isTip is)
430-
pure (Just (snapshotFromIS is), is)
431-
else do
432-
-- The tip changed, we have to revalidate
429+
let (slot, ls') = tickLedgerState cfg $ ForgeInUnknownSlot ls
430+
if pointHash (isTip is) == castHash (getTipHash ls) && isSlotNo is == slot
431+
then do
432+
-- The tip didn't change, put the same state.
433+
traceWith trcr $ TraceMempoolSyncNotNeeded (isTip is)
434+
pure (Just (snapshotFromIS is), is)
435+
else do
436+
-- The tip changed, we have to revalidate
437+
eFrk <- meFrk
438+
case eFrk of
439+
-- This case should happen only if the tip has moved again, this time
440+
-- to a separate fork, since the background thread saw a change in the
441+
-- tip, which should happen very rarely
442+
Left{} -> do
443+
traceWith trcr TraceMempoolTipMovedBetweenSTMBlocks
444+
pure (Nothing, is)
445+
Right frk -> do
433446
modifyMVar_
434447
forkerMVar
435448
( \oldFrk -> do

0 commit comments

Comments
 (0)