@@ -23,6 +23,7 @@ import qualified Cardano.Binary as Serialize
2323import Cardano.DbSync.Config
2424import Cardano.DbSync.Config.Cardano
2525import Cardano.DbSync.Config.Types
26+ import qualified Cardano.DbSync.Era.Cardano.Util as Cardano
2627import Cardano.DbSync.Types
2728import Cardano.DbSync.Util
2829
@@ -38,20 +39,20 @@ import Control.Monad.Extra (firstJustM)
3839
3940import qualified Data.ByteString.Char8 as BS
4041import qualified Data.ByteString.Lazy.Char8 as LBS
42+ import qualified Data.ByteString.Short as BSS
4143import Data.Either (partitionEithers )
4244import qualified Data.List as List
4345
44- import Ouroboros.Consensus.Block (CodecConfig , WithOrigin (.. ))
45- import Ouroboros.Consensus.Cardano.Block
46- (LedgerState (LedgerStateByron , LedgerStateShelley ))
46+ import Ouroboros.Consensus.Block (CodecConfig , WithOrigin (.. ), blockHash , blockPrevHash )
47+ import Ouroboros.Consensus.Cardano.Block (LedgerState (.. ))
4748import Ouroboros.Consensus.Cardano.CanHardFork ()
4849import Ouroboros.Consensus.Config (TopLevelConfig (.. ), configCodec , configLedger )
4950import qualified Ouroboros.Consensus.HardFork.Combinator as Consensus
5051import Ouroboros.Consensus.HardFork.Combinator.Basics (LedgerState (.. ))
5152import Ouroboros.Consensus.HardFork.Combinator.State (epochInfoLedger )
5253import qualified Ouroboros.Consensus.HardFork.Combinator.State as Consensus
5354import qualified Ouroboros.Consensus.HeaderValidation as Consensus
54- import Ouroboros.Consensus.Ledger.Abstract (ledgerTipSlot , tickThenApply , tickThenReapply )
55+ import Ouroboros.Consensus.Ledger.Abstract (ledgerTipHash , ledgerTipSlot , tickThenReapply )
5556import Ouroboros.Consensus.Ledger.Extended (ExtLedgerCfg (.. ), ExtLedgerState (.. ),
5657 decodeExtLedgerState , encodeExtLedgerState )
5758import qualified Ouroboros.Consensus.Node.ProtocolInfo as Consensus
@@ -61,8 +62,6 @@ import qualified Ouroboros.Consensus.Shelley.Protocol as Consensus
6162import Ouroboros.Consensus.Storage.Serialisation (DecodeDisk (.. ), EncodeDisk (.. ))
6263import qualified Ouroboros.Consensus.TypeFamilyWrappers as Consensus
6364
64-
65-
6665import qualified Shelley.Spec.Ledger.API.Protocol as Shelley
6766import qualified Shelley.Spec.Ledger.BaseTypes as Shelley
6867import qualified Shelley.Spec.Ledger.EpochBoundary as Shelley
@@ -137,12 +136,9 @@ applyBlock (LedgerStateVar stateVar) blk =
137136 where
138137 applyBlk :: ExtLedgerCfg CardanoBlock -> CardanoBlock -> ExtLedgerState CardanoBlock -> ExtLedgerState CardanoBlock
139138 applyBlk cfg block lsb =
140- -- Set to False to get better error messages from Consensus (but slower block application).
141- if True
142- then tickThenReapply cfg block lsb
143- else case runExcept $ tickThenApply cfg block lsb of
144- Left err -> panic $ textShow err
145- Right result -> result
139+ case tickThenReapplyCheckHash cfg block lsb of
140+ Left err -> panic err
141+ Right result -> result
146142
147143saveLedgerState :: LedgerStateDir -> LedgerStateVar -> CardanoLedgerState -> SyncState -> IO ()
148144saveLedgerState lsd@ (LedgerStateDir stateDir) (LedgerStateVar stateVar) ledger synced = do
@@ -234,7 +230,6 @@ loadState stateDir ledger slotNo = do
234230 Left (_ :: IOException ) -> pure Nothing
235231 Right bs -> pure $ decode bs
236232
237-
238233 codecConfig :: CodecConfig CardanoBlock
239234 codecConfig = configCodec (clsConfig ledger)
240235
@@ -297,7 +292,7 @@ ledgerEpochUpdate els mRewards =
297292 , euRewards = fromMaybe Shelley. emptyRewardUpdate mRewards
298293
299294 -- Use '_pstakeSet' here instead of '_pstateMark' because the stake addresses for the
300- -- later may not have been added to the database yet. That means that whne these values
295+ -- later may not have been added to the database yet. That means that when these values
301296 -- are added to the database, the epoch number where they become active is the current
302297 -- epoch plus one.
303298 , euStakeDistribution = Shelley. _stake . Shelley. _pstakeSet . Shelley. esSnapshots
@@ -326,3 +321,21 @@ extractEpochNonce extLedgerState =
326321 $ Consensus. tpraosStateChainDepState (Consensus. unwrapChainDepState chainDepStateShelley)
327322 Consensus. TS {} ->
328323 Nothing
324+
325+ -- Like 'Consensus.tickThenReapply' but also checks that the previous hash from the block matches
326+ -- the head hash of the ledger state.
327+ tickThenReapplyCheckHash
328+ :: ExtLedgerCfg CardanoBlock -> CardanoBlock -> ExtLedgerState CardanoBlock
329+ -> Either Text (ExtLedgerState CardanoBlock )
330+ tickThenReapplyCheckHash cfg block lsb =
331+ if blockPrevHash block == ledgerTipHash (ledgerState lsb)
332+ then Right $ tickThenReapply cfg block lsb
333+ else Left $ mconcat
334+ [ " Ledger state hash mismatch. Ledger head is slot "
335+ , textShow (unSlotNo $ fromWithOrigin (SlotNo 0 ) (ledgerTipSlot $ ledgerState lsb))
336+ , " hash " , renderByteArray (Cardano. unChainHash (ledgerTipHash $ ledgerState lsb))
337+ , " but block previous hash is "
338+ , renderByteArray (Cardano. unChainHash $ blockPrevHash block)
339+ , " and block current hash is "
340+ , renderByteArray (BSS. fromShort . Consensus. getOneEraHash $ blockHash block), " ."
341+ ]
0 commit comments