Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Header validation
Synopsis
- revalidateHeader ∷ ∀ blk. (BlockSupportsProtocol blk, ValidateEnvelope blk, HasCallStack) ⇒ TopLevelConfig blk → LedgerView (BlockProtocol blk) → Header blk → Ticked (HeaderState blk) → HeaderState blk
- validateHeader ∷ (BlockSupportsProtocol blk, ValidateEnvelope blk) ⇒ TopLevelConfig blk → LedgerView (BlockProtocol blk) → Header blk → Ticked (HeaderState blk) → Except (HeaderError blk) (HeaderState blk)
- data AnnTip blk = AnnTip {
- annTipSlotNo ∷ !SlotNo
- annTipBlockNo ∷ !BlockNo
- annTipInfo ∷ !(TipInfo blk)
- class (StandardHash blk, Show (TipInfo blk), Eq (TipInfo blk), NoThunks (TipInfo blk)) ⇒ HasAnnTip blk where
- type TipInfo blk ∷ Type
- getTipInfo ∷ Header blk → TipInfo blk
- tipInfoHash ∷ proxy blk → TipInfo blk → HeaderHash blk
- annTipHash ∷ ∀ blk. HasAnnTip blk ⇒ AnnTip blk → HeaderHash blk
- annTipPoint ∷ ∀ blk. HasAnnTip blk ⇒ AnnTip blk → Point blk
- annTipRealPoint ∷ ∀ blk. HasAnnTip blk ⇒ AnnTip blk → RealPoint blk
- castAnnTip ∷ TipInfo blk ~ TipInfo blk' ⇒ AnnTip blk → AnnTip blk'
- getAnnTip ∷ (HasHeader (Header blk), HasAnnTip blk) ⇒ Header blk → AnnTip blk
- mapAnnTip ∷ (TipInfo blk → TipInfo blk') → AnnTip blk → AnnTip blk'
- data HeaderState blk = HeaderState {
- headerStateTip ∷ !(WithOrigin (AnnTip blk))
- headerStateChainDep ∷ !(ChainDepState (BlockProtocol blk))
- castHeaderState ∷ (Coercible (ChainDepState (BlockProtocol blk)) (ChainDepState (BlockProtocol blk')), TipInfo blk ~ TipInfo blk') ⇒ HeaderState blk → HeaderState blk'
- genesisHeaderState ∷ ChainDepState (BlockProtocol blk) → HeaderState blk
- headerStateBlockNo ∷ HeaderState blk → WithOrigin BlockNo
- headerStatePoint ∷ HasAnnTip blk ⇒ HeaderState blk → Point blk
- tickHeaderState ∷ ConsensusProtocol (BlockProtocol blk) ⇒ ConsensusConfig (BlockProtocol blk) → LedgerView (BlockProtocol blk) → SlotNo → HeaderState blk → Ticked (HeaderState blk)
- class (HasHeader (Header blk), HasAnnTip blk) ⇒ BasicEnvelopeValidation blk where
- expectedFirstBlockNo ∷ proxy blk → BlockNo
- expectedNextBlockNo ∷ proxy blk → TipInfo blk → TipInfo blk → BlockNo → BlockNo
- minimumPossibleSlotNo ∷ Proxy blk → SlotNo
- minimumNextSlotNo ∷ proxy blk → TipInfo blk → TipInfo blk → SlotNo → SlotNo
- data HeaderEnvelopeError blk
- = UnexpectedBlockNo !BlockNo !BlockNo
- | UnexpectedSlotNo !SlotNo !SlotNo
- | UnexpectedPrevHash !(WithOrigin (HeaderHash blk)) !(ChainHash blk)
- | CheckpointMismatch !BlockNo !(HeaderHash blk) !(HeaderHash blk)
- | OtherHeaderEnvelopeError !(OtherHeaderEnvelopeError blk)
- class (BasicEnvelopeValidation blk, GetPrevHash blk, Eq (OtherHeaderEnvelopeError blk), Show (OtherHeaderEnvelopeError blk), NoThunks (OtherHeaderEnvelopeError blk)) ⇒ ValidateEnvelope blk where
- type OtherHeaderEnvelopeError blk ∷ Type
- additionalEnvelopeChecks ∷ TopLevelConfig blk → LedgerView (BlockProtocol blk) → Header blk → Except (OtherHeaderEnvelopeError blk) ()
- castHeaderEnvelopeError ∷ (HeaderHash blk ~ HeaderHash blk', OtherHeaderEnvelopeError blk ~ OtherHeaderEnvelopeError blk') ⇒ HeaderEnvelopeError blk → HeaderEnvelopeError blk'
- data HeaderError blk
- = HeaderProtocolError !(ValidationErr (BlockProtocol blk))
- | HeaderEnvelopeError !(HeaderEnvelopeError blk)
- castHeaderError ∷ (ValidationErr (BlockProtocol blk) ~ ValidationErr (BlockProtocol blk'), HeaderHash blk ~ HeaderHash blk', OtherHeaderEnvelopeError blk ~ OtherHeaderEnvelopeError blk') ⇒ HeaderError blk → HeaderError blk'
- data TipInfoIsEBB blk = TipInfoIsEBB !(HeaderHash blk) !IsEBB
- decodeAnnTipIsEBB ∷ TipInfo blk ~ TipInfoIsEBB blk ⇒ (∀ s. Decoder s (HeaderHash blk)) → ∀ s. Decoder s (AnnTip blk)
- decodeHeaderState ∷ (∀ s. Decoder s (ChainDepState (BlockProtocol blk))) → (∀ s. Decoder s (AnnTip blk)) → ∀ s. Decoder s (HeaderState blk)
- defaultDecodeAnnTip ∷ TipInfo blk ~ HeaderHash blk ⇒ (∀ s. Decoder s (HeaderHash blk)) → ∀ s. Decoder s (AnnTip blk)
- defaultEncodeAnnTip ∷ TipInfo blk ~ HeaderHash blk ⇒ (HeaderHash blk → Encoding) → AnnTip blk → Encoding
- encodeAnnTipIsEBB ∷ TipInfo blk ~ TipInfoIsEBB blk ⇒ (HeaderHash blk → Encoding) → AnnTip blk → Encoding
- encodeHeaderState ∷ (ChainDepState (BlockProtocol blk) → Encoding) → (AnnTip blk → Encoding) → HeaderState blk → Encoding
- data family Ticked st ∷ Type
Documentation
revalidateHeader ∷ ∀ blk. (BlockSupportsProtocol blk, ValidateEnvelope blk, HasCallStack) ⇒ TopLevelConfig blk → LedgerView (BlockProtocol blk) → Header blk → Ticked (HeaderState blk) → HeaderState blk Source #
Header revalidation
Same as validateHeader
but used when the header has been validated before
w.r.t. the same exact HeaderState
.
Expensive validation checks are skipped (reupdateChainDepState
vs.
updateChainDepState
).
validateHeader ∷ (BlockSupportsProtocol blk, ValidateEnvelope blk) ⇒ TopLevelConfig blk → LedgerView (BlockProtocol blk) → Header blk → Ticked (HeaderState blk) → Except (HeaderError blk) (HeaderState blk) Source #
Header validation
Header validation (as opposed to block validation) is done by the chain sync client: as we download headers from other network nodes, we validate those headers before deciding whether or not to download the corresponding blocks.
Before we adopt any blocks we have downloaded, however, we will do a full block validation. As such, the header validation check can omit some checks (provided that we do those checks when we do the full validation); at worst, this would mean we might download some blocks that we will reject as being invalid where we could have detected that sooner.
For this reason, the header validation currently only checks two things:
- It verifies the consensus part of the header.
For example, for Praos this means checking the VRF proofs.
- It verifies the
HasHeader
part of the header.
By default, we verify that
- Block numbers are consecutive
- The block number of the first block is
firstBlockNo
- Slot numbers are strictly increasing
- The slot number of the first block is at least
minimumPossibleSlotNo
- Hashes line up
If a particular ledger wants to verify additional fields in the header, it
will get the chance to do so in applyBlockLedgerResult
, which is passed the
entire block (not just the block body).
Annotated tips
Annotated information about the tip of the chain
The annotation is the additional information we need to validate the header envelope. Under normal circumstances no additional information is required, but for instance for Byron we need to know if the previous header was an EBB.
AnnTip | |
|
Instances
class (StandardHash blk, Show (TipInfo blk), Eq (TipInfo blk), NoThunks (TipInfo blk)) ⇒ HasAnnTip blk where Source #
Nothing
getTipInfo ∷ Header blk → TipInfo blk Source #
Extract TipInfo
from a block header
default getTipInfo ∷ (TipInfo blk ~ HeaderHash blk, HasHeader (Header blk)) ⇒ Header blk → TipInfo blk Source #
tipInfoHash ∷ proxy blk → TipInfo blk → HeaderHash blk Source #
The tip info must at least include the hash
default tipInfoHash ∷ TipInfo blk ~ HeaderHash blk ⇒ proxy blk → TipInfo blk → HeaderHash blk Source #
Instances
CanHardFork xs ⇒ HasAnnTip (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block type TipInfo (HardForkBlock xs) Source # getTipInfo ∷ Header (HardForkBlock xs) → TipInfo (HardForkBlock xs) Source # tipInfoHash ∷ proxy (HardForkBlock xs) → TipInfo (HardForkBlock xs) → HeaderHash (HardForkBlock xs) Source # | |
Bridge m a ⇒ HasAnnTip (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual getTipInfo ∷ Header (DualBlock m a) → TipInfo (DualBlock m a) Source # tipInfoHash ∷ proxy (DualBlock m a) → TipInfo (DualBlock m a) → HeaderHash (DualBlock m a) Source # |
annTipHash ∷ ∀ blk. HasAnnTip blk ⇒ AnnTip blk → HeaderHash blk Source #
Header state
data HeaderState blk Source #
State required to validate the header
See validateHeader
for details
HeaderState | |
|
Instances
castHeaderState ∷ (Coercible (ChainDepState (BlockProtocol blk)) (ChainDepState (BlockProtocol blk')), TipInfo blk ~ TipInfo blk') ⇒ HeaderState blk → HeaderState blk' Source #
genesisHeaderState ∷ ChainDepState (BlockProtocol blk) → HeaderState blk Source #
headerStatePoint ∷ HasAnnTip blk ⇒ HeaderState blk → Point blk Source #
tickHeaderState ∷ ConsensusProtocol (BlockProtocol blk) ⇒ ConsensusConfig (BlockProtocol blk) → LedgerView (BlockProtocol blk) → SlotNo → HeaderState blk → Ticked (HeaderState blk) Source #
Tick the ChainDepState
inside the HeaderState
Validate header envelope
class (HasHeader (Header blk), HasAnnTip blk) ⇒ BasicEnvelopeValidation blk where Source #
Ledger-independent envelope validation (block, slot, hash)
Nothing
expectedFirstBlockNo ∷ proxy blk → BlockNo Source #
The block number of the first block on the chain
Next block number
minimumPossibleSlotNo ∷ Proxy blk → SlotNo Source #
The smallest possible SlotNo
NOTE: This does not affect the translation between SlotNo
and EpochNo
.
Ouroboros.Consensus.HardFork.History for details.
Minimum next slot number
Instances
CanHardFork xs ⇒ BasicEnvelopeValidation (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block expectedFirstBlockNo ∷ proxy (HardForkBlock xs) → BlockNo Source # expectedNextBlockNo ∷ proxy (HardForkBlock xs) → TipInfo (HardForkBlock xs) → TipInfo (HardForkBlock xs) → BlockNo → BlockNo Source # minimumPossibleSlotNo ∷ Proxy (HardForkBlock xs) → SlotNo Source # minimumNextSlotNo ∷ proxy (HardForkBlock xs) → TipInfo (HardForkBlock xs) → TipInfo (HardForkBlock xs) → SlotNo → SlotNo Source # | |
Bridge m a ⇒ BasicEnvelopeValidation (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual expectedFirstBlockNo ∷ proxy (DualBlock m a) → BlockNo Source # expectedNextBlockNo ∷ proxy (DualBlock m a) → TipInfo (DualBlock m a) → TipInfo (DualBlock m a) → BlockNo → BlockNo Source # minimumPossibleSlotNo ∷ Proxy (DualBlock m a) → SlotNo Source # minimumNextSlotNo ∷ proxy (DualBlock m a) → TipInfo (DualBlock m a) → TipInfo (DualBlock m a) → SlotNo → SlotNo Source # |
data HeaderEnvelopeError blk Source #
UnexpectedBlockNo !BlockNo !BlockNo | Invalid block number We record both the expected and actual block number |
UnexpectedSlotNo !SlotNo !SlotNo | Invalid slot number We record both the expected (minimum) and actual slot number |
UnexpectedPrevHash !(WithOrigin (HeaderHash blk)) !(ChainHash blk) | Invalid hash (in the reference to the previous block) We record the current tip as well as the prev hash of the new block. |
CheckpointMismatch !BlockNo !(HeaderHash blk) !(HeaderHash blk) | The block at the given block number has a hash which does not match the expected checkpoint hash. CheckpointMismatch blockNo expected actual |
OtherHeaderEnvelopeError !(OtherHeaderEnvelopeError blk) | Block specific envelope error |
Instances
class (BasicEnvelopeValidation blk, GetPrevHash blk, Eq (OtherHeaderEnvelopeError blk), Show (OtherHeaderEnvelopeError blk), NoThunks (OtherHeaderEnvelopeError blk)) ⇒ ValidateEnvelope blk where Source #
Validate header envelope
Nothing
type OtherHeaderEnvelopeError blk ∷ Type Source #
A block-specific error that validateEnvelope
can return.
type OtherHeaderEnvelopeError blk = Void
additionalEnvelopeChecks ∷ TopLevelConfig blk → LedgerView (BlockProtocol blk) → Header blk → Except (OtherHeaderEnvelopeError blk) () Source #
Do additional envelope checks
Instances
CanHardFork xs ⇒ ValidateEnvelope (HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Ledger type OtherHeaderEnvelopeError (HardForkBlock xs) Source # additionalEnvelopeChecks ∷ TopLevelConfig (HardForkBlock xs) → LedgerView (BlockProtocol (HardForkBlock xs)) → Header (HardForkBlock xs) → Except (OtherHeaderEnvelopeError (HardForkBlock xs)) () Source # | |
Bridge m a ⇒ ValidateEnvelope (DualBlock m a) Source # | |
Defined in Ouroboros.Consensus.Ledger.Dual type OtherHeaderEnvelopeError (DualBlock m a) Source # additionalEnvelopeChecks ∷ TopLevelConfig (DualBlock m a) → LedgerView (BlockProtocol (DualBlock m a)) → Header (DualBlock m a) → Except (OtherHeaderEnvelopeError (DualBlock m a)) () Source # |
castHeaderEnvelopeError ∷ (HeaderHash blk ~ HeaderHash blk', OtherHeaderEnvelopeError blk ~ OtherHeaderEnvelopeError blk') ⇒ HeaderEnvelopeError blk → HeaderEnvelopeError blk' Source #
Errors
data HeaderError blk Source #
Invalid header
HeaderProtocolError !(ValidationErr (BlockProtocol blk)) | Invalid consensus protocol fields |
HeaderEnvelopeError !(HeaderEnvelopeError blk) | Failed to validate the envelope |
Instances
castHeaderError ∷ (ValidationErr (BlockProtocol blk) ~ ValidationErr (BlockProtocol blk'), HeaderHash blk ~ HeaderHash blk', OtherHeaderEnvelopeError blk ~ OtherHeaderEnvelopeError blk') ⇒ HeaderError blk → HeaderError blk' Source #
TipInfoIsEBB
data TipInfoIsEBB blk Source #
Reusable strict data type for TipInfo
in case the TipInfo
should
contain IsEBB
in addition to the HeaderHash
.
TipInfoIsEBB !(HeaderHash blk) !IsEBB |
Instances
Serialization
decodeAnnTipIsEBB ∷ TipInfo blk ~ TipInfoIsEBB blk ⇒ (∀ s. Decoder s (HeaderHash blk)) → ∀ s. Decoder s (AnnTip blk) Source #
decodeHeaderState ∷ (∀ s. Decoder s (ChainDepState (BlockProtocol blk))) → (∀ s. Decoder s (AnnTip blk)) → ∀ s. Decoder s (HeaderState blk) Source #
defaultDecodeAnnTip ∷ TipInfo blk ~ HeaderHash blk ⇒ (∀ s. Decoder s (HeaderHash blk)) → ∀ s. Decoder s (AnnTip blk) Source #
defaultEncodeAnnTip ∷ TipInfo blk ~ HeaderHash blk ⇒ (HeaderHash blk → Encoding) → AnnTip blk → Encoding Source #
encodeAnnTipIsEBB ∷ TipInfo blk ~ TipInfoIsEBB blk ⇒ (HeaderHash blk → Encoding) → AnnTip blk → Encoding Source #
encodeHeaderState ∷ (ChainDepState (BlockProtocol blk) → Encoding) → (AnnTip blk → Encoding) → HeaderState blk → Encoding Source #
Type family instances
data family Ticked st ∷ Type Source #
" Ticked " piece of state, either LedgerState
or ChainDepState
Ticking refers to the passage of time (the ticking of the clock). When a
piece of state is marked as ticked, it means that time-related changes have
been applied to the state. There are exactly two methods in the interface
that do that: tickChainDepState
and
applyChainTickLedgerResult
.
Also note that a successful forecast
must equal
forecastFor
(ledgerViewForecastAt
cfg st)
slot
. Thus a
protocolLedgerView
cfg
(applyChainTick
cfg slot st)LedgerView
can only be projected
from a Ticked
state, but cannot itself be ticked.
Some examples of time related changes:
- Scheduled delegations might have been applied in Byron
- New leader schedule computed for Shelley
- Transition from Byron to Shelley activated in the hard fork combinator.
- Nonces switched out at the start of a new epoch.