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

Ouroboros.Consensus.Protocol.Abstract

Synopsis

Abstract definition of the Ouroboros protocol

class (Show (ChainDepState p), Show (ValidationErr p), Show (LedgerView p), Eq (ChainDepState p), Eq (ValidationErr p), NoThunks (ConsensusConfig p), NoThunks (ChainDepState p), NoThunks (ValidationErr p), Typeable p, ChainSelection p) => ConsensusProtocol p where Source #

The (open) universe of Ouroboros protocols

This class encodes the part that is independent from any particular block representation.

Associated Types

type ChainDepState p :: Type Source #

Protocol-specific state

NOTE: This chain is blockchain dependent, i.e., updated when new blocks come in (more precisely, new headers), and subject to rollback.

type IsLeader p :: Type Source #

Evidence that a node is the leader

type CanBeLeader p :: Type Source #

Evidence that we can be a leader

type LedgerView p :: Type Source #

Projection of the ledger state the Ouroboros protocol needs access to

The LedgerView is a summary of the state of the ledger that the consensus algorithm requires to do its job. Under certain circumstances the consensus algorithm may require the LedgerView for slots in the past (before the current tip of the chain) or in the (near) future (beyond the tip of the current chain, without having seen those future blocks yet).

This puts limitations on what the LedgerView can be. For example, it cannot be the "current stake distribution", since it is of course impossible to compute the current stake distibution for a slot in the future. This means that for a consensus algorithm that requires the stake distribution such as Praos, the LedgerView for a particular slot must be the "stake distribution for the purpose of leader selection". This "relevant" stake distribution can be computed for slots in the (near) future because it is based on historical stake, not current.

A somewhat unfortunate consequence of this is that some decisions that ought to live in the consensus layer (such as the decision precisely which historical stake to sample to determine the relevant stake distribution) instead live in the ledger layer. It is difficult to disentangle this, because the ledger may indeed depend on those sampling decisions (for example, reward calculations must be based on that same stake distribution).

There are also some advantages to moving these sorts of decisions to the ledger layer. It means that the consensus algorithm can continue to function without modifications if we decide that the stake distribution for leader selection should be based on something else instead (for example, for some bespoke version of the blockchain we may wish to use a committee instead of a decentralized blockchain). Having sampling decisions in the ledger layer rather than the consensus layer means that these decisions can be made without modifying the consensus algorithm.

Note that for the specific case of Praos, whilst the ledger layer provides the relevant stake distribution, the precise leader election must still live in the consensus layer since that depends on the computation (and sampling) of entropy, which is done consensus side, not ledger side (the reward calculation does not depend on this).

type ValidationErr p :: Type Source #

Validation errors

type ValidateView p :: Type Source #

View on a header required to validate it

Methods

chainSelConfig :: ConsensusConfig p -> ChainSelConfig p Source #

ConsensusConfig must include the ChainSelConfig p

checkIsLeader :: HasCallStack => ConsensusConfig p -> CanBeLeader p -> SlotNo -> Ticked (ChainDepState p) -> Maybe (IsLeader p) Source #

Check if a node is the leader

tickChainDepState :: ConsensusConfig p -> Ticked (LedgerView p) -> SlotNo -> ChainDepState p -> Ticked (ChainDepState p) Source #

Tick the ChainDepState

We pass the ticked LedgerView to tickChainDepState. Functions that take a ticked ChainDepState are not separately passed a ticked ledger view; protocols that require it, can include it in their ticked ChainDepState type.

updateChainDepState :: HasCallStack => ConsensusConfig p -> ValidateView p -> SlotNo -> Ticked (ChainDepState p) -> Except (ValidationErr p) (ChainDepState p) Source #

Apply a header

reupdateChainDepState :: HasCallStack => ConsensusConfig p -> ValidateView p -> SlotNo -> Ticked (ChainDepState p) -> ChainDepState p Source #

Re-apply a header to the same ChainDepState we have been able to successfully apply to before.

Since a header can only be applied to a single, specific, ChainDepState, if we apply a previously applied header again it will be applied in the very same ChainDepState, and therefore can't possibly fail.

It is worth noting that since we already know that the header is valid w.r.t. the provided ChainDepState, no validation checks should be performed.

protocolSecurityParam :: ConsensusConfig p -> SecurityParam Source #

We require that protocols support a k security parameter

Instances

Instances details
ConsensusProtocol p => ConsensusProtocol (WithLeaderSchedule p) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.LeaderSchedule

BftCrypto c => ConsensusProtocol (Bft c) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.BFT

Associated Types

type ChainDepState (Bft c) Source #

type IsLeader (Bft c) Source #

type CanBeLeader (Bft c) Source #

type LedgerView (Bft c) Source #

type ValidationErr (Bft c) Source #

type ValidateView (Bft c) Source #

CanHardFork xs => ConsensusProtocol (HardForkProtocol xs) Source # 
Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Protocol

PBftCrypto c => ConsensusProtocol (PBft c) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.PBFT

(Typeable p, Typeable s, ConsensusProtocol p, ChainSelection s) => ConsensusProtocol (ModChainSel p s) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.ModChainSel

class (NoThunks (ChainSelConfig p), Show (SelectView p), Show (ChainSelConfig p), Eq (ChainSelConfig p)) => ChainSelection p where Source #

Chain selection

Minimal complete definition

Nothing

Associated Types

type ChainSelConfig p :: Type Source #

Configuration required for chain selection

type ChainSelConfig p = ()

type SelectView p :: Type Source #

View on a header required for chain selection

Methods

preferCandidate Source #

Arguments

:: proxy p 
-> ChainSelConfig p 
-> SelectView p

Tip of our chain

-> SelectView p

Tip of the candidate

-> Bool 

Do we prefer the candidate chain over ours?

Should return True when we prefer the candidate over our chain.

We pass only the tips of the chains; for all consensus protocols we are interested in, this provides sufficient context. (Ouroboros Genesis is the only exception, but we will handle the genesis rule elsewhere.)

PRECONDITIONS:

  • The candidate chain does not extend into the future.
  • The candidate must intersect with our chain within k blocks from our tip.

NOTE: An assumption that is quite deeply ingrained in the design of the consensus layer is that if a chain can be extended, it always should (e.g., see the chain database spec in ChainDB.md). This means that any chain is always preferred over the empty chain, and preferCandidate does not need (indeed, cannot) be called if our current chain is empty.

compareCandidates :: proxy p -> ChainSelConfig p -> SelectView p -> SelectView p -> Ordering Source #

Compare two candidates, both of which we prefer to our own chain

PRECONDITION: both candidates must be preferred to our own chain

Instances

Instances details
ChainSelection p => ChainSelection (WithLeaderSchedule p) Source #

Chain selection is unchanged

Instance details

Defined in Ouroboros.Consensus.Protocol.LeaderSchedule

ChainSelection (Bft c) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.BFT

Associated Types

type ChainSelConfig (Bft c) Source #

type SelectView (Bft c) Source #

Methods

preferCandidate :: proxy (Bft c) -> ChainSelConfig (Bft c) -> SelectView (Bft c) -> SelectView (Bft c) -> Bool Source #

compareCandidates :: proxy (Bft c) -> ChainSelConfig (Bft c) -> SelectView (Bft c) -> SelectView (Bft c) -> Ordering Source #

CanHardFork xs => ChainSelection (HardForkProtocol xs) Source #

Chain selection across eras

Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Protocol

PBftCrypto c => ChainSelection (PBft c) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.PBFT

Associated Types

type ChainSelConfig (PBft c) Source #

type SelectView (PBft c) Source #

ChainSelection s => ChainSelection (ModChainSel p s) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.ModChainSel

Associated Types

type ChainSelConfig (ModChainSel p s) Source #

type SelectView (ModChainSel p s) Source #

data family ConsensusConfig p :: Type Source #

Static configuration required to run the consensus protocol

Every method in the ConsensusProtocol class takes the consensus configuration as a parameter, so having this as a data family rather than a type family resolves most ambiguity.

Defined out of the class so that protocols can define this type without having to define the entire protocol at the same time (or indeed in the same module).

Instances

Instances details
Generic (ConsensusConfig (ModChainSel p s)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.ModChainSel

Associated Types

type Rep (ConsensusConfig (ModChainSel p s)) :: Type -> Type #

Generic (ConsensusConfig (WithLeaderSchedule p)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.LeaderSchedule

Associated Types

type Rep (ConsensusConfig (WithLeaderSchedule p)) :: Type -> Type #

Generic (ConsensusConfig (Bft c)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.BFT

Associated Types

type Rep (ConsensusConfig (Bft c)) :: Type -> Type #

Generic (ConsensusConfig (HardForkProtocol xs)) Source # 
Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Basics

Associated Types

type Rep (ConsensusConfig (HardForkProtocol xs)) :: Type -> Type #

Generic (ConsensusConfig (PBft c)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.PBFT

Associated Types

type Rep (ConsensusConfig (PBft c)) :: Type -> Type #

(ConsensusProtocol p, ChainSelection s) => NoThunks (ConsensusConfig (ModChainSel p s)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.ModChainSel

ConsensusProtocol p => NoThunks (ConsensusConfig (WithLeaderSchedule p)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.LeaderSchedule

BftCrypto c => NoThunks (ConsensusConfig (Bft c)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.BFT

CanHardFork xs => NoThunks (ConsensusConfig (HardForkProtocol xs)) Source # 
Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Basics

NoThunks (ConsensusConfig (PBft c)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.PBFT

type Rep (ConsensusConfig (ModChainSel p s)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.ModChainSel

type Rep (ConsensusConfig (ModChainSel p s)) = D1 ('MetaData "ConsensusConfig" "Ouroboros.Consensus.Protocol.ModChainSel" "ouroboros-consensus-0.1.0.0-GfJNvFcM6lj2s5utKAUPEp" 'False) (C1 ('MetaCons "McsConsensusConfig" 'PrefixI 'True) (S1 ('MetaSel ('Just "mcsConfigS") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ChainSelConfig s)) :*: S1 ('MetaSel ('Just "mcsConfigP") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ConsensusConfig p))))
type Rep (ConsensusConfig (WithLeaderSchedule p)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.LeaderSchedule

type Rep (ConsensusConfig (WithLeaderSchedule p)) = D1 ('MetaData "ConsensusConfig" "Ouroboros.Consensus.Protocol.LeaderSchedule" "ouroboros-consensus-0.1.0.0-GfJNvFcM6lj2s5utKAUPEp" 'False) (C1 ('MetaCons "WLSConfig" 'PrefixI 'True) (S1 ('MetaSel ('Just "wlsConfigSchedule") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 LeaderSchedule) :*: (S1 ('MetaSel ('Just "wlsConfigP") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (ConsensusConfig p)) :*: S1 ('MetaSel ('Just "wlsConfigNodeId") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 CoreNodeId))))
type Rep (ConsensusConfig (Bft c)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.BFT

type Rep (ConsensusConfig (Bft c)) = D1 ('MetaData "ConsensusConfig" "Ouroboros.Consensus.Protocol.BFT" "ouroboros-consensus-0.1.0.0-GfJNvFcM6lj2s5utKAUPEp" 'False) (C1 ('MetaCons "BftConfig" 'PrefixI 'True) (S1 ('MetaSel ('Just "bftParams") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 BftParams) :*: (S1 ('MetaSel ('Just "bftSignKey") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (SignKeyDSIGN (BftDSIGN c))) :*: S1 ('MetaSel ('Just "bftVerKeys") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Map NodeId (VerKeyDSIGN (BftDSIGN c)))))))
type Rep (ConsensusConfig (HardForkProtocol xs)) Source # 
Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Basics

type Rep (ConsensusConfig (HardForkProtocol xs)) = D1 ('MetaData "ConsensusConfig" "Ouroboros.Consensus.HardFork.Combinator.Basics" "ouroboros-consensus-0.1.0.0-GfJNvFcM6lj2s5utKAUPEp" 'False) (C1 ('MetaCons "HardForkConsensusConfig" 'PrefixI 'True) (S1 ('MetaSel ('Just "hardForkConsensusConfigK") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 SecurityParam) :*: (S1 ('MetaSel ('Just "hardForkConsensusConfigShape") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Shape xs)) :*: S1 ('MetaSel ('Just "hardForkConsensusConfigPerEra") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (PerEraConsensusConfig xs)))))
type Rep (ConsensusConfig (PBft c)) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.PBFT

type Rep (ConsensusConfig (PBft c)) = D1 ('MetaData "ConsensusConfig" "Ouroboros.Consensus.Protocol.PBFT" "ouroboros-consensus-0.1.0.0-GfJNvFcM6lj2s5utKAUPEp" 'False) (C1 ('MetaCons "PBftConfig" 'PrefixI 'True) (S1 ('MetaSel ('Just "pbftParams") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 PBftParams)))
data ConsensusConfig (WithLeaderSchedule p) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.LeaderSchedule

data ConsensusConfig (Bft c) Source #

(Static) node configuration

Instance details

Defined in Ouroboros.Consensus.Protocol.BFT

data ConsensusConfig (HardForkProtocol xs) Source # 
Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Basics

data ConsensusConfig (PBft c) Source #

(Static) node configuration

Instance details

Defined in Ouroboros.Consensus.Protocol.PBFT

data ConsensusConfig (ModChainSel p s) Source # 
Instance details

Defined in Ouroboros.Consensus.Protocol.ModChainSel

Convenience re-exports

newtype SecurityParam Source #

Protocol security parameter

We interpret this as the number of rollbacks we support.

i.e., k == 0: we can't roll back at all k == 1: we can roll back at most one block, etc

NOTE: This talks about the number of blocks we can roll back, not the number of slots.

Constructors

SecurityParam 

Fields

Instances

Instances details
Eq SecurityParam Source # 
Instance details

Defined in Ouroboros.Consensus.Config.SecurityParam

Show SecurityParam Source # 
Instance details

Defined in Ouroboros.Consensus.Config.SecurityParam

Generic SecurityParam Source # 
Instance details

Defined in Ouroboros.Consensus.Config.SecurityParam

Associated Types

type Rep SecurityParam :: Type -> Type #

NoThunks SecurityParam Source # 
Instance details

Defined in Ouroboros.Consensus.Config.SecurityParam

type Rep SecurityParam Source # 
Instance details

Defined in Ouroboros.Consensus.Config.SecurityParam

type Rep SecurityParam = D1 ('MetaData "SecurityParam" "Ouroboros.Consensus.Config.SecurityParam" "ouroboros-consensus-0.1.0.0-GfJNvFcM6lj2s5utKAUPEp" 'True) (C1 ('MetaCons "SecurityParam" 'PrefixI 'True) (S1 ('MetaSel ('Just "maxRollbacks") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Word64)))