{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Ouroboros.Network.Mock.ProducerState where
import Ouroboros.Network.Block (HasFullHeader, castPoint, genesisPoint)
import Ouroboros.Network.Mock.Chain (Chain, ChainUpdate (..), HasHeader,
HeaderHash, Point (..), blockPoint, pointOnChain)
import Ouroboros.Network.Mock.Chain qualified as Chain
import Control.Exception (assert)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Maybe (fromMaybe)
data ChainProducerState block = ChainProducerState {
forall block. ChainProducerState block -> Chain block
chainState :: Chain block,
forall block. ChainProducerState block -> FollowerStates block
chainFollowers :: FollowerStates block,
forall block. ChainProducerState block -> FollowerId
nextFollowerId :: FollowerId
}
deriving (ChainProducerState block -> ChainProducerState block -> Bool
(ChainProducerState block -> ChainProducerState block -> Bool)
-> (ChainProducerState block -> ChainProducerState block -> Bool)
-> Eq (ChainProducerState block)
forall block.
(StandardHash block, Eq block) =>
ChainProducerState block -> ChainProducerState block -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall block.
(StandardHash block, Eq block) =>
ChainProducerState block -> ChainProducerState block -> Bool
== :: ChainProducerState block -> ChainProducerState block -> Bool
$c/= :: forall block.
(StandardHash block, Eq block) =>
ChainProducerState block -> ChainProducerState block -> Bool
/= :: ChainProducerState block -> ChainProducerState block -> Bool
Eq, FollowerId -> ChainProducerState block -> ShowS
[ChainProducerState block] -> ShowS
ChainProducerState block -> String
(FollowerId -> ChainProducerState block -> ShowS)
-> (ChainProducerState block -> String)
-> ([ChainProducerState block] -> ShowS)
-> Show (ChainProducerState block)
forall block.
(StandardHash block, Show block) =>
FollowerId -> ChainProducerState block -> ShowS
forall block.
(StandardHash block, Show block) =>
[ChainProducerState block] -> ShowS
forall block.
(StandardHash block, Show block) =>
ChainProducerState block -> String
forall a.
(FollowerId -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall block.
(StandardHash block, Show block) =>
FollowerId -> ChainProducerState block -> ShowS
showsPrec :: FollowerId -> ChainProducerState block -> ShowS
$cshow :: forall block.
(StandardHash block, Show block) =>
ChainProducerState block -> String
show :: ChainProducerState block -> String
$cshowList :: forall block.
(StandardHash block, Show block) =>
[ChainProducerState block] -> ShowS
showList :: [ChainProducerState block] -> ShowS
Show)
type FollowerStates block = Map FollowerId (FollowerState block)
type FollowerId = Int
data FollowerState block = FollowerState {
forall block. FollowerState block -> Point block
followerPoint :: Point block,
forall block. FollowerState block -> FollowerNext
followerNext :: FollowerNext
}
deriving (FollowerState block -> FollowerState block -> Bool
(FollowerState block -> FollowerState block -> Bool)
-> (FollowerState block -> FollowerState block -> Bool)
-> Eq (FollowerState block)
forall block.
StandardHash block =>
FollowerState block -> FollowerState block -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall block.
StandardHash block =>
FollowerState block -> FollowerState block -> Bool
== :: FollowerState block -> FollowerState block -> Bool
$c/= :: forall block.
StandardHash block =>
FollowerState block -> FollowerState block -> Bool
/= :: FollowerState block -> FollowerState block -> Bool
Eq, FollowerId -> FollowerState block -> ShowS
[FollowerState block] -> ShowS
FollowerState block -> String
(FollowerId -> FollowerState block -> ShowS)
-> (FollowerState block -> String)
-> ([FollowerState block] -> ShowS)
-> Show (FollowerState block)
forall block.
StandardHash block =>
FollowerId -> FollowerState block -> ShowS
forall block. StandardHash block => [FollowerState block] -> ShowS
forall block. StandardHash block => FollowerState block -> String
forall a.
(FollowerId -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall block.
StandardHash block =>
FollowerId -> FollowerState block -> ShowS
showsPrec :: FollowerId -> FollowerState block -> ShowS
$cshow :: forall block. StandardHash block => FollowerState block -> String
show :: FollowerState block -> String
$cshowList :: forall block. StandardHash block => [FollowerState block] -> ShowS
showList :: [FollowerState block] -> ShowS
Show)
data FollowerNext = FollowerBackTo | FollowerForwardFrom
deriving (FollowerNext -> FollowerNext -> Bool
(FollowerNext -> FollowerNext -> Bool)
-> (FollowerNext -> FollowerNext -> Bool) -> Eq FollowerNext
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FollowerNext -> FollowerNext -> Bool
== :: FollowerNext -> FollowerNext -> Bool
$c/= :: FollowerNext -> FollowerNext -> Bool
/= :: FollowerNext -> FollowerNext -> Bool
Eq, FollowerId -> FollowerNext -> ShowS
[FollowerNext] -> ShowS
FollowerNext -> String
(FollowerId -> FollowerNext -> ShowS)
-> (FollowerNext -> String)
-> ([FollowerNext] -> ShowS)
-> Show FollowerNext
forall a.
(FollowerId -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: FollowerId -> FollowerNext -> ShowS
showsPrec :: FollowerId -> FollowerNext -> ShowS
$cshow :: FollowerNext -> String
show :: FollowerNext -> String
$cshowList :: [FollowerNext] -> ShowS
showList :: [FollowerNext] -> ShowS
Show)
invChainProducerState :: HasFullHeader block => ChainProducerState block -> Bool
invChainProducerState :: forall block.
HasFullHeader block =>
ChainProducerState block -> Bool
invChainProducerState (ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cfid) =
Chain block -> Bool
forall block. HasFullHeader block => Chain block -> Bool
Chain.valid Chain block
c
Bool -> Bool -> Bool
&& Chain block -> FollowerStates block -> Bool
forall block.
HasHeader block =>
Chain block -> FollowerStates block -> Bool
invFollowerStates Chain block
c FollowerStates block
cflrst
Bool -> Bool -> Bool
&& (FollowerId -> Bool) -> [FollowerId] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (FollowerId -> FollowerId -> Bool
forall a. Ord a => a -> a -> Bool
< FollowerId
cfid) (FollowerStates block -> [FollowerId]
forall k a. Map k a -> [k]
Map.keys FollowerStates block
cflrst)
invFollowerStates :: HasHeader block => Chain block -> FollowerStates block -> Bool
invFollowerStates :: forall block.
HasHeader block =>
Chain block -> FollowerStates block -> Bool
invFollowerStates Chain block
c FollowerStates block
flrst =
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Point block -> Chain block -> Bool
forall block. HasHeader block => Point block -> Chain block -> Bool
pointOnChain Point block
followerPoint Chain block
c | FollowerState{Point block
followerPoint :: forall block. FollowerState block -> Point block
followerPoint :: Point block
followerPoint} <- FollowerStates block -> [FollowerState block]
forall k a. Map k a -> [a]
Map.elems FollowerStates block
flrst ]
initChainProducerState :: Chain block -> ChainProducerState block
initChainProducerState :: forall block. Chain block -> ChainProducerState block
initChainProducerState Chain block
c = Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c FollowerStates block
forall k a. Map k a
Map.empty FollowerId
0
lookupFollower :: ChainProducerState block -> FollowerId -> FollowerState block
lookupFollower :: forall block.
ChainProducerState block -> FollowerId -> FollowerState block
lookupFollower (ChainProducerState Chain block
_ FollowerStates block
cflrst FollowerId
_) FollowerId
fid = FollowerStates block
cflrst FollowerStates block -> FollowerId -> FollowerState block
forall k a. Ord k => Map k a -> k -> a
Map.! FollowerId
fid
followerExists :: FollowerId -> ChainProducerState block -> Bool
followerExists :: forall block. FollowerId -> ChainProducerState block -> Bool
followerExists FollowerId
fid (ChainProducerState Chain block
_ FollowerStates block
cflrst FollowerId
_) = FollowerId
fid FollowerId -> FollowerStates block -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` FollowerStates block
cflrst
producerChain :: ChainProducerState block -> Chain block
producerChain :: forall block. ChainProducerState block -> Chain block
producerChain (ChainProducerState Chain block
c FollowerStates block
_ FollowerId
_) = Chain block
c
findFirstPoint :: HasHeader block
=> [Point block]
-> ChainProducerState block
-> Maybe (Point block)
findFirstPoint :: forall block.
HasHeader block =>
[Point block] -> ChainProducerState block -> Maybe (Point block)
findFirstPoint [Point block]
ps = [Point block] -> Chain block -> Maybe (Point block)
forall block.
HasHeader block =>
[Point block] -> Chain block -> Maybe (Point block)
Chain.findFirstPoint [Point block]
ps (Chain block -> Maybe (Point block))
-> (ChainProducerState block -> Chain block)
-> ChainProducerState block
-> Maybe (Point block)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainProducerState block -> Chain block
forall block. ChainProducerState block -> Chain block
producerChain
initFollower :: HasHeader block
=> Point block
-> ChainProducerState block
-> (ChainProducerState block, FollowerId)
initFollower :: forall block.
HasHeader block =>
Point block
-> ChainProducerState block
-> (ChainProducerState block, FollowerId)
initFollower Point block
point (ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cfid) =
Bool
-> (ChainProducerState block, FollowerId)
-> (ChainProducerState block, FollowerId)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Point block -> Chain block -> Bool
forall block. HasHeader block => Point block -> Chain block -> Bool
pointOnChain Point block
point Chain block
c) ((ChainProducerState block, FollowerId)
-> (ChainProducerState block, FollowerId))
-> (ChainProducerState block, FollowerId)
-> (ChainProducerState block, FollowerId)
forall a b. (a -> b) -> a -> b
$
(Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c (FollowerId
-> FollowerState block
-> FollowerStates block
-> FollowerStates block
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert FollowerId
cfid FollowerState block
flrst FollowerStates block
cflrst) (FollowerId -> FollowerId
forall a. Enum a => a -> a
succ FollowerId
cfid), FollowerId
cfid)
where
flrst :: FollowerState block
flrst = FollowerState {
followerPoint :: Point block
followerPoint = Point block
point,
followerNext :: FollowerNext
followerNext = FollowerNext
FollowerBackTo
}
deleteFollower :: FollowerId -> ChainProducerState block -> ChainProducerState block
deleteFollower :: forall block.
FollowerId -> ChainProducerState block -> ChainProducerState block
deleteFollower FollowerId
fid (ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cfid) =
Bool -> ChainProducerState block -> ChainProducerState block
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (FollowerId
fid FollowerId -> FollowerStates block -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` FollowerStates block
cflrst) (ChainProducerState block -> ChainProducerState block)
-> ChainProducerState block -> ChainProducerState block
forall a b. (a -> b) -> a -> b
$
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c (FollowerId -> FollowerStates block -> FollowerStates block
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete FollowerId
fid FollowerStates block
cflrst) FollowerId
cfid
updateFollower :: HasHeader block
=> FollowerId
-> Point block
-> ChainProducerState block
-> ChainProducerState block
updateFollower :: forall block.
HasHeader block =>
FollowerId
-> Point block
-> ChainProducerState block
-> ChainProducerState block
updateFollower FollowerId
fid Point block
point (ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cnfid) =
Bool -> ChainProducerState block -> ChainProducerState block
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Point block -> Chain block -> Bool
forall block. HasHeader block => Point block -> Chain block -> Bool
pointOnChain Point block
point Chain block
c) (ChainProducerState block -> ChainProducerState block)
-> ChainProducerState block -> ChainProducerState block
forall a b. (a -> b) -> a -> b
$
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c ((FollowerState block -> FollowerState block)
-> FollowerId -> FollowerStates block -> FollowerStates block
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust FollowerState block -> FollowerState block
update FollowerId
fid FollowerStates block
cflrst) FollowerId
cnfid
where
update :: FollowerState block -> FollowerState block
update FollowerState block
flrst = FollowerState block
flrst { followerPoint = point, followerNext = FollowerBackTo }
switchFork :: HasHeader block
=> Chain block
-> ChainProducerState block
-> ChainProducerState block
switchFork :: forall block.
HasHeader block =>
Chain block -> ChainProducerState block -> ChainProducerState block
switchFork Chain block
c (ChainProducerState Chain block
c' FollowerStates block
cflrst FollowerId
cfid) =
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c (FollowerState block -> FollowerState block
update (FollowerState block -> FollowerState block)
-> FollowerStates block -> FollowerStates block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FollowerStates block
cflrst) FollowerId
cfid
where
ipoint :: Point block
ipoint = Point block -> Maybe (Point block) -> Point block
forall a. a -> Maybe a -> a
fromMaybe Point block
forall {k} (block :: k). Point block
genesisPoint (Maybe (Point block) -> Point block)
-> Maybe (Point block) -> Point block
forall a b. (a -> b) -> a -> b
$ Chain block -> Chain block -> Maybe (Point block)
forall block.
HasHeader block =>
Chain block -> Chain block -> Maybe (Point block)
Chain.intersectChains Chain block
c Chain block
c'
update :: FollowerState block -> FollowerState block
update flrst :: FollowerState block
flrst@FollowerState{Point block
followerPoint :: forall block. FollowerState block -> Point block
followerPoint :: Point block
followerPoint} =
if Point block -> Chain block -> Bool
forall block. HasHeader block => Point block -> Chain block -> Bool
pointOnChain Point block
followerPoint Chain block
c
then FollowerState block
flrst
else FollowerState block
flrst { followerPoint = ipoint, followerNext = FollowerBackTo }
followerInstruction :: HasHeader block
=> FollowerId
-> ChainProducerState block
-> Maybe (ChainUpdate block block, ChainProducerState block)
followerInstruction :: forall block.
HasHeader block =>
FollowerId
-> ChainProducerState block
-> Maybe (ChainUpdate block block, ChainProducerState block)
followerInstruction FollowerId
fid cps :: ChainProducerState block
cps@(ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cfid) =
let FollowerState {Point block
followerPoint :: forall block. FollowerState block -> Point block
followerPoint :: Point block
followerPoint, FollowerNext
followerNext :: forall block. FollowerState block -> FollowerNext
followerNext :: FollowerNext
followerNext} = ChainProducerState block -> FollowerId -> FollowerState block
forall block.
ChainProducerState block -> FollowerId -> FollowerState block
lookupFollower ChainProducerState block
cps FollowerId
fid in
case FollowerNext
followerNext of
FollowerNext
FollowerForwardFrom ->
Bool
-> Maybe (ChainUpdate block block, ChainProducerState block)
-> Maybe (ChainUpdate block block, ChainProducerState block)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Point block -> Chain block -> Bool
forall block. HasHeader block => Point block -> Chain block -> Bool
pointOnChain Point block
followerPoint Chain block
c) (Maybe (ChainUpdate block block, ChainProducerState block)
-> Maybe (ChainUpdate block block, ChainProducerState block))
-> Maybe (ChainUpdate block block, ChainProducerState block)
-> Maybe (ChainUpdate block block, ChainProducerState block)
forall a b. (a -> b) -> a -> b
$
case Point block -> Chain block -> Maybe block
forall block.
HasHeader block =>
Point block -> Chain block -> Maybe block
Chain.successorBlock Point block
followerPoint Chain block
c of
Maybe block
Nothing -> Maybe (ChainUpdate block block, ChainProducerState block)
forall a. Maybe a
Nothing
Just block
b -> (ChainUpdate block block, ChainProducerState block)
-> Maybe (ChainUpdate block block, ChainProducerState block)
forall a. a -> Maybe a
Just (block -> ChainUpdate block block
forall {k} (block :: k) a. a -> ChainUpdate block a
AddBlock block
b, ChainProducerState block
cps')
where
cps' :: ChainProducerState block
cps' = Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c ((FollowerState block -> FollowerState block)
-> FollowerId -> FollowerStates block -> FollowerStates block
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust FollowerState block -> FollowerState block
setPoint FollowerId
fid FollowerStates block
cflrst) FollowerId
cfid
setPoint :: FollowerState block -> FollowerState block
setPoint FollowerState block
flrst = FollowerState block
flrst { followerPoint = blockPoint b }
FollowerNext
FollowerBackTo -> (ChainUpdate block block, ChainProducerState block)
-> Maybe (ChainUpdate block block, ChainProducerState block)
forall a. a -> Maybe a
Just (Point block -> ChainUpdate block block
forall {k} (block :: k) a. Point block -> ChainUpdate block a
RollBack Point block
followerPoint, ChainProducerState block
cps')
where
cps' :: ChainProducerState block
cps' = Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState Chain block
c ((FollowerState block -> FollowerState block)
-> FollowerId -> FollowerStates block -> FollowerStates block
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust FollowerState block -> FollowerState block
forall {block}. FollowerState block -> FollowerState block
setForwardFrom FollowerId
fid FollowerStates block
cflrst) FollowerId
cfid
setForwardFrom :: FollowerState block -> FollowerState block
setForwardFrom FollowerState block
flrst = FollowerState block
flrst { followerNext = FollowerForwardFrom }
addBlock :: HasHeader block
=> block
-> ChainProducerState block
-> ChainProducerState block
addBlock :: forall block.
HasHeader block =>
block -> ChainProducerState block -> ChainProducerState block
addBlock block
b (ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cfid) =
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
forall block.
Chain block
-> FollowerStates block -> FollowerId -> ChainProducerState block
ChainProducerState (block -> Chain block -> Chain block
forall block.
HasHeader block =>
block -> Chain block -> Chain block
Chain.addBlock block
b Chain block
c) FollowerStates block
cflrst FollowerId
cfid
rollback :: (HasHeader block, HeaderHash block ~ HeaderHash block')
=> Point block'
-> ChainProducerState block
-> Maybe (ChainProducerState block)
rollback :: forall block block'.
(HasHeader block, HeaderHash block ~ HeaderHash block') =>
Point block'
-> ChainProducerState block -> Maybe (ChainProducerState block)
rollback Point block'
p (ChainProducerState Chain block
c FollowerStates block
cflrst FollowerId
cfid) = do
c' <- Point block -> Chain block -> Maybe (Chain block)
forall block.
HasHeader block =>
Point block -> Chain block -> Maybe (Chain block)
Chain.rollback (Point block' -> Point block
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point block'
p) Chain block
c
return $ ChainProducerState c' (rollbackFollower <$> cflrst) cfid
where
rollbackFollower :: FollowerState block -> FollowerState block
rollbackFollower flrst :: FollowerState block
flrst@FollowerState { followerPoint :: forall block. FollowerState block -> Point block
followerPoint = Point block
p' }
| Point block -> Point block -> Chain block -> Bool
forall block.
HasHeader block =>
Point block -> Point block -> Chain block -> Bool
Chain.pointIsAfter Point block
p' (Point block' -> Point block
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point block'
p) Chain block
c
= FollowerState block
flrst { followerPoint = castPoint p, followerNext = FollowerBackTo }
| Bool
otherwise
= FollowerState block
flrst
applyChainUpdate :: (HasHeader block, HeaderHash block ~ HeaderHash block')
=> ChainUpdate block' block
-> ChainProducerState block
-> Maybe (ChainProducerState block)
applyChainUpdate :: forall block block'.
(HasHeader block, HeaderHash block ~ HeaderHash block') =>
ChainUpdate block' block
-> ChainProducerState block -> Maybe (ChainProducerState block)
applyChainUpdate (AddBlock block
b) ChainProducerState block
c = ChainProducerState block -> Maybe (ChainProducerState block)
forall a. a -> Maybe a
Just (block -> ChainProducerState block -> ChainProducerState block
forall block.
HasHeader block =>
block -> ChainProducerState block -> ChainProducerState block
addBlock block
b ChainProducerState block
c)
applyChainUpdate (RollBack Point block'
p) ChainProducerState block
c = Point block'
-> ChainProducerState block -> Maybe (ChainProducerState block)
forall block block'.
(HasHeader block, HeaderHash block ~ HeaderHash block') =>
Point block'
-> ChainProducerState block -> Maybe (ChainProducerState block)
rollback Point block'
p ChainProducerState block
c
applyChainUpdates :: (HasHeader block, HeaderHash block ~ HeaderHash block')
=> [ChainUpdate block' block]
-> ChainProducerState block
-> Maybe (ChainProducerState block)
applyChainUpdates :: forall block block'.
(HasHeader block, HeaderHash block ~ HeaderHash block') =>
[ChainUpdate block' block]
-> ChainProducerState block -> Maybe (ChainProducerState block)
applyChainUpdates [] ChainProducerState block
c = ChainProducerState block -> Maybe (ChainProducerState block)
forall a. a -> Maybe a
Just ChainProducerState block
c
applyChainUpdates (ChainUpdate block' block
u:[ChainUpdate block' block]
us) ChainProducerState block
c = [ChainUpdate block' block]
-> ChainProducerState block -> Maybe (ChainProducerState block)
forall block block'.
(HasHeader block, HeaderHash block ~ HeaderHash block') =>
[ChainUpdate block' block]
-> ChainProducerState block -> Maybe (ChainProducerState block)
applyChainUpdates [ChainUpdate block' block]
us (ChainProducerState block -> Maybe (ChainProducerState block))
-> Maybe (ChainProducerState block)
-> Maybe (ChainProducerState block)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ChainUpdate block' block
-> ChainProducerState block -> Maybe (ChainProducerState block)
forall block block'.
(HasHeader block, HeaderHash block ~ HeaderHash block') =>
ChainUpdate block' block
-> ChainProducerState block -> Maybe (ChainProducerState block)
applyChainUpdate ChainUpdate block' block
u ChainProducerState block
c