@@ -17,6 +17,7 @@ module Cardano.Tools.DBAnalyser.Analysis (
1717 , AnalysisName (.. )
1818 , AnalysisResult (.. )
1919 , AnalysisStartFrom (.. )
20+ , LedgerApplicationMode (.. )
2021 , Limit (.. )
2122 , NumberOfBlocks (.. )
2223 , SStartFrom (.. )
@@ -51,7 +52,7 @@ import Ouroboros.Consensus.HeaderValidation (HasAnnTip (..),
5152 HeaderState (.. ), headerStatePoint , tickHeaderState ,
5253 validateHeader )
5354import Ouroboros.Consensus.Ledger.Abstract (LedgerCfg , LedgerConfig ,
54- applyBlockLedgerResult , applyChainTick ,
55+ applyBlockLedgerResult , applyChainTick , tickThenApply ,
5556 tickThenApplyLedgerResult , tickThenReapply )
5657import Ouroboros.Consensus.Ledger.Basics (LedgerResult (.. ),
5758 LedgerState , getTipSlot )
@@ -72,6 +73,7 @@ import Ouroboros.Consensus.Storage.LedgerDB (DiskSnapshot (..),
7273 writeSnapshot )
7374import Ouroboros.Consensus.Storage.Serialisation (SizeInBytes ,
7475 encodeDisk )
76+ import Ouroboros.Consensus.Util ((..:) )
7577import qualified Ouroboros.Consensus.Util.IOLike as IOLike
7678import Ouroboros.Consensus.Util.ResourceRegistry
7779import System.FS.API (SomeHasFS (.. ))
@@ -88,7 +90,7 @@ data AnalysisName =
8890 | ShowBlockTxsSize
8991 | ShowEBBs
9092 | OnlyValidation
91- | StoreLedgerStateAt SlotNo
93+ | StoreLedgerStateAt SlotNo LedgerApplicationMode
9294 | CountBlocks
9395 | CheckNoThunksEvery Word64
9496 | TraceLedgerProcessing
@@ -109,6 +111,11 @@ data AnalysisResult =
109111newtype NumberOfBlocks = NumberOfBlocks { unNumberOfBlocks :: Word64 }
110112 deriving (Eq , Show , Num , Read )
111113
114+ -- | Whether to apply blocks to a ledger state via /reapplication/ (eg skipping
115+ -- signature checks/Plutus scripts) or full /application/ (much slower).
116+ data LedgerApplicationMode = LedgerReapply | LedgerApply
117+ deriving (Eq , Show )
118+
112119runAnalysis ::
113120 forall blk .
114121 ( HasAnalysis blk
@@ -133,7 +140,7 @@ runAnalysis analysisName = case go analysisName of
133140 go ShowBlockTxsSize = mkAnalysis $ showBlockTxsSize
134141 go ShowEBBs = mkAnalysis $ showEBBs
135142 go OnlyValidation = mkAnalysis @ StartFromPoint $ \ _ -> pure Nothing
136- go (StoreLedgerStateAt slotNo) = mkAnalysis $ storeLedgerStateAt slotNo
143+ go (StoreLedgerStateAt slotNo lgrAppMode ) = mkAnalysis $ storeLedgerStateAt slotNo lgrAppMode
137144 go CountBlocks = mkAnalysis $ countBlocks
138145 go (CheckNoThunksEvery nBks) = mkAnalysis $ checkNoThunksEvery nBks
139146 go TraceLedgerProcessing = mkAnalysis $ traceLedgerProcessing
@@ -221,6 +228,8 @@ data TraceEvent blk =
221228 -- ^ triggered once during StoreLedgerStateAt analysis,
222229 -- when snapshot was created in slot proceeding the
223230 -- requested one
231+ | LedgerErrorEvent (Point blk ) (ExtValidationError blk )
232+ -- ^ triggered when applying a block with the given point failed
224233 | BlockTxSizeEvent SlotNo Int SizeInBytes
225234 -- ^ triggered for all blocks during ShowBlockTxsSize analysis,
226235 -- it holds:
@@ -241,7 +250,7 @@ data TraceEvent blk =
241250 -- * total time spent in the mutator when calling 'Mempool.getSnapshotFor'
242251 -- * total time spent in gc when calling 'Mempool.getSnapshotFor'
243252
244- instance HasAnalysis blk => Show (TraceEvent blk ) where
253+ instance ( HasAnalysis blk , LedgerSupportsProtocol blk ) => Show (TraceEvent blk ) where
245254 show (StartedEvent analysisName) = " Started " <> (show analysisName)
246255 show DoneEvent = " Done"
247256 show (BlockSlotEvent bn sn h) = intercalate " \t " $ [
@@ -273,6 +282,8 @@ instance HasAnalysis blk => Show (TraceEvent blk) where
273282 show (SnapshotWarningEvent requested actual) =
274283 " Snapshot was created at " <> show actual <> " " <>
275284 " because there was no block forged at requested " <> show requested
285+ show (LedgerErrorEvent pt err) =
286+ " Applying block at " <> show pt <> " failed: " <> show err
276287 show (BlockTxSizeEvent slot numBlocks txsSize) = intercalate " \t " [
277288 show slot
278289 , " Num txs in block = " <> show numBlocks
@@ -398,21 +409,33 @@ storeLedgerStateAt ::
398409 , HasAnalysis blk
399410 , LedgerSupportsProtocol blk
400411 )
401- => SlotNo -> Analysis blk StartFromLedgerState
402- storeLedgerStateAt slotNo (AnalysisEnv { db, registry, startFrom, cfg, limit, ledgerDbFS, tracer }) = do
412+ => SlotNo
413+ -> LedgerApplicationMode
414+ -> Analysis blk StartFromLedgerState
415+ storeLedgerStateAt slotNo ledgerAppMode env = do
403416 void $ processAllUntil db registry GetBlock startFrom limit initLedger process
404417 pure Nothing
405418 where
419+ AnalysisEnv { db, registry, startFrom, cfg, limit, ledgerDbFS, tracer } = env
406420 FromLedgerState initLedger = startFrom
407421
408422 process :: ExtLedgerState blk -> blk -> IO (NextStep , ExtLedgerState blk )
409423 process oldLedger blk = do
410424 let ledgerCfg = ExtLedgerCfg cfg
411- newLedger = tickThenReapply ledgerCfg blk oldLedger
412- when (blockSlot blk >= slotNo) $ storeLedgerState blk newLedger
413- when (blockSlot blk > slotNo) $ issueWarning blk
414- when ((unBlockNo $ blockNo blk) `mod` 1000 == 0 ) $ reportProgress blk
415- return (continue blk, newLedger)
425+ case runExcept $ tickThenXApply ledgerCfg blk oldLedger of
426+ Right newLedger -> do
427+ when (blockSlot blk >= slotNo) $ storeLedgerState newLedger
428+ when (blockSlot blk > slotNo) $ issueWarning blk
429+ when ((unBlockNo $ blockNo blk) `mod` 1000 == 0 ) $ reportProgress blk
430+ return (continue blk, newLedger)
431+ Left err -> do
432+ traceWith tracer $ LedgerErrorEvent (blockPoint blk) err
433+ storeLedgerState oldLedger
434+ pure (Stop , oldLedger)
435+
436+ tickThenXApply = case ledgerAppMode of
437+ LedgerReapply -> pure ..: tickThenReapply
438+ LedgerApply -> tickThenApply
416439
417440 continue :: blk -> NextStep
418441 continue blk
@@ -424,16 +447,15 @@ storeLedgerStateAt slotNo (AnalysisEnv { db, registry, startFrom, cfg, limit, le
424447 reportProgress blk = let event = BlockSlotEvent (blockNo blk) (blockSlot blk) (blockHash blk)
425448 in traceWith tracer event
426449
427- storeLedgerState ::
428- blk
429- -> ExtLedgerState blk
430- -> IO ()
431- storeLedgerState blk ledgerState = do
432- let snapshot = DiskSnapshot
433- (unSlotNo $ blockSlot blk)
434- (Just $ " db-analyser" )
435- writeSnapshot ledgerDbFS encLedger snapshot ledgerState
436- traceWith tracer $ SnapshotStoredEvent (blockSlot blk)
450+ storeLedgerState :: ExtLedgerState blk -> IO ()
451+ storeLedgerState ledgerState = case pointSlot pt of
452+ NotOrigin slot -> do
453+ let snapshot = DiskSnapshot (unSlotNo slot) (Just " db-analyser" )
454+ writeSnapshot ledgerDbFS encLedger snapshot ledgerState
455+ traceWith tracer $ SnapshotStoredEvent slot
456+ Origin -> pure ()
457+ where
458+ pt = headerStatePoint $ headerState ledgerState
437459
438460 encLedger :: ExtLedgerState blk -> Encoding
439461 encLedger =
0 commit comments