{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Ouroboros.Consensus.Util.AnchoredFragment (
compareHeadBlockNo
, forksAtMostKBlocks
, preferAnchoredCandidate
, compareAnchoredCandidates
) where
import Data.Function (on)
import Data.Proxy
import Data.Word (Word64)
import GHC.Stack
import Ouroboros.Network.AnchoredFragment
(AnchoredFragment ((:>), Empty))
import qualified Ouroboros.Network.AnchoredFragment as AF
import Ouroboros.Consensus.Block
import Ouroboros.Consensus.Config
import Ouroboros.Consensus.Protocol.Abstract
compareHeadBlockNo
:: HasHeader b
=> AnchoredFragment b
-> AnchoredFragment b
-> Ordering
compareHeadBlockNo :: AnchoredFragment b -> AnchoredFragment b -> Ordering
compareHeadBlockNo = WithOrigin BlockNo -> WithOrigin BlockNo -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (WithOrigin BlockNo -> WithOrigin BlockNo -> Ordering)
-> (AnchoredFragment b -> WithOrigin BlockNo)
-> AnchoredFragment b
-> AnchoredFragment b
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` AnchoredFragment b -> WithOrigin BlockNo
forall block.
HasHeader block =>
AnchoredFragment block -> WithOrigin BlockNo
AF.headBlockNo
forksAtMostKBlocks
:: HasHeader b
=> Word64
-> AnchoredFragment b
-> AnchoredFragment b
-> Bool
forksAtMostKBlocks :: Word64 -> AnchoredFragment b -> AnchoredFragment b -> Bool
forksAtMostKBlocks Word64
k AnchoredFragment b
ours AnchoredFragment b
theirs = case AnchoredFragment b
ours AnchoredFragment b
-> AnchoredFragment b
-> Maybe
(AnchoredFragment b, AnchoredFragment b, AnchoredFragment b,
AnchoredFragment b)
forall block1 block2.
(HasHeader block1, HasHeader block2,
HeaderHash block1 ~ HeaderHash block2) =>
AnchoredFragment block1
-> AnchoredFragment block2
-> Maybe
(AnchoredFragment block1, AnchoredFragment block2,
AnchoredFragment block1, AnchoredFragment block2)
`AF.intersect` AnchoredFragment b
theirs of
Maybe
(AnchoredFragment b, AnchoredFragment b, AnchoredFragment b,
AnchoredFragment b)
Nothing -> Bool
False
Just (AnchoredFragment b
_, AnchoredFragment b
_, AnchoredFragment b
ourSuffix, AnchoredFragment b
_) -> Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (AnchoredFragment b -> Int
forall block. HasHeader block => AnchoredFragment block -> Int
AF.length AnchoredFragment b
ourSuffix) Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
k
preferAnchoredCandidate :: forall blk. BlockSupportsProtocol blk
=> TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate :: TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cfg AnchoredFragment (Header blk)
ours AnchoredFragment (Header blk)
theirs =
case (AnchoredFragment (Header blk)
ours, AnchoredFragment (Header blk)
theirs) of
(AnchoredFragment (Header blk)
_, Empty Anchor (Header blk)
_) ->
Bool
False
(Empty Anchor (Header blk)
ourAnchor, AnchoredFragment (Header blk)
_ :> Header blk
theirTip) ->
Header blk -> Point (Header blk)
forall block. HasHeader block => block -> Point block
blockPoint Header blk
theirTip Point (Header blk) -> Point (Header blk) -> Bool
forall a. Eq a => a -> a -> Bool
/= Anchor (Header blk) -> Point (Header blk)
forall block. Anchor block -> Point block
AF.anchorToPoint Anchor (Header blk)
ourAnchor
(AnchoredFragment (Header blk)
_ :> Header blk
ourTip, AnchoredFragment (Header blk)
_ :> Header blk
theirTip) ->
Proxy (BlockProtocol blk)
-> ChainSelConfig (BlockProtocol blk)
-> SelectView (BlockProtocol blk)
-> SelectView (BlockProtocol blk)
-> Bool
forall p (proxy :: * -> *).
ChainSelection p =>
proxy p -> ChainSelConfig p -> SelectView p -> SelectView p -> Bool
preferCandidate
(Proxy (BlockProtocol blk)
forall k (t :: k). Proxy t
Proxy @(BlockProtocol blk))
(ConsensusConfig (BlockProtocol blk)
-> ChainSelConfig (BlockProtocol blk)
forall p.
ConsensusProtocol p =>
ConsensusConfig p -> ChainSelConfig p
chainSelConfig (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg))
(BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
forall blk.
BlockSupportsProtocol blk =>
BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
selectView (TopLevelConfig blk -> BlockConfig blk
forall blk. TopLevelConfig blk -> BlockConfig blk
configBlock TopLevelConfig blk
cfg) Header blk
ourTip)
(BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
forall blk.
BlockSupportsProtocol blk =>
BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
selectView (TopLevelConfig blk -> BlockConfig blk
forall blk. TopLevelConfig blk -> BlockConfig blk
configBlock TopLevelConfig blk
cfg) Header blk
theirTip)
compareAnchoredCandidates :: forall blk. (BlockSupportsProtocol blk, HasCallStack)
=> TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
compareAnchoredCandidates :: TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
compareAnchoredCandidates TopLevelConfig blk
cfg AnchoredFragment (Header blk)
ours AnchoredFragment (Header blk)
theirs =
case (AnchoredFragment (Header blk)
ours, AnchoredFragment (Header blk)
theirs) of
(AnchoredFragment (Header blk)
_ :> Header blk
ourTip, AnchoredFragment (Header blk)
_ :> Header blk
theirTip) ->
Proxy (BlockProtocol blk)
-> ChainSelConfig (BlockProtocol blk)
-> SelectView (BlockProtocol blk)
-> SelectView (BlockProtocol blk)
-> Ordering
forall p (proxy :: * -> *).
ChainSelection p =>
proxy p
-> ChainSelConfig p -> SelectView p -> SelectView p -> Ordering
compareCandidates
(Proxy (BlockProtocol blk)
forall k (t :: k). Proxy t
Proxy @(BlockProtocol blk))
(ConsensusConfig (BlockProtocol blk)
-> ChainSelConfig (BlockProtocol blk)
forall p.
ConsensusProtocol p =>
ConsensusConfig p -> ChainSelConfig p
chainSelConfig (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg))
(BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
forall blk.
BlockSupportsProtocol blk =>
BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
selectView (TopLevelConfig blk -> BlockConfig blk
forall blk. TopLevelConfig blk -> BlockConfig blk
configBlock TopLevelConfig blk
cfg) Header blk
ourTip)
(BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
forall blk.
BlockSupportsProtocol blk =>
BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
selectView (TopLevelConfig blk -> BlockConfig blk
forall blk. TopLevelConfig blk -> BlockConfig blk
configBlock TopLevelConfig blk
cfg) Header blk
theirTip)
(AnchoredFragment (Header blk), AnchoredFragment (Header blk))
_otherwise ->
[Char] -> Ordering
forall a. HasCallStack => [Char] -> a
error [Char]
"compareAnchoredCandidates: precondition violated"