ouroboros-consensus-0.21.0.0: Consensus layer for the Ouroboros blockchain protocol
Safe HaskellSafe-Inferred
LanguageHaskell2010

Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Description

The ChainSync client logic

Its core specification is found in "The Shelley Networking Protocol", currently found at https://ouroboros-network.cardano.intersectmbo.org/pdfs/network-spec/network-spec.pdf.

It would be difficult to maintain or extrend this module without understanding the typed-protocols architecture; eg see https://github.com/input-output-hk/typed-protocols.

This module is intended for qualified import, aliased as either CSC, CSClient, or CsClient.

Synopsis

ChainSync client

bracketChainSyncClient Source #

Arguments

∷ ∀ m peer blk a. (IOLike m, Ord peer, LedgerSupportsProtocol blk, MonadTimer m) 
Tracer m (TraceChainSyncClientEvent blk) 
ChainDbView m blk 
StrictTVar m (Map peer (ChainSyncClientHandle m blk))

The kill handle and states for each peer, we need the whole map because we (de)register nodes (peer).

STM m GsmState

A function giving the current GSM state; only used at startup.

→ peer 
NodeToNodeVersion 
ChainSyncLoPBucketConfig 
CSJConfig 
DiffusionPipeliningSupport 
→ (ChainSyncStateView m blk → m a) 
→ m a 

chainSyncClient ∷ ∀ m blk. (IOLike m, LedgerSupportsProtocol blk) ⇒ ConfigEnv m blk → DynamicEnv m blk → Consensus ChainSyncClientPipelined blk m Source #

Chain sync client

This never terminates. In case of a failure, a ChainSyncClientException is thrown. The network layer classifies exception such that the corresponding peer will never be chosen again.

Arguments

data ChainDbView m blk Source #

Abstract over the ChainDB

data ConfigEnv m blk Source #

Arguments determined by configuration

These are available before the diffusion layer is online.

data DynamicEnv m blk Source #

Arguments determined dynamically

These are available only after the diffusion layer is online and/or on per client basis.

data InternalEnv m blk arrival judgment Source #

General values collectively needed by the top-level entry points

Constructors

InternalEnv 

Fields

Results

data ChainSyncClientException Source #

When the upstream node violates the protocol or exhibits malicious behaviour, e.g., serving an invalid header or a header corresponding to a known invalid block, we throw an exception to disconnect. This will bring down all miniprotocols in both directions with that node.

Constructors

∀ blk.(BlockSupportsProtocol blk, ValidateEnvelope blk) ⇒ HeaderError 

Fields

∀ blk.BlockSupportsProtocol blk ⇒ InvalidIntersection 

Fields

  • (Point blk)

    Intersection

  • (Our (Tip blk))
     
  • (Their (Tip blk))

    We send the upstream node a bunch of points from a chain fragment and the upstream node responded with an intersection point that is not on our chain fragment, and thus not among the points we sent.

    We store the intersection point the upstream node sent us.

∀ blk.LedgerSupportsProtocol blk ⇒ InvalidBlock 

Fields

  • (Point blk)

    Block that triggered the validity check.

  • (HeaderHash blk)

    Invalid block. If pipelining was negotiated, this can be different from the previous argument.

  • (ExtValidationError blk)

    The upstream node's chain contained a block that we know is invalid.

InFutureHeaderExceedsClockSkew !HeaderArrivalException

A header arrived from the far future.

HistoricityError !HistoricityException 
EmptyBucket

The peer lost its race against the bucket.

InvalidJumpResponse

When the peer responded incorrectly to a jump request.

DensityTooLow

The peer has been deemed unworthy by the GDD

data ChainSyncClientResult Source #

The Chain sync client only _gracefully_ terminates when the upstream node's chain is not interesting (e.g., forked off too far in the past). By gracefully terminating, the network layer can keep the other mini-protocols connect to the same upstream node running.

For example, a relay node will often receive connections from nodes syncing from scratch or an old chain. Since these nodes have a chain that is shorter than the relay node's chain, it's useless for the relay node to run the client-side of the chain sync protocol. However, the other direction of the protocol, and, e.g., the transaction submission protocol, should keep running.

Constructors

∀ blk.BlockSupportsProtocol blk ⇒ ForkTooDeep 

Fields

  • (Point blk)

    Intersection

  • (Our (Tip blk))
     
  • (Their (Tip blk))

    The server we're connecting to forked more than k blocks ago.

∀ blk.BlockSupportsProtocol blk ⇒ NoMoreIntersection (Our (Tip blk)) (Their (Tip blk))

Our chain changed such that it no longer intersects with the candidate's fragment, and asking for a new intersection did not yield one.

∀ blk.BlockSupportsProtocol blk ⇒ RolledBackPastIntersection 

Fields

  • (Point blk)

    Point asked to roll back to

  • (Our (Tip blk))
     
  • (Their (Tip blk))

    We were asked to roll back past the anchor point of the candidate's fragment. This means the candidate chain no longer forks off within k, making it impossible to switch to.

AskedToTerminate

We were asked to terminate via the ControlMessageSTM

Misc

type Consensus (client ∷ TypeTypeType → (TypeType) → TypeType) blk m = client (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult Source #

Merely a helpful abbreviation

newtype Our a Source #

A newtype wrapper to avoid confusing our tip with their tip.

Constructors

Our 

Fields

Instances

Instances details
Show a ⇒ Show (Our a) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Methods

showsPrecIntOur a → ShowS #

showOur a → String #

showList ∷ [Our a] → ShowS #

Eq a ⇒ Eq (Our a) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Methods

(==)Our a → Our a → Bool #

(/=)Our a → Our a → Bool #

NoThunks a ⇒ NoThunks (Our a) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

newtype Their a Source #

A newtype wrapper to avoid confusing our tip with their tip.

Constructors

Their 

Fields

Instances

Instances details
Show a ⇒ Show (Their a) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Methods

showsPrecIntTheir a → ShowS #

showTheir a → String #

showList ∷ [Their a] → ShowS #

Eq a ⇒ Eq (Their a) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Methods

(==)Their a → Their a → Bool #

(/=)Their a → Their a → Bool #

NoThunks a ⇒ NoThunks (Their a) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Genesis configuration

data CSJConfig Source #

Configuration of ChainSync Jumping

Constructors

CSJDisabled

Disable ChainSync Jumping. All clients will fully synchronize with the chain of its peer.

CSJEnabled CSJEnabledConfig

Enable ChainSync Jumping

newtype CSJEnabledConfig Source #

Constructors

CSJEnabledConfig 

Fields

  • csjcJumpSizeSlotNo

    The _ideal_ size for ChainSync jumps. Note that the algorithm is best-effort: there might not be exactly $sel:csjcJumpSize:CSJEnabledConfig slots between two jumps, depending on the chain.

    There can be a few less slots between jumps if there is not a block exactly at the boundary. Jumps are often made when a block is announced after the jump boundary.

    There can be even less slots if a dynamo is elected and it requires an initial jump regardless of how far we are from the next jump boundary.

    csjcJumpSize must be greater than 0 and smaller or equal to the genesis window size. The larger the jump size, the less jumps are made and peers are less involved in the syncing. A jump size as large as the genesis window has a higher change that dishonest peers can delay syncing by a small margin (around 2 minutes per dishonest peer with mainnet parameters).

data ChainSyncLoPBucketConfig Source #

Configuration of the leaky bucket.

Constructors

ChainSyncLoPBucketDisabled

Fully disable the leaky bucket. The background thread that is used to run it will not even be started.

ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig

Enable the leaky bucket.

data ChainSyncLoPBucketEnabledConfig Source #

Configuration of the leaky bucket when it is enabled.

Constructors

ChainSyncLoPBucketEnabledConfig 

Fields

Trace events

data TraceChainSyncClientEvent blk Source #

Events traced by the Chain Sync Client.

Constructors

TraceDownloadedHeader (Header blk)

While following a candidate chain, we rolled forward by downloading a header.

TraceRolledBack (Point blk)

While following a candidate chain, we rolled back to the given point.

TraceFoundIntersection (Point blk) (Our (Tip blk)) (Their (Tip blk))

We found an intersection between our chain fragment and the candidate's chain.

TraceException ChainSyncClientException

An exception was thrown by the Chain Sync Client.

TraceTermination ChainSyncClientResult

The client has terminated.

TraceValidatedHeader (Header blk)

We have validated the given header.

TraceWaitingBeyondForecastHorizon SlotNo

The SlotNo is beyond the forecast horizon, the ChainSync client cannot yet validate a header in this slot and therefore is waiting.

TraceAccessingForecastHorizon SlotNo

The SlotNo, which was previously beyond the forecast horizon, has now entered it, and we can resume processing.

TraceGaveLoPToken Bool (Header blk) BlockNo

Whether we added a token to the LoP bucket of the peer. Also carries the considered header and the best block number known prior to this header.

TraceOfferJump (Point blk)

ChainSync Jumping offering a point to jump to.

TraceJumpResult (JumpResult blk)

ChainSync Jumping -- reply.

TraceJumpingWaitingForNextInstruction

ChainSync Jumping -- the ChainSync client is requesting the next instruction.

TraceJumpingInstructionIs (Instruction blk)

ChainSync Jumping -- the ChainSync client got its next instruction.

State shared with other components

data ChainSyncClientHandle m blk Source #

An interface to a ChainSync client that's used by other components, like the GDD governor.

Constructors

ChainSyncClientHandle 

Fields

Instances

Instances details
Generic (ChainSyncClientHandle m blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State

Associated Types

type Rep (ChainSyncClientHandle m blk) ∷ TypeType #

(IOLike m, HasHeader blk, LedgerSupportsProtocol blk, NoThunks (Header blk)) ⇒ NoThunks (ChainSyncClientHandle m blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State

type Rep (ChainSyncClientHandle m blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State

type Rep (ChainSyncClientHandle m blk) = D1 ('MetaData "ChainSyncClientHandle" "Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State" "ouroboros-consensus-0.21.0.0-inplace" 'False) (C1 ('MetaCons "ChainSyncClientHandle" 'PrefixI 'True) ((S1 ('MetaSel ('Just "cschGDDKill") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (m ())) :*: S1 ('MetaSel ('Just "cschOnGsmStateChanged") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (GsmStateTimeSTM m ()))) :*: (S1 ('MetaSel ('Just "cschState") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (StrictTVar m (ChainSyncState blk))) :*: (S1 ('MetaSel ('Just "cschJumping") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (StrictTVar m (ChainSyncJumpingState m blk))) :*: S1 ('MetaSel ('Just "cschJumpInfo") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (StrictTVar m (Maybe (JumpInfo blk))))))))

data ChainSyncState blk Source #

A ChainSync client's state that's used by other components, like the GDD or the jumping governor.

Constructors

ChainSyncState 

Fields

  • csCandidate ∷ !(AnchoredFragment (Header blk))

    The current candidate fragment.

  • csIdling ∷ !Bool

    Whether the last message sent by the peer was MsgAwaitReply.

    This ChainSync client should ensure that its peer sets this flag while and only while both of the following conditions are satisfied: the peer's latest message has been fully processed (especially that its candidate has been updated; previous argument) and its latest message did not claim that it already has headers that extend its candidate.

    It's more important that the flag is unset promptly than it is for the flag to be set promptly, because of how this is used by the GSM to determine that the node is done syncing.

  • csLatestSlot ∷ !(StrictMaybe (WithOrigin SlotNo))

    When the client receives a new header, it updates this field before processing it further, and the latest slot may refer to a header beyond the forecast horizon while the candidate fragment isn't extended yet, to signal to GDD that the density is known up to this slot.

Instances

Instances details
Generic (ChainSyncState blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State

Associated Types

type Rep (ChainSyncState blk) ∷ TypeType #

Methods

fromChainSyncState blk → Rep (ChainSyncState blk) x #

toRep (ChainSyncState blk) x → ChainSyncState blk #

(HasHeader blk, NoThunks (Header blk)) ⇒ NoThunks (ChainSyncState blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State

type Rep (ChainSyncState blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State

type Rep (ChainSyncState blk) = D1 ('MetaData "ChainSyncState" "Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State" "ouroboros-consensus-0.21.0.0-inplace" 'False) (C1 ('MetaCons "ChainSyncState" 'PrefixI 'True) (S1 ('MetaSel ('Just "csCandidate") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (AnchoredFragment (Header blk))) :*: (S1 ('MetaSel ('Just "csIdling") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: S1 ('MetaSel ('Just "csLatestSlot") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (StrictMaybe (WithOrigin SlotNo))))))

data ChainSyncStateView m blk Source #

Interface for the ChainSync client to its state allocated by bracketChainSyncClient.

Constructors

ChainSyncStateView 

Fields

Instances

Instances details
Generic (ChainSyncStateView m blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

Associated Types

type Rep (ChainSyncStateView m blk) ∷ TypeType #

Methods

fromChainSyncStateView m blk → Rep (ChainSyncStateView m blk) x #

toRep (ChainSyncStateView m blk) x → ChainSyncStateView m blk #

(IOLike m, HasHeader blk, NoThunks (Header blk)) ⇒ NoThunks (ChainSyncStateView m blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

type Rep (ChainSyncStateView m blk) Source # 
Instance details

Defined in Ouroboros.Consensus.MiniProtocol.ChainSync.Client

type Rep (ChainSyncStateView m blk)

noJumpingMonadSTM m ⇒ Jumping m blk Source #

No-op implementation of CSJ

chainSyncStateForOrd peer ⇒ IOLike m ⇒ StrictTVar m (Map peer (ChainSyncClientHandle m blk)) → peer → STM m (ChainSyncState blk) Source #

Convenience function for reading the ChainSyncState for a single peer from a nested set of TVars.

noIdlingApplicative m ⇒ Idling m Source #

No-op implementation, for tests.

noLoPBucketApplicative m ⇒ LoPBucket m Source #

No-op implementation, for tests.

viewChainSyncStateIOLike m ⇒ StrictTVar m (Map peer (ChainSyncClientHandle m blk)) → (ChainSyncState blk → a) → STM m (Map peer a) Source #

Convenience function for reading a nested set of TVars and extracting some data from ChainSyncState.