Skip to content

Commit 61b87bf

Browse files
committed
feature(cardano-db-sync): Create a new HasNewEpochState class
This class can be used to get/update the underlying extended ledger state
1 parent 35b5cd7 commit 61b87bf

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

cardano-db-sync/src/Cardano/DbSync/Ledger/Types.hs

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{-# LANGUAGE RankNTypes #-}
66
{-# LANGUAGE ScopedTypeVariables #-}
77
{-# LANGUAGE TypeFamilies #-}
8+
{-# LANGUAGE TypeOperators #-}
89
{-# LANGUAGE NoImplicitPrelude #-}
910

1011
module Cardano.DbSync.Ledger.Types where
@@ -28,6 +29,7 @@ import Cardano.Ledger.Coin (Coin)
2829
import Cardano.Ledger.Conway.Governance
2930
import Cardano.Ledger.Credential (Credential (..))
3031
import Cardano.Ledger.Keys (KeyRole (..))
32+
import Cardano.Ledger.Shelley.LedgerState (NewEpochState ())
3133
import Cardano.Prelude hiding (atomically)
3234
import Cardano.Slotting.Slot (
3335
EpochNo (..),
@@ -39,13 +41,17 @@ import Control.Concurrent.Class.MonadSTM.Strict (
3941
)
4042
import Control.Concurrent.STM.TBQueue (TBQueue)
4143
import qualified Data.Map.Strict as Map
44+
import Data.SOP.Strict
4245
import qualified Data.Set as Set
4346
import qualified Data.Strict.Maybe as Strict
47+
import Lens.Micro (Traversal')
4448
import Ouroboros.Consensus.BlockchainTime.WallClock.Types (SystemStart (..))
45-
import Ouroboros.Consensus.Cardano.Block (StandardConway, StandardCrypto)
49+
import Ouroboros.Consensus.Cardano.Block hiding (CardanoBlock, CardanoLedgerState)
50+
import Ouroboros.Consensus.HardFork.Combinator.Basics (LedgerState (..))
4651
import Ouroboros.Consensus.Ledger.Abstract (getTipSlot)
4752
import Ouroboros.Consensus.Ledger.Extended (ExtLedgerState (..))
4853
import qualified Ouroboros.Consensus.Node.ProtocolInfo as Consensus
54+
import Ouroboros.Consensus.Shelley.Ledger (LedgerState (..), ShelleyBlock)
4955
import Ouroboros.Network.AnchoredSeq (Anchorable (..), AnchoredSeq (..))
5056
import Prelude (fail, id)
5157

@@ -190,3 +196,61 @@ instance Anchorable (WithOrigin SlotNo) CardanoLedgerState CardanoLedgerState wh
190196
getAnchorMeasure _ = getTipSlot . clsState
191197

192198
data SnapshotPoint = OnDisk LedgerStateFile | InMemory CardanoPoint
199+
200+
-- | Per-era pure getters and setters on @NewEpochState@. Note this is a bit of an abuse
201+
-- of the cardano-ledger/ouroboros-consensus public APIs, because ledger state is not
202+
-- designed to be updated this way. We are only replaying the chain, so this should be
203+
-- safe.
204+
class HasNewEpochState era where
205+
getNewEpochState :: ExtLedgerState CardanoBlock -> Maybe (NewEpochState era)
206+
207+
applyNewEpochState ::
208+
NewEpochState era ->
209+
ExtLedgerState CardanoBlock ->
210+
ExtLedgerState CardanoBlock
211+
212+
instance HasNewEpochState StandardShelley where
213+
getNewEpochState st = case ledgerState st of
214+
LedgerStateShelley shelley -> Just (shelleyLedgerState shelley)
215+
_ -> Nothing
216+
217+
applyNewEpochState st =
218+
hApplyExtLedgerState $
219+
fn (applyNewEpochState' st) :* fn id :* fn id :* fn id :* fn id :* fn id :* Nil
220+
221+
instance HasNewEpochState StandardConway where
222+
getNewEpochState st = case ledgerState st of
223+
LedgerStateConway shelley -> Just (shelleyLedgerState shelley)
224+
_ -> Nothing
225+
226+
applyNewEpochState st =
227+
hApplyExtLedgerState $
228+
fn id :* fn id :* fn id :* fn id :* fn id :* fn (applyNewEpochState' st) :* Nil
229+
230+
hApplyExtLedgerState ::
231+
NP (LedgerState -.-> LedgerState) (CardanoShelleyEras StandardCrypto) ->
232+
ExtLedgerState CardanoBlock ->
233+
ExtLedgerState CardanoBlock
234+
hApplyExtLedgerState f ledger =
235+
case ledgerState ledger of
236+
HardForkLedgerState hfState ->
237+
let newHfState = hap (fn id :* f) hfState
238+
in updateLedgerState $ HardForkLedgerState newHfState
239+
where
240+
updateLedgerState st = ledger {ledgerState = st}
241+
242+
applyNewEpochState' ::
243+
NewEpochState era ->
244+
LedgerState (ShelleyBlock proto era) ->
245+
LedgerState (ShelleyBlock proto era)
246+
applyNewEpochState' newEpochState' ledger =
247+
ledger {shelleyLedgerState = newEpochState'}
248+
249+
-- | A @Traversal@ that targets the @NewEpochState@ from the extended ledger state
250+
newEpochStateT ::
251+
HasNewEpochState era =>
252+
Traversal' (ExtLedgerState CardanoBlock) (NewEpochState era)
253+
newEpochStateT f ledger =
254+
case getNewEpochState ledger of
255+
Just newEpochState' -> flip applyNewEpochState ledger <$> f newEpochState'
256+
Nothing -> pure ledger

cardano-db-sync/src/Cardano/DbSync/Types.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{-# LANGUAGE DataKinds #-}
22
{-# LANGUAGE DeriveGeneric #-}
3+
{-# LANGUAGE FlexibleInstances #-}
34
{-# LANGUAGE LambdaCase #-}
5+
{-# LANGUAGE TypeFamilies #-}
46

57
module Cardano.DbSync.Types (
68
BlockDetails (..),
@@ -53,6 +55,7 @@ import qualified Cardano.Ledger.Credential as Ledger
5355
import Cardano.Ledger.Crypto (StandardCrypto)
5456
import qualified Cardano.Ledger.Hashes as Ledger
5557
import Cardano.Ledger.Keys
58+
5659
import Cardano.Prelude hiding (Meta, show)
5760
import Cardano.Slotting.Slot (EpochNo (..), EpochSize (..), SlotNo (..))
5861
import qualified Data.Text as Text

0 commit comments

Comments
 (0)