@@ -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) = intercalate " \t " $ [
@@ -272,6 +281,8 @@ instance HasAnalysis blk => Show (TraceEvent blk) where
272281 show (SnapshotWarningEvent requested actual) =
273282 " Snapshot was created at " <> show actual <> " " <>
274283 " because there was no block forged at requested " <> show requested
284+ show (LedgerErrorEvent pt err) =
285+ " Applying block at " <> show pt <> " failed: " <> show err
275286 show (BlockTxSizeEvent slot numBlocks txsSize) = intercalate " \t " [
276287 show slot
277288 , " Num txs in block = " <> show numBlocks
@@ -396,21 +407,33 @@ storeLedgerStateAt ::
396407 , HasAnalysis blk
397408 , LedgerSupportsProtocol blk
398409 )
399- => SlotNo -> Analysis blk StartFromLedgerState
400- storeLedgerStateAt slotNo (AnalysisEnv { db, registry, startFrom, cfg, limit, ledgerDbFS, tracer }) = do
410+ => SlotNo
411+ -> LedgerApplicationMode
412+ -> Analysis blk StartFromLedgerState
413+ storeLedgerStateAt slotNo ledgerAppMode env = do
401414 void $ processAllUntil db registry GetBlock startFrom limit initLedger process
402415 pure Nothing
403416 where
417+ AnalysisEnv { db, registry, startFrom, cfg, limit, ledgerDbFS, tracer } = env
404418 FromLedgerState initLedger = startFrom
405419
406420 process :: ExtLedgerState blk -> blk -> IO (NextStep , ExtLedgerState blk )
407421 process oldLedger blk = do
408422 let ledgerCfg = ExtLedgerCfg cfg
409- newLedger = tickThenReapply ledgerCfg blk oldLedger
410- when (blockSlot blk >= slotNo) $ storeLedgerState blk newLedger
411- when (blockSlot blk > slotNo) $ issueWarning blk
412- when ((unBlockNo $ blockNo blk) `mod` 1000 == 0 ) $ reportProgress blk
413- return (continue blk, newLedger)
423+ case runExcept $ tickThenXApply ledgerCfg blk oldLedger of
424+ Right newLedger -> do
425+ when (blockSlot blk >= slotNo) $ storeLedgerState newLedger
426+ when (blockSlot blk > slotNo) $ issueWarning blk
427+ when ((unBlockNo $ blockNo blk) `mod` 1000 == 0 ) $ reportProgress blk
428+ return (continue blk, newLedger)
429+ Left err -> do
430+ traceWith tracer $ LedgerErrorEvent (blockPoint blk) err
431+ storeLedgerState oldLedger
432+ pure (Stop , oldLedger)
433+
434+ tickThenXApply = case ledgerAppMode of
435+ LedgerReapply -> pure ..: tickThenReapply
436+ LedgerApply -> tickThenApply
414437
415438 continue :: blk -> NextStep
416439 continue blk
@@ -422,16 +445,15 @@ storeLedgerStateAt slotNo (AnalysisEnv { db, registry, startFrom, cfg, limit, le
422445 reportProgress blk = let event = BlockSlotEvent (blockNo blk) (blockSlot blk)
423446 in traceWith tracer event
424447
425- storeLedgerState ::
426- blk
427- -> ExtLedgerState blk
428- -> IO ()
429- storeLedgerState blk ledgerState = do
430- let snapshot = DiskSnapshot
431- (unSlotNo $ blockSlot blk)
432- (Just $ " db-analyser" )
433- writeSnapshot ledgerDbFS encLedger snapshot ledgerState
434- traceWith tracer $ SnapshotStoredEvent (blockSlot blk)
448+ storeLedgerState :: ExtLedgerState blk -> IO ()
449+ storeLedgerState ledgerState = case pointSlot pt of
450+ NotOrigin slot -> do
451+ let snapshot = DiskSnapshot (unSlotNo slot) (Just " db-analyser" )
452+ writeSnapshot ledgerDbFS encLedger snapshot ledgerState
453+ traceWith tracer $ SnapshotStoredEvent slot
454+ Origin -> pure ()
455+ where
456+ pt = headerStatePoint $ headerState ledgerState
435457
436458 encLedger :: ExtLedgerState blk -> Encoding
437459 encLedger =
0 commit comments