@@ -10,14 +10,13 @@ module Ouroboros.Consensus.Mempool.Update (
10
10
11
11
import Cardano.Slotting.Slot
12
12
import Control.Concurrent.Class.MonadMVar (withMVar )
13
+ import Control.Monad (void )
13
14
import Control.Monad.Except (runExcept )
14
15
import Control.Tracer
15
16
import qualified Data.List.NonEmpty as NE
16
17
import Data.Maybe (fromMaybe )
17
18
import qualified Data.Measure as Measure
18
19
import qualified Data.Set as Set
19
- import Ouroboros.Consensus.Block.Abstract (castHash , castPoint ,
20
- pointHash )
21
20
import Ouroboros.Consensus.HeaderValidation
22
21
import Ouroboros.Consensus.Ledger.Abstract
23
22
import Ouroboros.Consensus.Ledger.SupportsMempool
@@ -27,8 +26,9 @@ import Ouroboros.Consensus.Mempool.Capacity
27
26
import Ouroboros.Consensus.Mempool.Impl.Common
28
27
import Ouroboros.Consensus.Mempool.TxSeq (TxTicket (.. ))
29
28
import qualified Ouroboros.Consensus.Mempool.TxSeq as TxSeq
30
- import Ouroboros.Consensus.Util (whenJust )
29
+ import Ouroboros.Consensus.Util (whenJust , withTMVarAnd )
31
30
import Ouroboros.Consensus.Util.IOLike hiding (withMVar )
31
+ import Ouroboros.Network.Block
32
32
33
33
{- ------------------------------------------------------------------------------
34
34
Add transactions
@@ -158,32 +158,37 @@ doAddTx mpEnv wti tx =
158
158
159
159
doAddTx' s = do
160
160
traceWith trcr $ TraceMempoolAttemptingAdd tx
161
- is <- atomically $ do
162
- i <- takeTMVar istate
161
+ res <- withTMVarAnd istate (\ is ->
163
162
case s of
164
163
Nothing -> pure ()
165
- Just s' -> check $ isMempoolSize i /= s'
166
- pure i
167
- mTbs <- getLedgerTablesAtFor ldgrInterface (isTip is) [tx]
168
- case mTbs of
169
- Just tbs -> do
170
- traceWith trcr $ TraceMempoolLedgerFound (isTip is)
171
- case pureTryAddTx cfg wti tx is tbs of
172
- NotEnoughSpaceLeft -> do
173
- atomically $ putTMVar istate is
174
- doAddTx' (Just $ isMempoolSize is)
175
- Processed outcome@ (TransactionProcessingResult is' _ _) -> do
176
- atomically $ putTMVar istate $ fromMaybe is is'
177
- pure outcome
178
- Nothing -> do
179
- traceWith trcr $ TraceMempoolLedgerNotFound (isTip is)
180
- -- We couldn't retrieve the values because the state is no longer on
181
- -- the db. We need to resync.
182
- atomically $ putTMVar istate is
183
- (_, mTrace) <- implSyncWithLedger mpEnv
184
- whenJust mTrace (traceWith trcr)
164
+ Just s' -> check $ isMempoolSize is /= s')
165
+ $ \ is () -> do
166
+ mTbs <- getLedgerTablesAtFor ldgrInterface (isTip is) [tx]
167
+ case mTbs of
168
+ Just tbs -> do
169
+ traceWith trcr $ TraceMempoolLedgerFound (isTip is)
170
+ case pureTryAddTx cfg wti tx is tbs of
171
+ NotEnoughSpaceLeft -> do
172
+ pure (Retry (isMempoolSize is), is)
173
+ Processed outcome@ (TransactionProcessingResult is' _ _) -> do
174
+ pure (OK outcome, fromMaybe is is')
175
+ Nothing -> do
176
+ traceWith trcr $ TraceMempoolLedgerNotFound (isTip is)
177
+ -- We couldn't retrieve the values because the state is no longer on
178
+ -- the db. We need to resync.
179
+ pure (Resync , is)
180
+ case res of
181
+ Retry s' -> doAddTx' (Just s')
182
+ OK outcome -> pure outcome
183
+ Resync -> do
184
+ void $ implSyncWithLedger mpEnv
185
185
doAddTx' s
186
186
187
+ data WithTMVarOutcome retry ok =
188
+ Retry retry
189
+ | OK ok
190
+ | Resync
191
+
187
192
-- | Craft a 'TriedToAddTx' value containing the resulting state if
188
193
-- applicable, the tracing event and the result of adding this transaction. See
189
194
-- the documentation of 'implAddTx' for some more context.
@@ -318,10 +323,8 @@ implRemoveTxs ::
318
323
-> NE. NonEmpty (GenTxId blk )
319
324
-> m ()
320
325
implRemoveTxs mpEnv toRemove = do
321
- (is, ls) <- atomically $ do
322
- is <- takeTMVar istate
323
- ls <- getCurrentLedgerState ldgrInterface
324
- pure (is, ls)
326
+ out <- withTMVarAnd istate (const $ getCurrentLedgerState ldgrInterface)
327
+ $ \ is ls -> do
325
328
let toKeep = filter
326
329
( (`notElem` Set. fromList (NE. toList toRemove))
327
330
. txId
@@ -333,9 +336,7 @@ implRemoveTxs mpEnv toRemove = do
333
336
toKeep' = [ txForgetValidated . TxSeq. txTicketTx $ tx | tx <- toKeep ]
334
337
mTbs <- getLedgerTablesAtFor ldgrInterface (castPoint (getTip ls)) toKeep'
335
338
case mTbs of
336
- Nothing -> do
337
- atomically $ putTMVar istate is
338
- implRemoveTxs mpEnv toRemove
339
+ Nothing -> pure (Resync , is)
339
340
Just tbs -> do
340
341
let (is', t) = pureRemoveTxs
341
342
capacityOverride
@@ -346,8 +347,14 @@ implRemoveTxs mpEnv toRemove = do
346
347
(isLastTicketNo is)
347
348
toKeep
348
349
toRemove
349
- atomically $ putTMVar istate is'
350
350
traceWith trcr t
351
+ pure (OK () , is')
352
+ case out of
353
+ Resync -> do
354
+ void $ implSyncWithLedger mpEnv
355
+ implRemoveTxs mpEnv toRemove
356
+ OK () -> pure ()
357
+ Retry _ -> error " Impossible!"
351
358
where
352
359
MempoolEnv { mpEnvStateVar = istate
353
360
, mpEnvLedger = ldgrInterface
@@ -399,47 +406,43 @@ implSyncWithLedger ::
399
406
, HasTxId (GenTx blk )
400
407
)
401
408
=> MempoolEnv m blk
402
- -> m (MempoolSnapshot blk , Maybe ( TraceEventMempool blk ) )
409
+ -> m (MempoolSnapshot blk )
403
410
implSyncWithLedger mpEnv = do
404
411
traceWith trcr TraceMempoolAttemptingSync
405
- (is, ls) <- atomically $ do
406
- is <- takeTMVar istate
407
- ls <- getCurrentLedgerState ldgrInterface
408
- pure (is, ls)
409
-
410
- let (slot, ls') = tickLedgerState cfg $ ForgeInUnknownSlot ls
411
-
412
- if pointHash (isTip is) == castHash (getTipHash ls) &&
413
- isSlotNo is == slot
414
- then do
415
- -- The tip didn't change, put the same state.
416
- atomically $ putTMVar istate is
417
- traceWith trcr $ TraceMempoolSyncNotNeeded (isTip is) (castPoint $ getTip ls)
418
- pure (snapshotFromIS is, Nothing )
419
- else do
420
- -- We need to revalidate
421
- let pt = castPoint (getTip ls)
422
- txs = [ txForgetValidated . TxSeq. txTicketTx $ tx
423
- | tx <- TxSeq. toList $ isTxs is
424
- ]
425
- mTbs <- getLedgerTablesAtFor ldgrInterface pt txs
426
- case mTbs of
427
- Just tbs -> do
428
- let (is', mTrace) = pureSyncWithLedger
429
- capacityOverride
430
- cfg
431
- slot
432
- ls'
433
- tbs
434
- is
435
- atomically $ putTMVar istate is'
436
- whenJust mTrace (traceWith trcr)
437
- traceWith trcr TraceMempoolSyncDone
438
- return (snapshotFromIS is', mTrace)
439
- Nothing -> do
440
- -- If the point is gone, resync
441
- atomically $ putTMVar istate is
442
- implSyncWithLedger mpEnv
412
+ res <- withTMVarAnd istate (const $ getCurrentLedgerState ldgrInterface) $
413
+ \ is ls -> do
414
+ let (slot, ls') = tickLedgerState cfg $ ForgeInUnknownSlot ls
415
+ if pointHash (isTip is) == castHash (getTipHash ls) && isSlotNo is == slot
416
+ then do
417
+ -- The tip didn't change, put the same state.
418
+ traceWith trcr $ TraceMempoolSyncNotNeeded (isTip is) (castPoint $ getTip ls)
419
+ pure (OK (snapshotFromIS is), is)
420
+ else do
421
+ -- We need to revalidate
422
+ let pt = castPoint (getTip ls)
423
+ txs = [ txForgetValidated . TxSeq. txTicketTx $ tx
424
+ | tx <- TxSeq. toList $ isTxs is
425
+ ]
426
+ mTbs <- getLedgerTablesAtFor ldgrInterface pt txs
427
+ case mTbs of
428
+ Just tbs -> do
429
+ let (is', mTrace) = pureSyncWithLedger
430
+ capacityOverride
431
+ cfg
432
+ slot
433
+ ls'
434
+ tbs
435
+ is
436
+ whenJust mTrace (traceWith trcr)
437
+ traceWith trcr TraceMempoolSyncDone
438
+ pure (OK (snapshotFromIS is'), is')
439
+ Nothing -> do
440
+ -- If the point is gone, resync
441
+ pure (Resync , is)
442
+ case res of
443
+ OK v -> pure v
444
+ Resync -> implSyncWithLedger mpEnv
445
+ Retry _ -> error " Impossible!"
443
446
where
444
447
MempoolEnv { mpEnvStateVar = istate
445
448
, mpEnvLedger = ldgrInterface
0 commit comments