{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}

module Cardano.Chain.Byron.API.Mempool (
  ApplyMempoolPayloadErr (..),
  applyMempoolPayload,
  mempoolPayloadRecoverBytes,
  mempoolPayloadReencode,
)
where

import qualified Cardano.Chain.Block as CC
import Cardano.Chain.Byron.API.Common
import qualified Cardano.Chain.Delegation as Delegation
import qualified Cardano.Chain.Delegation.Validation.Interface as D.Iface
import qualified Cardano.Chain.Delegation.Validation.Scheduling as D.Sched
import qualified Cardano.Chain.Genesis as Gen
import qualified Cardano.Chain.MempoolPayload as CC
import qualified Cardano.Chain.Slotting as CC
import qualified Cardano.Chain.UTxO as Utxo
import qualified Cardano.Chain.Update as Update
import qualified Cardano.Chain.Update.Validation.Interface as U.Iface
import qualified Cardano.Chain.ValidationMode as CC
import Cardano.Crypto.ProtocolMagic
import Cardano.Ledger.Binary
import Cardano.Prelude hiding (cborError)
import qualified Codec.CBOR.Write as CBOR
import qualified Data.Set as Set

{-------------------------------------------------------------------------------
  Apply any kind of transactions
-------------------------------------------------------------------------------}

-- | Errors that arise from applying an arbitrary mempool payload
--
-- Although @cardano-legder@ defines 'MempoolPayload', it does not define a
-- corresponding error type. We could 'ChainValidationError', but it's too
-- large, which is problematic because we actually sent encoded versions of
-- these errors across the wire.
data ApplyMempoolPayloadErr
  = MempoolTxErr Utxo.UTxOValidationError
  | MempoolDlgErr D.Sched.Error
  | MempoolUpdateProposalErr U.Iface.Error
  | MempoolUpdateVoteErr U.Iface.Error
  deriving (ApplyMempoolPayloadErr -> ApplyMempoolPayloadErr -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ApplyMempoolPayloadErr -> ApplyMempoolPayloadErr -> Bool
$c/= :: ApplyMempoolPayloadErr -> ApplyMempoolPayloadErr -> Bool
== :: ApplyMempoolPayloadErr -> ApplyMempoolPayloadErr -> Bool
$c== :: ApplyMempoolPayloadErr -> ApplyMempoolPayloadErr -> Bool
Eq, Int -> ApplyMempoolPayloadErr -> ShowS
[ApplyMempoolPayloadErr] -> ShowS
ApplyMempoolPayloadErr -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ApplyMempoolPayloadErr] -> ShowS
$cshowList :: [ApplyMempoolPayloadErr] -> ShowS
show :: ApplyMempoolPayloadErr -> String
$cshow :: ApplyMempoolPayloadErr -> String
showsPrec :: Int -> ApplyMempoolPayloadErr -> ShowS
$cshowsPrec :: Int -> ApplyMempoolPayloadErr -> ShowS
Show)

instance ToCBOR ApplyMempoolPayloadErr where
  toCBOR :: ApplyMempoolPayloadErr -> Encoding
toCBOR = forall a. EncCBOR a => a -> Encoding
toByronCBOR

instance FromCBOR ApplyMempoolPayloadErr where
  fromCBOR :: forall s. Decoder s ApplyMempoolPayloadErr
fromCBOR = forall a s. DecCBOR a => Decoder s a
fromByronCBOR

instance EncCBOR ApplyMempoolPayloadErr where
  encCBOR :: ApplyMempoolPayloadErr -> Encoding
encCBOR (MempoolTxErr UTxOValidationError
err) =
    Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
0 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR UTxOValidationError
err
  encCBOR (MempoolDlgErr Error
err) =
    Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
1 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Error
err
  encCBOR (MempoolUpdateProposalErr Error
err) =
    Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
2 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Error
err
  encCBOR (MempoolUpdateVoteErr Error
err) =
    Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
3 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Error
err

instance DecCBOR ApplyMempoolPayloadErr where
  decCBOR :: forall s. Decoder s ApplyMempoolPayloadErr
decCBOR = do
    forall s. Text -> Int -> Decoder s ()
enforceSize Text
"ApplyMempoolPayloadErr" Int
2
    forall s. Decoder s Word8
decodeWord8 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Word8
0 -> UTxOValidationError -> ApplyMempoolPayloadErr
MempoolTxErr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR
      Word8
1 -> Error -> ApplyMempoolPayloadErr
MempoolDlgErr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR
      Word8
2 -> Error -> ApplyMempoolPayloadErr
MempoolUpdateProposalErr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR
      Word8
3 -> Error -> ApplyMempoolPayloadErr
MempoolUpdateVoteErr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR
      Word8
tag -> forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError forall a b. (a -> b) -> a -> b
$ Text -> Word8 -> DecoderError
DecoderErrorUnknownTag Text
"ApplyMempoolPayloadErr" Word8
tag

applyMempoolPayload ::
  MonadError ApplyMempoolPayloadErr m =>
  CC.ValidationMode ->
  Gen.Config ->
  CC.SlotNumber ->
  CC.AMempoolPayload ByteString ->
  CC.ChainValidationState ->
  m CC.ChainValidationState
applyMempoolPayload :: forall (m :: * -> *).
MonadError ApplyMempoolPayloadErr m =>
ValidationMode
-> Config
-> SlotNumber
-> AMempoolPayload ByteString
-> ChainValidationState
-> m ChainValidationState
applyMempoolPayload ValidationMode
validationMode Config
cfg SlotNumber
currentSlot AMempoolPayload ByteString
payload =
  case AMempoolPayload ByteString
payload of
    CC.MempoolTx ATxAux ByteString
tx ->
      (forall e' (m :: * -> *) e a.
MonadError e' m =>
Either e a -> (e -> e') -> m a
`wrapError` UTxOValidationError -> ApplyMempoolPayloadErr
MempoolTxErr)
        forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (m :: * -> *).
MonadError UTxOValidationError m =>
ValidationMode
-> Config
-> [ATxAux ByteString]
-> ChainValidationState
-> m ChainValidationState
applyTxAux ValidationMode
validationMode Config
cfg [ATxAux ByteString
tx]
    CC.MempoolDlg ACertificate ByteString
cert ->
      (forall e' (m :: * -> *) e a.
MonadError e' m =>
Either e a -> (e -> e') -> m a
`wrapError` Error -> ApplyMempoolPayloadErr
MempoolDlgErr)
        forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (m :: * -> *).
MonadError Error m =>
Config
-> SlotNumber
-> [ACertificate ByteString]
-> ChainValidationState
-> m ChainValidationState
applyCertificate Config
cfg SlotNumber
currentSlot [ACertificate ByteString
cert]
    CC.MempoolUpdateProposal AProposal ByteString
proposal ->
      (forall e' (m :: * -> *) e a.
MonadError e' m =>
Either e a -> (e -> e') -> m a
`wrapError` Error -> ApplyMempoolPayloadErr
MempoolUpdateProposalErr)
        forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (m :: * -> *).
MonadError Error m =>
Config
-> SlotNumber
-> AProposal ByteString
-> ChainValidationState
-> m ChainValidationState
applyUpdateProposal Config
cfg SlotNumber
currentSlot AProposal ByteString
proposal
    CC.MempoolUpdateVote AVote ByteString
vote ->
      (forall e' (m :: * -> *) e a.
MonadError e' m =>
Either e a -> (e -> e') -> m a
`wrapError` Error -> ApplyMempoolPayloadErr
MempoolUpdateVoteErr)
        forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (m :: * -> *).
MonadError Error m =>
Config
-> SlotNumber
-> AVote ByteString
-> ChainValidationState
-> m ChainValidationState
applyUpdateVote Config
cfg SlotNumber
currentSlot AVote ByteString
vote

-- | The encoding of the mempool payload (without a 'AMempoolPayload' envelope)
mempoolPayloadRecoverBytes :: CC.AMempoolPayload ByteString -> ByteString
mempoolPayloadRecoverBytes :: AMempoolPayload ByteString -> ByteString
mempoolPayloadRecoverBytes = AMempoolPayload ByteString -> ByteString
go
  where
    go :: CC.AMempoolPayload ByteString -> ByteString
    go :: AMempoolPayload ByteString -> ByteString
go (CC.MempoolTx ATxAux ByteString
payload) = forall t. Decoded t => t -> ByteString
recoverBytes ATxAux ByteString
payload
    go (CC.MempoolDlg ACertificate ByteString
payload) = forall t. Decoded t => t -> ByteString
recoverBytes ACertificate ByteString
payload
    go (CC.MempoolUpdateProposal AProposal ByteString
payload) = forall t. Decoded t => t -> ByteString
recoverBytes AProposal ByteString
payload
    go (CC.MempoolUpdateVote AVote ByteString
payload) = forall t. Decoded t => t -> ByteString
recoverBytes AVote ByteString
payload

-- | Re-encode the mempool payload (without any envelope)
mempoolPayloadReencode :: CC.AMempoolPayload a -> ByteString
mempoolPayloadReencode :: forall a. AMempoolPayload a -> ByteString
mempoolPayloadReencode = forall a. AMempoolPayload a -> ByteString
go
  where
    go :: forall a. CC.AMempoolPayload a -> ByteString
    go :: forall a. AMempoolPayload a -> ByteString
go (CC.MempoolTx ATxAux a
payload) = forall (f :: * -> *) a.
(Functor f, EncCBOR (f ())) =>
f a -> ByteString
reencode ATxAux a
payload
    go (CC.MempoolDlg ACertificate a
payload) = forall (f :: * -> *) a.
(Functor f, EncCBOR (f ())) =>
f a -> ByteString
reencode ACertificate a
payload
    go (CC.MempoolUpdateProposal AProposal a
payload) = forall (f :: * -> *) a.
(Functor f, EncCBOR (f ())) =>
f a -> ByteString
reencode AProposal a
payload
    go (CC.MempoolUpdateVote AVote a
payload) = forall (f :: * -> *) a.
(Functor f, EncCBOR (f ())) =>
f a -> ByteString
reencode AVote a
payload

    reencode :: (Functor f, EncCBOR (f ())) => f a -> ByteString
    reencode :: forall (f :: * -> *) a.
(Functor f, EncCBOR (f ())) =>
f a -> ByteString
reencode = Encoding -> ByteString
CBOR.toStrictByteString forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Version -> Encoding -> Encoding
toPlainEncoding Version
byronProtVer forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a. EncCBOR a => a -> Encoding
encCBOR forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (f :: * -> *) a. Functor f => f a -> f ()
void

{-------------------------------------------------------------------------------
  Applying transactions
-------------------------------------------------------------------------------}

mkUtxoEnvironment ::
  Gen.Config ->
  CC.ChainValidationState ->
  Utxo.Environment
mkUtxoEnvironment :: Config -> ChainValidationState -> Environment
mkUtxoEnvironment Config
cfg ChainValidationState
cvs =
  Utxo.Environment
    { protocolMagic :: AProtocolMagic ByteString
Utxo.protocolMagic = AProtocolMagic ByteString
protocolMagic
    , protocolParameters :: ProtocolParameters
Utxo.protocolParameters = State -> ProtocolParameters
U.Iface.adoptedProtocolParameters State
updateState
    , utxoConfiguration :: UTxOConfiguration
Utxo.utxoConfiguration = Config -> UTxOConfiguration
Gen.configUTxOConfiguration Config
cfg
    }
  where
    protocolMagic :: AProtocolMagic ByteString
protocolMagic = ProtocolMagic -> AProtocolMagic ByteString
reAnnotateMagic (Config -> ProtocolMagic
Gen.configProtocolMagic Config
cfg)
    updateState :: State
updateState = ChainValidationState -> State
CC.cvsUpdateState ChainValidationState
cvs

mkDelegationEnvironment ::
  Gen.Config ->
  CC.SlotNumber ->
  D.Iface.Environment
mkDelegationEnvironment :: Config -> SlotNumber -> Environment
mkDelegationEnvironment Config
cfg SlotNumber
currentSlot =
  D.Iface.Environment
    { protocolMagic :: Annotated ProtocolMagicId ByteString
D.Iface.protocolMagic = forall a. AProtocolMagic a -> Annotated ProtocolMagicId a
getAProtocolMagicId AProtocolMagic ByteString
protocolMagic
    , allowedDelegators :: Set KeyHash
D.Iface.allowedDelegators = Config -> Set KeyHash
allowedDelegators Config
cfg
    , k :: BlockCount
D.Iface.k = BlockCount
k
    , -- The @currentSlot@/@currentEpoch@ for checking a delegation certificate
      -- must be that of the block in which the delegation certificate is/will
      -- be included.
      currentEpoch :: EpochNumber
D.Iface.currentEpoch = EpochNumber
currentEpoch
    , currentSlot :: SlotNumber
D.Iface.currentSlot = SlotNumber
currentSlot
    }
  where
    k :: BlockCount
k = Config -> BlockCount
Gen.configK Config
cfg
    protocolMagic :: AProtocolMagic ByteString
protocolMagic = ProtocolMagic -> AProtocolMagic ByteString
reAnnotateMagic (Config -> ProtocolMagic
Gen.configProtocolMagic Config
cfg)
    currentEpoch :: EpochNumber
currentEpoch = EpochSlots -> SlotNumber -> EpochNumber
CC.slotNumberEpoch (Config -> EpochSlots
Gen.configEpochSlots Config
cfg) SlotNumber
currentSlot

mkUpdateEnvironment ::
  Gen.Config ->
  CC.SlotNumber ->
  Delegation.Map ->
  U.Iface.Environment
mkUpdateEnvironment :: Config -> SlotNumber -> Map -> Environment
mkUpdateEnvironment Config
cfg SlotNumber
currentSlot Map
delegationMap =
  U.Iface.Environment
    { protocolMagic :: Annotated ProtocolMagicId ByteString
U.Iface.protocolMagic = forall a. AProtocolMagic a -> Annotated ProtocolMagicId a
getAProtocolMagicId AProtocolMagic ByteString
protocolMagic
    , k :: BlockCount
U.Iface.k = BlockCount
k
    , currentSlot :: SlotNumber
U.Iface.currentSlot = SlotNumber
currentSlot
    , numGenKeys :: Word8
U.Iface.numGenKeys = Word8
numGenKeys
    , delegationMap :: Map
U.Iface.delegationMap = Map
delegationMap
    }
  where
    k :: BlockCount
k = Config -> BlockCount
Gen.configK Config
cfg
    protocolMagic :: AProtocolMagic ByteString
protocolMagic = ProtocolMagic -> AProtocolMagic ByteString
reAnnotateMagic (Config -> ProtocolMagic
Gen.configProtocolMagic Config
cfg)
    numGenKeys :: Word8
numGenKeys = Int -> Word8
toNumGenKeys forall a b. (a -> b) -> a -> b
$ forall a. Set a -> Int
Set.size (Config -> Set KeyHash
allowedDelegators Config
cfg)

    toNumGenKeys :: Int -> Word8
    toNumGenKeys :: Int -> Word8
toNumGenKeys Int
n
      | Int
n forall a. Ord a => a -> a -> Bool
> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Word8) =
          forall a. HasCallStack => Text -> a
panic Text
"toNumGenKeys: Too many genesis keys"
      | Bool
otherwise = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n

applyTxAux ::
  MonadError Utxo.UTxOValidationError m =>
  CC.ValidationMode ->
  Gen.Config ->
  [Utxo.ATxAux ByteString] ->
  CC.ChainValidationState ->
  m CC.ChainValidationState
applyTxAux :: forall (m :: * -> *).
MonadError UTxOValidationError m =>
ValidationMode
-> Config
-> [ATxAux ByteString]
-> ChainValidationState
-> m ChainValidationState
applyTxAux ValidationMode
validationMode Config
cfg [ATxAux ByteString]
txs ChainValidationState
cvs =
  forall a b c. (a -> b -> c) -> b -> a -> c
flip forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ValidationMode
validationMode
    forall a b. (a -> b) -> a -> b
$ (UTxO -> ChainValidationState -> ChainValidationState
`setUTxO` ChainValidationState
cvs)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
(MonadError UTxOValidationError m, MonadReader ValidationMode m) =>
Environment -> UTxO -> [ATxAux ByteString] -> m UTxO
Utxo.updateUTxO Environment
utxoEnv UTxO
utxo [ATxAux ByteString]
txs
  where
    utxoEnv :: Environment
utxoEnv = Config -> ChainValidationState -> Environment
mkUtxoEnvironment Config
cfg ChainValidationState
cvs
    utxo :: UTxO
utxo = ChainValidationState -> UTxO
CC.cvsUtxo ChainValidationState
cvs

applyCertificate ::
  MonadError D.Sched.Error m =>
  Gen.Config ->
  CC.SlotNumber ->
  [Delegation.ACertificate ByteString] ->
  CC.ChainValidationState ->
  m CC.ChainValidationState
applyCertificate :: forall (m :: * -> *).
MonadError Error m =>
Config
-> SlotNumber
-> [ACertificate ByteString]
-> ChainValidationState
-> m ChainValidationState
applyCertificate Config
cfg SlotNumber
currentSlot [ACertificate ByteString]
certs ChainValidationState
cvs =
  (State -> ChainValidationState -> ChainValidationState
`setDelegationState` ChainValidationState
cvs)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadError Error m =>
Environment -> State -> [ACertificate ByteString] -> m State
D.Iface.updateDelegation Environment
dlgEnv State
dlgState [ACertificate ByteString]
certs
  where
    dlgEnv :: Environment
dlgEnv = Config -> SlotNumber -> Environment
mkDelegationEnvironment Config
cfg SlotNumber
currentSlot
    dlgState :: State
dlgState = ChainValidationState -> State
CC.cvsDelegationState ChainValidationState
cvs

applyUpdateProposal ::
  MonadError U.Iface.Error m =>
  Gen.Config ->
  CC.SlotNumber ->
  Update.AProposal ByteString ->
  CC.ChainValidationState ->
  m CC.ChainValidationState
applyUpdateProposal :: forall (m :: * -> *).
MonadError Error m =>
Config
-> SlotNumber
-> AProposal ByteString
-> ChainValidationState
-> m ChainValidationState
applyUpdateProposal Config
cfg SlotNumber
currentSlot AProposal ByteString
proposal ChainValidationState
cvs =
  (State -> ChainValidationState -> ChainValidationState
`setUpdateState` ChainValidationState
cvs)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadError Error m =>
Environment -> State -> AProposal ByteString -> m State
U.Iface.registerProposal Environment
updateEnv State
updateState AProposal ByteString
proposal
  where
    updateEnv :: Environment
updateEnv = Config -> SlotNumber -> Map -> Environment
mkUpdateEnvironment Config
cfg SlotNumber
currentSlot (ChainValidationState -> Map
getDelegationMap ChainValidationState
cvs)
    updateState :: State
updateState = ChainValidationState -> State
CC.cvsUpdateState ChainValidationState
cvs

applyUpdateVote ::
  MonadError U.Iface.Error m =>
  Gen.Config ->
  CC.SlotNumber ->
  Update.AVote ByteString ->
  CC.ChainValidationState ->
  m CC.ChainValidationState
applyUpdateVote :: forall (m :: * -> *).
MonadError Error m =>
Config
-> SlotNumber
-> AVote ByteString
-> ChainValidationState
-> m ChainValidationState
applyUpdateVote Config
cfg SlotNumber
currentSlot AVote ByteString
vote ChainValidationState
cvs =
  (State -> ChainValidationState -> ChainValidationState
`setUpdateState` ChainValidationState
cvs)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadError Error m =>
Environment -> State -> AVote ByteString -> m State
U.Iface.registerVote Environment
updateEnv State
updateState AVote ByteString
vote
  where
    updateEnv :: Environment
updateEnv = Config -> SlotNumber -> Map -> Environment
mkUpdateEnvironment Config
cfg SlotNumber
currentSlot (ChainValidationState -> Map
getDelegationMap ChainValidationState
cvs)
    updateState :: State
updateState = ChainValidationState -> State
CC.cvsUpdateState ChainValidationState
cvs

{-------------------------------------------------------------------------------
  Update parts of the chain state
-------------------------------------------------------------------------------}

setUTxO ::
  Utxo.UTxO ->
  CC.ChainValidationState ->
  CC.ChainValidationState
setUTxO :: UTxO -> ChainValidationState -> ChainValidationState
setUTxO UTxO
newUTxO ChainValidationState
cvs = ChainValidationState
cvs {$sel:cvsUtxo:ChainValidationState :: UTxO
CC.cvsUtxo = UTxO
newUTxO}

setDelegationState ::
  D.Iface.State ->
  CC.ChainValidationState ->
  CC.ChainValidationState
setDelegationState :: State -> ChainValidationState -> ChainValidationState
setDelegationState State
newDlg ChainValidationState
cvs = ChainValidationState
cvs {$sel:cvsDelegationState:ChainValidationState :: State
CC.cvsDelegationState = State
newDlg}

setUpdateState ::
  U.Iface.State ->
  CC.ChainValidationState ->
  CC.ChainValidationState
setUpdateState :: State -> ChainValidationState -> ChainValidationState
setUpdateState State
newUpdate ChainValidationState
cvs = ChainValidationState
cvs {$sel:cvsUpdateState:ChainValidationState :: State
CC.cvsUpdateState = State
newUpdate}