@@ -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