ouroboros-consensus-0.27.0.0: Consensus layer for the Ouroboros blockchain protocol
Safe HaskellNone
LanguageHaskell2010

Ouroboros.Consensus.Peras.Weight

Description

Data structure for tracking the weight of blocks due to Peras boosts.

Synopsis

PerasWeightSnapshot type

data PerasWeightSnapshot blk Source #

Data structure for tracking the weight of blocks due to Peras boosts.

Instances

Instances details
Generic (PerasWeightSnapshot blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Peras.Weight

Associated Types

type Rep (PerasWeightSnapshot blk) 
Instance details

Defined in Ouroboros.Consensus.Peras.Weight

type Rep (PerasWeightSnapshot blk) = D1 ('MetaData "PerasWeightSnapshot" "Ouroboros.Consensus.Peras.Weight" "ouroboros-consensus-0.27.0.0-inplace" 'True) (C1 ('MetaCons "PerasWeightSnapshot" 'PrefixI 'True) (S1 ('MetaSel ('Just "getPerasWeightSnapshot") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map (Point blk) PerasWeight))))
StandardHash blk ⇒ Show (PerasWeightSnapshot blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Peras.Weight

StandardHash blk ⇒ Eq (PerasWeightSnapshot blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Peras.Weight

StandardHash blk ⇒ NoThunks (PerasWeightSnapshot blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Peras.Weight

type Rep (PerasWeightSnapshot blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Peras.Weight

type Rep (PerasWeightSnapshot blk) = D1 ('MetaData "PerasWeightSnapshot" "Ouroboros.Consensus.Peras.Weight" "ouroboros-consensus-0.27.0.0-inplace" 'True) (C1 ('MetaCons "PerasWeightSnapshot" 'PrefixI 'True) (S1 ('MetaSel ('Just "getPerasWeightSnapshot") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map (Point blk) PerasWeight))))

Construction

emptyPerasWeightSnapshotPerasWeightSnapshot blk Source #

An empty PerasWeightSnapshot not containing any boosted blocks.

mkPerasWeightSnapshotStandardHash blk ⇒ [(Point blk, PerasWeight)] → PerasWeightSnapshot blk Source #

Create a weight snapshot from a list of boosted points with an associated weight. In case of duplicate points, their weights are combined.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  , (BlockPoint 3 "bar", PerasWeight 2)
  , (BlockPoint 2 "foo", PerasWeight 2)
  ]
:}
>>> snap = mkPerasWeightSnapshot weights
>>> snap
[(Point Origin,PerasWeight 3),(Point (At (Block {blockPointSlot = SlotNo 2, blockPointHash = "foo"})),PerasWeight 4),(Point (At (Block {blockPointSlot = SlotNo 3, blockPointHash = "bar"})),PerasWeight 2)]

Conversion

perasWeightSnapshotToListPerasWeightSnapshot blk → [(Point blk, PerasWeight)] Source #

Return the list of boosted points with their associated weight, sorted based on their point. Does not contain duplicate points.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  , (BlockPoint 3 "bar", PerasWeight 2)
  , (BlockPoint 2 "foo", PerasWeight 2)
  ]
:}
>>> snap = mkPerasWeightSnapshot weights
>>> perasWeightSnapshotToList snap
[(Point Origin,PerasWeight 3),(Point (At (Block {blockPointSlot = SlotNo 2, blockPointHash = "foo"})),PerasWeight 4),(Point (At (Block {blockPointSlot = SlotNo 3, blockPointHash = "bar"})),PerasWeight 2)]

Insertion

addToPerasWeightSnapshotStandardHash blk ⇒ Point blk → PerasWeightPerasWeightSnapshot blk → PerasWeightSnapshot blk Source #

Add weight for the given point to the PerasWeightSnapshot. If the point already has some weight, it is added on top.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  ]
:}
>>> snap0 = mkPerasWeightSnapshot weights
>>> snap0
[(Point Origin,PerasWeight 3),(Point (At (Block {blockPointSlot = SlotNo 2, blockPointHash = "foo"})),PerasWeight 2)]
>>> snap1 = addToPerasWeightSnapshot (BlockPoint 3 "bar") (PerasWeight 2) snap0
>>> snap1
[(Point Origin,PerasWeight 3),(Point (At (Block {blockPointSlot = SlotNo 2, blockPointHash = "foo"})),PerasWeight 2),(Point (At (Block {blockPointSlot = SlotNo 3, blockPointHash = "bar"})),PerasWeight 2)]
>>> snap2 = addToPerasWeightSnapshot (BlockPoint 2 "foo") (PerasWeight 2) snap1
>>> snap2
[(Point Origin,PerasWeight 3),(Point (At (Block {blockPointSlot = SlotNo 2, blockPointHash = "foo"})),PerasWeight 4),(Point (At (Block {blockPointSlot = SlotNo 3, blockPointHash = "bar"})),PerasWeight 2)]

Pruning

prunePerasWeightSnapshotSlotNoPerasWeightSnapshot blk → PerasWeightSnapshot blk Source #

Prune the given PerasWeightSnapshot by removing the weight of all blocks strictly older than the given slot.

This function is used to get garbage-collect boosted blocks blocks which are older than our immutable tip as we will never adopt a chain containing them.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  , (BlockPoint 3 "bar", PerasWeight 2)
  , (BlockPoint 2 "foo", PerasWeight 2)
  ]
:}
>>> snap = mkPerasWeightSnapshot weights
>>> prunePerasWeightSnapshot (SlotNo 2) snap
[(Point (At (Block {blockPointSlot = SlotNo 2, blockPointHash = "foo"})),PerasWeight 4),(Point (At (Block {blockPointSlot = SlotNo 3, blockPointHash = "bar"})),PerasWeight 2)]
>>> prunePerasWeightSnapshot (SlotNo 3) snap
[(Point (At (Block {blockPointSlot = SlotNo 3, blockPointHash = "bar"})),PerasWeight 2)]

Query

weightBoostOfPointStandardHash blk ⇒ PerasWeightSnapshot blk → Point blk → PerasWeight Source #

Get the weight boost for a point, or mempty :: PerasWeight otherwise.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  , (BlockPoint 3 "bar", PerasWeight 2)
  , (BlockPoint 2 "foo", PerasWeight 2)
  ]
:}
>>> snap = mkPerasWeightSnapshot weights
>>> weightBoostOfPoint snap (BlockPoint 2 "foo")
PerasWeight 4
>>> weightBoostOfPoint snap (BlockPoint 2 "baz")
PerasWeight 0

weightBoostOfFragment ∷ (StandardHash blk, HasHeader h, HeaderHash blk ~ HeaderHash h) ⇒ PerasWeightSnapshot blk → AnchoredFragment h → PerasWeight Source #

Get the weight boost for a fragment, ie the sum of all weightBoostOfPoint for all points on the fragment (excluding the anchor).

Note that this quantity is relative to the anchor of the fragment, so it should only be compared against other fragments with the same anchor.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  , (BlockPoint 3 "bar", PerasWeight 2)
  , (BlockPoint 2 "foo", PerasWeight 2)
  ]
:}
>>> :{
snap = mkPerasWeightSnapshot weights
foo = HeaderFields (SlotNo 2) (BlockNo 1) "foo"
bar = HeaderFields (SlotNo 3) (BlockNo 2) "bar"
frag0 :: AnchoredFragment (HeaderFields Blk)
frag0 = Empty AnchorGenesis :> foo :> bar
:}
>>> weightBoostOfFragment snap frag0
PerasWeight 6

Only keeping the last block from frag0:

>>> frag1 = AF.anchorNewest 1 frag0
>>> weightBoostOfFragment snap frag1
PerasWeight 2

Dropping the head from frag0, and instead adding an unboosted point:

>>> frag2 = AF.dropNewest 1 frag0 :> HeaderFields (SlotNo 4) (BlockNo 2) "baz"
>>> weightBoostOfFragment snap frag2
PerasWeight 4

totalWeightOfFragment ∷ (StandardHash blk, HasHeader h, HeaderHash blk ~ HeaderHash h) ⇒ PerasWeightSnapshot blk → AnchoredFragment h → PerasWeight Source #

Get the total weight for a fragment, ie the length plus the weight boost (weightBoostOfFragment) of the fragment.

Note that this quantity is relative to the anchor of the fragment, so it should only be compared against other fragments with the same anchor.

>>> :{
weights :: [(Point Blk, PerasWeight)]
weights =
  [ (BlockPoint 2 "foo", PerasWeight 2)
  , (GenesisPoint,       PerasWeight 3)
  , (BlockPoint 3 "bar", PerasWeight 2)
  , (BlockPoint 2 "foo", PerasWeight 2)
  ]
:}
>>> :{
snap = mkPerasWeightSnapshot weights
foo = HeaderFields (SlotNo 2) (BlockNo 1) "foo"
bar = HeaderFields (SlotNo 3) (BlockNo 2) "bar"
frag0 :: AnchoredFragment (HeaderFields Blk)
frag0 = Empty AnchorGenesis :> foo :> bar
:}
>>> totalWeightOfFragment snap frag0
PerasWeight 8

Only keeping the last block from frag0:

>>> frag1 = AF.anchorNewest 1 frag0
>>> totalWeightOfFragment snap frag1
PerasWeight 3

Dropping the head from frag0, and instead adding an unboosted point:

>>> frag2 = AF.dropNewest 1 frag0 :> HeaderFields (SlotNo 4) (BlockNo 2) "baz"
>>> totalWeightOfFragment snap frag2
PerasWeight 6