protocol

package
v0.10.1-consensus-desr... Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2020 License: AGPL-3.0 Imports: 5 Imported by: 55

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsIdentityNotFound

func IsIdentityNotFound(err error) bool

Types

type Cluster

type Cluster interface {

	// Index returns the index for this cluster.
	Index() uint

	// ChainID returns chain ID for the cluster's chain.
	ChainID() flow.ChainID

	// EpochCounter returns the epoch counter for this cluster.
	EpochCounter() uint64

	// Members returns the initial set of collector nodes in this cluster.
	Members() flow.IdentityList

	// RootBlock returns the root block for this cluster.
	RootBlock() *cluster.Block

	// RootQC returns the quorum certificate for this cluster.
	RootQC() *flow.QuorumCertificate
}

Cluster represents the detailed information for a particular cluster, for a given epoch. This information represents the INITIAL state of the cluster, as defined by the Epoch Preparation Protocol. It DOES NOT take into account state changes over the course of the epoch (ie. slashing).

type Consumer

type Consumer interface {

	// BlockFinalized is called when a block is finalized.
	// Formally, this callback is informationally idempotent. I.e. the consumer
	// of this callback must handle repeated calls for the same block.
	BlockFinalized(block *flow.Header)

	// BlockProcessable is called when a correct block is encountered
	// that is ready to be processed (i.e. it is connected to the finalized
	// chain and its source of randomness is available).
	// Formally, this callback is informationally idempotent. I.e. the consumer
	// of this callback must handle repeated calls for the same block.
	BlockProcessable(block *flow.Header)

	// EpochTransition is called when we transition to a new epoch. This is
	// equivalent to the beginning of the new epoch's staking phase and the end
	// of the previous epoch's epoch committed phase.
	//
	// The block parameter is the first block of the new epoch.
	//
	// NOTE: Only called once the transition has been finalized.
	EpochTransition(newEpoch uint64, first *flow.Header)

	// EpochSetupPhaseStarted is called when we begin the epoch setup phase for
	// the current epoch. This is equivalent to the end of the epoch staking
	// phase for the current epoch.
	//
	// Referencing the diagram below, the event is emitted when block c is incorporated.
	// The block parameter is the first block of the epoch setup phase (block b).
	//
	// |<-- Epoch N ------------------------------------------------->|
	// |<-- StakingPhase -->|<-- SetupPhase -->|<-- CommittedPhase -->|
	//                    ^--- block A - this block's execution result contains an EpochSetup event
	//                      ^--- block b - contains seal for block A, first block of Setup phase
	//                         ^--- block c - finalizes block b and triggers `EpochSetupPhaseStarted`
	//
	// NOTE: Only called once the phase transition has been finalized.
	EpochSetupPhaseStarted(epoch uint64, first *flow.Header)

	// EpochCommittedPhase is called when we begin the epoch committed phase
	// for the current epoch. This is equivalent to the end of the epoch setup
	// phase for the current epoch.
	//
	// Referencing the diagram below, the event is emitted when block f is received.
	// The block parameter is the first block of the epoch committed phase (block e).
	//
	// |<-- Epoch N ------------------------------------------------->|
	// |<-- StakingPhase -->|<-- SetupPhase -->|<-- CommittedPhase -->|
	//                                       ^--- block D - this block's execution result contains an EpochCommit event
	//                                         ^--- block e - contains seal for block D, first block of Committed phase
	//                                            ^--- block f - this block finalizes block e, and triggers `EpochCommittedPhaseStarted`
	///
	//
	// NOTE: Only called once the phase transition has been finalized.
	EpochCommittedPhaseStarted(epoch uint64, first *flow.Header)
}

Consumer defines a set of events that occur within the protocol state, that can be propagated to other components via an implementation of this interface. Consumer implementations must be non-blocking.

NOTE: the epoch-related callbacks are only called once the fork containing the relevant event has been finalized.

type DKG

type DKG interface {

	// Size is the number of members in the DKG.
	Size() uint

	// GroupKey is the group public key.
	GroupKey() crypto.PublicKey

	// Index returns the index for the given node.
	Index(nodeID flow.Identifier) (uint, error)

	// KeyShare returns the public key share for the given node.
	KeyShare(nodeID flow.Identifier) (crypto.PublicKey, error)
}

DKG represents the result of running the distributed key generation procedure for the random beacon.

type Epoch

type Epoch interface {

	// Counter returns the Epoch's counter.
	Counter() (uint64, error)

	// FinalView returns the largest view number which still belongs to this epoch.
	FinalView() (uint64, error)

	// Seed generates a random seed using the source of randomness for this
	// epoch, specified in the EpochSetup service event.
	Seed(indices ...uint32) ([]byte, error)

	// InitialIdentities returns the identities for this epoch as they were
	// specified in the EpochSetup service event.
	InitialIdentities() (flow.IdentityList, error)

	// Clustering returns the cluster assignment for this epoch.
	Clustering() (flow.ClusterList, error)

	// Cluster returns the detailed cluster information for the cluster with the
	// given index, in this epoch.
	Cluster(index uint) (Cluster, error)

	// DKG returns the result of the distributed key generation procedure.
	DKG() (DKG, error)
}

Epoch contains the information specific to a certain Epoch (defined by the epoch Counter). Note that the Epoch preparation can differ along different forks, since the emission of service events is fork-dependent. Therefore, an epoch exists RELATIVE to the snapshot from which it was queried.

CAUTION: Clients must ensure to query epochs only for finalized blocks to ensure they query finalized epoch information.

An Epoch instance is constant and reports the identical information even if progress is made later and more information becomes available in subsequent blocks.

Methods error if epoch preparation has not progressed far enough for this information to be determined by a finalized block.

type EpochQuery

type EpochQuery interface {

	// Current returns the current epoch as of this snapshot.
	Current() Epoch

	// Next returns the next epoch as of this snapshot.
	Next() Epoch

	// ByCounter returns an arbitrary epoch by counter.
	ByCounter(counter uint64) Epoch
}

EpochQuery defines the different ways to query for epoch information given a Snapshot. It only exists to simplify the main Snapshot interface.

type IdentityNotFoundErr

type IdentityNotFoundErr struct {
	NodeID flow.Identifier
}

func (IdentityNotFoundErr) Error

func (e IdentityNotFoundErr) Error() string

type Mutator

type Mutator interface {

	// Bootstrap initializes the persistent protocol state with the given block,
	// execution state and block seal. In order to successfully bootstrap, the
	// execution result needs to refer to the provided block and the block seal
	// needs to refer to the provided block and execution result. The identities
	// in the block payload will be used as the initial set of staked node
	// identities.
	Bootstrap(root *flow.Block, result *flow.ExecutionResult, seal *flow.Seal) error

	// Extend introduces the block with the given ID into the persistent
	// protocol state without modifying the current finalized state. It allows
	// us to execute fork-aware queries against ambiguous protocol state, while
	// still checking that the given block is a valid extension of the protocol
	// state.
	Extend(block *flow.Block) error

	// HeaderExtend is a lighter version of Extend that checks whether the given
	// block is a valid extension of the protocol state by checking only the block
	// header.
	// Useful for consensus follower to check the block with lower cost, and
	// rely on consensus participants for the full block check, including the block
	// payload
	HeaderExtend(block *flow.Block) error

	// Finalize finalizes the block with the given hash.
	// At this level, we can only finalize one block at a time. This implies
	// that the parent of the pending block that is to be finalized has
	// to be the last finalized block.
	// It modifies the persistent immutable protocol state accordingly and
	// forwards the pointer to the latest finalized state.
	Finalize(blockID flow.Identifier) error

	// MarkValid marks the block header with the given block hash as valid.
	// At this level, we can only mark one block at a time as valid. This
	// implies that the parent of the block to be marked as valid
	// has to be already valid.
	// It modifies the persistent immutable protocol state accordingly.
	MarkValid(blockID flow.Identifier) error
}

Mutator represents an interface to modify the persistent protocol state in a way that conserves its integrity. It enforces a number of invariants on the input data that ensures the internal bookkeeping mechanisms remain functional and valid.

type Params

type Params interface {

	// ChainID returns the chain ID for the current consensus state.
	ChainID() (flow.ChainID, error)

	// Root returns the root header of the current consensus state.
	Root() (*flow.Header, error)

	// Seal returns the root block seal of the current consensus state.
	Seal() (*flow.Seal, error)
}

type ReadOnlyState

type ReadOnlyState interface {

	// Params gives access to a number of stable parameters of the protocol state.
	Params() Params

	// Final returns the snapshot of the persistent protocol state at the latest
	// finalized block, and the returned snapshot is therefore immutable over
	// time.
	Final() Snapshot

	// Sealed returns the snapshot of the persistent protocol state at the
	// latest sealed block, and the returned snapshot is therefore immutable
	// over time.
	Sealed() Snapshot

	// AtHeight returns the snapshot of the persistent protocol state at the
	// given block number. It is only available for finalized blocks and the
	// returned snapshot is therefore immutable over time.
	AtHeight(height uint64) Snapshot

	// AtBlockID returns the snapshot of the persistent protocol state at the
	// given block ID. It is available for any block that was introduced into
	// the protocol state, and can thus represent an ambiguous state that was or
	// will never be finalized.
	AtBlockID(blockID flow.Identifier) Snapshot
}

ReadOnlyState represents the full protocol state of the local node. It allows us to obtain snapshots of the state at any point of the protocol state history.

type Snapshot

type Snapshot interface {

	// Head returns the latest block at the selected point of the protocol state
	// history. It can represent either a finalized or ambiguous block,
	// depending on our selection criteria. Either way, it's the block on which
	// we should build the next block in the context of the selected state.
	Head() (*flow.Header, error)

	// Identities returns a list of identities at the selected point of
	// the protocol state history. It allows us to provide optional upfront
	// filters which can be used by the implementation to speed up database
	// lookups.
	Identities(selector flow.IdentityFilter) (flow.IdentityList, error)

	// Identity attempts to retrieve the node with the given identifier at the
	// selected point of the protocol state history. It will error if it doesn't exist.
	Identity(nodeID flow.Identifier) (*flow.Identity, error)

	// Commit return the sealed execution state commitment at this block.
	Commit() (flow.StateCommitment, error)

	// Pending returns the IDs of all descendants of the Head block. The IDs
	// are ordered such that parents are included before their children. These
	// are NOT guaranteed to have been validated by HotStuff.
	Pending() ([]flow.Identifier, error)

	// Seed returns a deterministic seed for a pseudo random number generator.
	// The seed is derived from the source of randomness for the Head block.
	// In order to deterministically derive task specific seeds, indices must
	// be specified. Refer to module/indices/rand.go for different indices.
	// NOTE: not to be confused with the epoch source of randomness!
	Seed(indices ...uint32) ([]byte, error)

	// Phase returns the epoch phase for the current epoch, as of the Head block.
	Phase() (flow.EpochPhase, error)

	// Epochs returns a query object enabling querying detailed information about
	// various epochs.
	//
	// For epochs that are in the future w.r.t. the Head block, some of Epoch's
	// methods may return errors, since the Epoch Preparation Protocol may be
	// in-progress and incomplete for the epoch.
	Epochs() EpochQuery
}

Snapshot represents an immutable snapshot of the protocol state at a specific block, denoted as the Head block. The Snapshot is fork-specific and only accounts for the information contained in blocks along this fork up to (including) Head. It allows us to read the parameters at the selected block in a deterministic manner.

type State

type State interface {
	ReadOnlyState

	// Mutate will create a mutator for the persistent protocol state. It allows
	// us to extend the protocol state in a consistent manner that conserves the
	// integrity, validity and functionality of the database.
	Mutate() Mutator
}

State allows, in addition to ReadOnlyState, mutating the protocol state in a consistent manner.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL