Safe Haskell | None |
---|---|
Language | Haskell2010 |
Ouroboros.Consensus.Block.SupportsDiffusionPipelining
Description
Synopsis
- class (Show (TentativeHeaderState blk), NoThunks (TentativeHeaderState blk), Show (TentativeHeaderView blk)) ⇒ BlockSupportsDiffusionPipelining blk where
- type TentativeHeaderState blk
- type TentativeHeaderView blk
- initialTentativeHeaderState ∷ Proxy blk → TentativeHeaderState blk
- tentativeHeaderView ∷ BlockConfig blk → Header blk → TentativeHeaderView blk
- applyTentativeHeaderView ∷ Proxy blk → TentativeHeaderView blk → TentativeHeaderState blk → Maybe (TentativeHeaderState blk)
- updateTentativeHeaderState ∷ BlockSupportsDiffusionPipelining blk ⇒ BlockConfig blk → Header blk → TentativeHeaderState blk → Maybe (TentativeHeaderState blk)
- newtype DisableDiffusionPipelining blk = DisableDiffusionPipelining blk
- newtype SelectViewDiffusionPipelining blk = SelectViewDiffusionPipelining blk
- data SelectViewTentativeState proto
- = LastInvalidSelectView !(SelectView proto)
- | NoLastInvalidSelectView
- data family BlockConfig blk
- data family Header blk
Documentation
class (Show (TentativeHeaderState blk), NoThunks (TentativeHeaderState blk), Show (TentativeHeaderView blk)) ⇒ BlockSupportsDiffusionPipelining blk where Source #
Block functionality required to support __Block Diffusion Pipelining via Delayed Validation__ (DPvDV).
High-level context
With DPvDV, a node is, under certain conditions, already announcing a new block to its downstream peers before it has fully validated the block body. Concretely, the node maintains a tentative header that, if present, extends the current selection, and is announced via the ChainSync servers to downstream peers.
Ideally, the body turns out to be valid, in which case the tentative header
is set to Nothing
, and the selection is updated to now include the header
at its tip.
If the body corresponding to the tentative header turns out to be invalid (we call such a header a trap header), the tentative header is cleared, and the ChainSync servers send a rollback instruction. In this case, the network wasted work in diffusing, storing and validating this block. If abused, this could cause an unbounded amount of work for honest nodes. Hence, we need to enforce that our upstream nodes adhere to an appropriate criterion related to trap headers, and so must also restrict ourselves accordingly such that downstream nodes do not disconnect from us.
Semantics
This type class allows to define a block-specific criterion determining whether a header that might turn out to be a trap header is allowed to be set as the tentative header.
This is used in two places:
- The ChainSel logic. We make sure that we only set the tentative header if this criterion is fulfilled.
- The BlockFetch clients, in combination with the ChainSel validation logic. For every upstream BlockFetch peer, we make sure that the invalid blocks this peer sent adhere to the pipelining criterion.
Concretely, the abstract Consensus layer maintains TentativeHeaderState
s
(one in ChainSel, and one for each (BlockFetch) upstream peer). Suppose that
hdr
either might turn out or is already known to be a trap header. Then
applyTentativeHeaderView
(Proxy
@blk) thv st
(where thv =
) will returntentativeHeaderView
bcfg hdr
Nothing
ifhdr
does not satisfy the pipelining criterion.- In ChainSel, this means that
hdr
should not be pipelined, as it would violate the criterion if it turns out to be a trap header. - In the BlockFetch punishment logic, this means that we disconnect from the peer that sent the corresponding invalid block.
- In ChainSel, this means that
ifJust
st'hdr
does satisfy the pipelining criterion. If thehdr
is (in the BlockFetch punishment logic) or turns out to be (in ChainSel) a trap header, theTentativeHeaderState
should be updated to the returnedst'
.
Requirements
Safety
The criterion is sufficiently strict such that an adversary can not induce an unbounded amount of work for honest nodes.
Consistent validity under subsequences
Suppose that over some period of time, an honest node advertised the headers
hdrs :: [Header blk]
as its trap tentative headers. A downstream honest
node might only observe a subsequence of this list (there's no guarantee that
every ChainSync server sends every selected tip), but must still consider our
behavior as valid.
Hence, for every subsequence thvs'
of thvs =
, we need to havetentativeHeaderView
bcfg
<$>
hdrs
isJust
hdrs'Valid
for all st ::
andTentativeHeaderState
blk
hdrsValid =foldlM
(flip
$applyTentativeHeaderView
p) st thvs hdrs'Valid =foldlM
(flip
$applyTentativeHeaderView
p) st thvs'
where
and isJust
hdrsValidp ::
.Proxy
blk
Efficiently enforcible
The TentativeHeaderState
must have bounded size, and
applyTentativeHeaderView
must be efficient and objective (different nodes
must agree on its result for the same header and state).
As a historical example for establishing objectivity, see the removal of the isSelfIssued tiebreaker in the chain order.
Usefulness despite adversarial activity
It must not be possible for an adversary to easily manipulate the
TentativeHeaderState
in such a way that almost no headers can be pipelined
anymore. It is acceptable if DPvDV is less effective in scenarios involving
an adversary with a very large amount of resources (like stake).
Associated Types
type TentativeHeaderState blk Source #
State that is maintained to judge whether a header can be pipelined. It can be thought of as a summary of all past trap tentative headers.
type TentativeHeaderView blk Source #
View on a header required for updating the TentativeHeaderState
.
Methods
initialTentativeHeaderState ∷ Proxy blk → TentativeHeaderState blk Source #
The initial TentativeHeaderState
. This is used as the initial value on
node startup, as well as by the HFC instance for new eras.
tentativeHeaderView ∷ BlockConfig blk → Header blk → TentativeHeaderView blk Source #
See TentativeHeaderView
.
applyTentativeHeaderView Source #
Arguments
∷ Proxy blk | |
→ TentativeHeaderView blk | Extracted using |
→ TentativeHeaderState blk | The most recent |
→ Maybe (TentativeHeaderState blk) | The new |
Apply a TentativeHeaderView
to the TentativeHeaderState
. This returns
to indicate that the underlying header can be pipelined, and
that the Just
stTentativeHeaderState
must be updated to st
if the header
turns/turned out to be a trap header (ie the corresponding block body is
invalid).
Also see updateTentativeHeaderState
.
Instances
updateTentativeHeaderState ∷ BlockSupportsDiffusionPipelining blk ⇒ BlockConfig blk → Header blk → TentativeHeaderState blk → Maybe (TentativeHeaderState blk) Source #
Composition of tentativeHeaderView
and applyTentativeHeaderView
.
DerivingVia
helpers
DisableDiffusionPipelining
newtype DisableDiffusionPipelining blk Source #
A DerivingVia
helper to implement BlockSupportsDiffusionPipelining
for
blocks where no header should ever be pipelined.
deriving via DisableDiffusionPipelining MyBlock instance BlockSupportsDiffusionPipelining MyBlock
Constructors
DisableDiffusionPipelining blk |
Instances
BlockSupportsDiffusionPipelining (DisableDiffusionPipelining blk) Source # | |||||||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining Associated Types
Methods initialTentativeHeaderState ∷ Proxy (DisableDiffusionPipelining blk) → TentativeHeaderState (DisableDiffusionPipelining blk) Source # tentativeHeaderView ∷ BlockConfig (DisableDiffusionPipelining blk) → Header (DisableDiffusionPipelining blk) → TentativeHeaderView (DisableDiffusionPipelining blk) Source # applyTentativeHeaderView ∷ Proxy (DisableDiffusionPipelining blk) → TentativeHeaderView (DisableDiffusionPipelining blk) → TentativeHeaderState (DisableDiffusionPipelining blk) → Maybe (TentativeHeaderState (DisableDiffusionPipelining blk)) Source # | |||||||||
newtype BlockConfig (DisableDiffusionPipelining blk) Source # | |||||||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining newtype BlockConfig (DisableDiffusionPipelining blk) = DisableDiffusionPipeliningBlockConfig (BlockConfig blk) | |||||||||
newtype Header (DisableDiffusionPipelining blk) Source # | |||||||||
type TentativeHeaderState (DisableDiffusionPipelining blk) Source # | |||||||||
type TentativeHeaderView (DisableDiffusionPipelining blk) Source # | |||||||||
SelectViewDiffusionPipelining
newtype SelectViewDiffusionPipelining blk Source #
A DerivingVia
helper to implement BlockSupportsDiffusionPipelining
for
blocks where a header should be pipelined iff it has a better SelectView
than the last tentative trap header.
deriving via DisableDiffusionPipelining MyBlock instance BlockSupportsProtocol blk => BlockSupportsDiffusionPipelining MyBlock
This requires that the SelectView
is totally ordered, in particular that
the order is transitive.
For example, if
, this means that a header can be
pipelined if it has a larger block number than the last tentative trap
header. So if someone diffused a trap header for a particular block height,
no other block can be pipelined for that block height. This would limit the
Usefulness despite adversarial activity if an attacker diffuses a trap
header (and later also a valid block) every time they are elected.SelectView
~ BlockNo
Constructors
SelectViewDiffusionPipelining blk |
Instances
(BlockSupportsProtocol blk, Show (SelectView (BlockProtocol blk))) ⇒ BlockSupportsDiffusionPipelining (SelectViewDiffusionPipelining blk) Source # | |||||||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining Associated Types
Methods initialTentativeHeaderState ∷ Proxy (SelectViewDiffusionPipelining blk) → TentativeHeaderState (SelectViewDiffusionPipelining blk) Source # tentativeHeaderView ∷ BlockConfig (SelectViewDiffusionPipelining blk) → Header (SelectViewDiffusionPipelining blk) → TentativeHeaderView (SelectViewDiffusionPipelining blk) Source # applyTentativeHeaderView ∷ Proxy (SelectViewDiffusionPipelining blk) → TentativeHeaderView (SelectViewDiffusionPipelining blk) → TentativeHeaderState (SelectViewDiffusionPipelining blk) → Maybe (TentativeHeaderState (SelectViewDiffusionPipelining blk)) Source # | |||||||||
newtype BlockConfig (SelectViewDiffusionPipelining blk) Source # | |||||||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining newtype BlockConfig (SelectViewDiffusionPipelining blk) = SelectViewDiffusionPipeliningBlockConfig (BlockConfig blk) | |||||||||
newtype Header (SelectViewDiffusionPipelining blk) Source # | |||||||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining newtype Header (SelectViewDiffusionPipelining blk) = SelectViewDiffusionPipeliningHeader (Header blk) | |||||||||
type TentativeHeaderState (SelectViewDiffusionPipelining blk) Source # | |||||||||
type TentativeHeaderView (SelectViewDiffusionPipelining blk) Source # | |||||||||
data SelectViewTentativeState proto Source #
TentativeHeaderState
(SelectViewDiffusionPipelining
blk) ~SelectViewTentativeState
(BlockProtocol
blk)
Constructors
LastInvalidSelectView !(SelectView proto) | |
NoLastInvalidSelectView |
Instances
Generic (SelectViewTentativeState proto) Source # | |||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining Associated Types
Methods from ∷ SelectViewTentativeState proto → Rep (SelectViewTentativeState proto) x # to ∷ Rep (SelectViewTentativeState proto) x → SelectViewTentativeState proto # | |||||
ConsensusProtocol proto ⇒ Show (SelectViewTentativeState proto) Source # | |||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining Methods showsPrec ∷ Int → SelectViewTentativeState proto → ShowS # show ∷ SelectViewTentativeState proto → String # showList ∷ [SelectViewTentativeState proto] → ShowS # | |||||
ConsensusProtocol proto ⇒ Eq (SelectViewTentativeState proto) Source # | |||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining Methods (==) ∷ SelectViewTentativeState proto → SelectViewTentativeState proto → Bool # (/=) ∷ SelectViewTentativeState proto → SelectViewTentativeState proto → Bool # | |||||
ConsensusProtocol proto ⇒ NoThunks (SelectViewTentativeState proto) Source # | |||||
type Rep (SelectViewTentativeState proto) Source # | |||||
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining type Rep (SelectViewTentativeState proto) = D1 ('MetaData "SelectViewTentativeState" "Ouroboros.Consensus.Block.SupportsDiffusionPipelining" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "LastInvalidSelectView" 'PrefixI 'False) (S1 ('MetaSel ('Nothing ∷ Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (SelectView proto))) :+: C1 ('MetaCons "NoLastInvalidSelectView" 'PrefixI 'False) (U1 ∷ Type → Type)) |
Data family instances
data family BlockConfig blk Source #
Static configuration required to work with this type of blocks
Instances
Isomorphic BlockConfig Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Embed.Unary Methods project ∷ NoHardForks blk ⇒ BlockConfig (HardForkBlock '[blk]) → BlockConfig blk Source # inject ∷ NoHardForks blk ⇒ BlockConfig blk → BlockConfig (HardForkBlock '[blk]) Source # | |
CanHardFork xs ⇒ NoThunks (BlockConfig (HardForkBlock xs)) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Basics Methods noThunks ∷ Context → BlockConfig (HardForkBlock xs) → IO (Maybe ThunkInfo) Source # wNoThunks ∷ Context → BlockConfig (HardForkBlock xs) → IO (Maybe ThunkInfo) Source # showTypeOf ∷ Proxy (BlockConfig (HardForkBlock xs)) → String Source # | |
NoThunks (BlockConfig (DualBlock m a)) Source # | |
newtype BlockConfig (DisableDiffusionPipelining blk) Source # | |
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining newtype BlockConfig (DisableDiffusionPipelining blk) = DisableDiffusionPipeliningBlockConfig (BlockConfig blk) | |
newtype BlockConfig (SelectViewDiffusionPipelining blk) Source # | |
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining newtype BlockConfig (SelectViewDiffusionPipelining blk) = SelectViewDiffusionPipeliningBlockConfig (BlockConfig blk) | |
newtype BlockConfig (HardForkBlock xs) Source # | |
data BlockConfig (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual |
data family Header blk Source #
Instances
GetHeader1 Header Source # | |
Defined in Ouroboros.Consensus.Block.Abstract Methods getHeader1 ∷ Header blk → Header blk Source # | |
Inject Header Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Embed.Nary Methods inject ∷ ∀ x (xs ∷ [Type]). (CanHardFork xs, HasCanonicalTxIn xs, HasHardForkTxOut xs) ⇒ InjectionIndex xs x → Header x → Header (HardForkBlock xs) Source # | |
Isomorphic Header Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Embed.Unary Methods project ∷ NoHardForks blk ⇒ Header (HardForkBlock '[blk]) → Header blk Source # inject ∷ NoHardForks blk ⇒ Header blk → Header (HardForkBlock '[blk]) Source # | |
CanHardFork xs ⇒ HasNestedContent Header (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block Methods unnest ∷ Header (HardForkBlock xs) → DepPair (NestedCtxt Header (HardForkBlock xs)) Source # nest ∷ DepPair (NestedCtxt Header (HardForkBlock xs)) → Header (HardForkBlock xs) Source # | |
SerialiseHFC xs ⇒ ReconstructNestedCtxt Header (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseDisk Methods reconstructPrefixLen ∷ proxy (Header (HardForkBlock xs)) → PrefixLen Source # reconstructNestedCtxt ∷ proxy (Header (HardForkBlock xs)) → ShortByteString → SizeInBytes → SomeSecond (NestedCtxt Header) (HardForkBlock xs) Source # | |
StandardHash blk ⇒ StandardHash (Header blk ∷ Type) Source # | |
Defined in Ouroboros.Consensus.Block.Abstract | |
Typeable xs ⇒ ShowProxy (Header (HardForkBlock xs) ∷ Type) Source # | |
HasNestedContent Header m ⇒ HasNestedContent Header (DualBlock m a) Source # | |
ReconstructNestedCtxt Header m ⇒ ReconstructNestedCtxt Header (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual Methods reconstructPrefixLen ∷ proxy (Header (DualBlock m a)) → PrefixLen Source # reconstructNestedCtxt ∷ proxy (Header (DualBlock m a)) → ShortByteString → SizeInBytes → SomeSecond (NestedCtxt Header) (DualBlock m a) Source # | |
CanHardFork xs ⇒ SameDepIndex (NestedCtxt_ (HardForkBlock xs) Header ∷ Type → Type) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block Methods sameDepIndex ∷ NestedCtxt_ (HardForkBlock xs) Header a → NestedCtxt_ (HardForkBlock xs) Header b → Maybe (a :~: b) Source # | |
(Typeable m, Typeable a) ⇒ ShowProxy (DualHeader m a ∷ Type) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual | |
CanHardFork xs ⇒ Show (Header (HardForkBlock xs)) Source # | |
All (Compose Eq Header) xs ⇒ Eq (Header (HardForkBlock xs)) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block Methods (==) ∷ Header (HardForkBlock xs) → Header (HardForkBlock xs) → Bool # (/=) ∷ Header (HardForkBlock xs) → Header (HardForkBlock xs) → Bool # | |
CanHardFork xs ⇒ NoThunks (Header (HardForkBlock xs)) Source # | |
NoThunks (Header (DualBlock m a)) Source # | |
All CondenseConstraints xs ⇒ Condense (Header (HardForkBlock xs)) Source # | |
CanHardFork xs ⇒ HasHeader (Header (HardForkBlock xs)) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block Methods getHeaderFields ∷ Header (HardForkBlock xs) → HeaderFields (Header (HardForkBlock xs)) Source # | |
SerialiseHFC xs ⇒ SerialiseNodeToNode (HardForkBlock xs) (Header (HardForkBlock xs)) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseNodeToNode Methods encodeNodeToNode ∷ CodecConfig (HardForkBlock xs) → BlockNodeToNodeVersion (HardForkBlock xs) → Header (HardForkBlock xs) → Encoding Source # decodeNodeToNode ∷ CodecConfig (HardForkBlock xs) → BlockNodeToNodeVersion (HardForkBlock xs) → ∀ s. Decoder s (Header (HardForkBlock xs)) Source # | |
SerialiseHFC xs ⇒ DecodeDiskDep (NestedCtxt Header) (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseDisk Methods decodeDiskDep ∷ CodecConfig (HardForkBlock xs) → NestedCtxt Header (HardForkBlock xs) a → ∀ s. Decoder s (ByteString → a) Source # | |
SerialiseHFC xs ⇒ DecodeDiskDepIx (NestedCtxt Header) (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseDisk Methods decodeDiskDepIx ∷ CodecConfig (HardForkBlock xs) → Decoder s (SomeSecond (NestedCtxt Header) (HardForkBlock xs)) Source # | |
SerialiseHFC xs ⇒ EncodeDiskDep (NestedCtxt Header) (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseDisk Methods encodeDiskDep ∷ CodecConfig (HardForkBlock xs) → NestedCtxt Header (HardForkBlock xs) a → a → Encoding Source # | |
SerialiseHFC xs ⇒ EncodeDiskDepIx (NestedCtxt Header) (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseDisk Methods encodeDiskDepIx ∷ CodecConfig (HardForkBlock xs) → SomeSecond (NestedCtxt Header) (HardForkBlock xs) → Encoding Source # | |
EncodeDiskDep (NestedCtxt Header) m ⇒ EncodeDiskDep (NestedCtxt Header) (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual Methods encodeDiskDep ∷ CodecConfig (DualBlock m a) → NestedCtxt Header (DualBlock m a) a0 → a0 → Encoding Source # | |
EncodeDiskDepIx (NestedCtxt Header) m ⇒ EncodeDiskDepIx (NestedCtxt Header) (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual Methods encodeDiskDepIx ∷ CodecConfig (DualBlock m a) → SomeSecond (NestedCtxt Header) (DualBlock m a) → Encoding Source # | |
Show (Header m) ⇒ Show (DualHeader m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual Methods showsPrec ∷ Int → DualHeader m a → ShowS # show ∷ DualHeader m a → String # showList ∷ [DualHeader m a] → ShowS # | |
Bridge m a ⇒ HasHeader (DualHeader m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual Methods getHeaderFields ∷ DualHeader m a → HeaderFields (DualHeader m a) Source # | |
All SingleEraBlock xs ⇒ Show (NestedCtxt_ (HardForkBlock xs) Header a) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block Methods showsPrec ∷ Int → NestedCtxt_ (HardForkBlock xs) Header a → ShowS # show ∷ NestedCtxt_ (HardForkBlock xs) Header a → String # showList ∷ [NestedCtxt_ (HardForkBlock xs) Header a] → ShowS # | |
type HeaderHash (Header blk ∷ Type) Source # | |
Defined in Ouroboros.Consensus.Block.Abstract | |
type BlockProtocol (Header blk) Source # | |
Defined in Ouroboros.Consensus.Block.Abstract | |
newtype Header (DisableDiffusionPipelining blk) Source # | |
newtype Header (SelectViewDiffusionPipelining blk) Source # | |
Defined in Ouroboros.Consensus.Block.SupportsDiffusionPipelining newtype Header (SelectViewDiffusionPipelining blk) = SelectViewDiffusionPipeliningHeader (Header blk) | |
newtype Header (HardForkBlock xs) Source # | |
newtype Header (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual |