loop

package
v0.4.3 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2021 License: MIT Imports: 18 Imported by: 0

README

Consensus Loop

The Loop is the most high-level component of the SBA* consensus implementation. It simulates a state-machine like architecture, with a functional flavor, where consensus phases are sequenced one after the other, returning functions as they complete, based on their outcomes.

Architecture

For any caller to be able to start the consensus, they will need to have access to a fully initialized Loop. It is initialized by giving a couple of pre-requisite items:

  • A public key, to which block generator rewards can be attributed
  • An Emitter, responsible for routing communications
  • A Requestor, which is capable of retrieving candidate blocks on request from the network
  • A callback to be used for candidate block verification
  • A database instance
  • The initial timeout

This Loop can then be re-used for the lifetime of the node to start and maintain consensus loops.

Communications

The Loop is responsible for establishing the communications bridge between the consensus and the rest of the node. This is done by creating an Emitter and passing it to the Loop on startup. The Loop will then set up message channels for each of the messages we expect to receive for the consensus, and subscribe them to the event bus with the relevant topics. From this point, all consensus messages will be directly routed to the correct components as they start coming in.

Running

To start the consensus loop, simply create the state machine by calling CreateStateMachine on the Loop instance. This will return two consensus phases - the score phase, and the agreement phase. There is a key distinction between the two, which is that the score phase will return another function as it completes, and so will it's successors until they reach the score phase again. This ensures the sequential, state-machine-like progression of the synchronous consensus phases. The agreement phase is intended to run concurrently, as it can receive messages at any time, and is not bound to a timer or anything of the sort.

With these two phases, all we have left to do to start the consensus loop, is to formulate a RoundUpdate. This contains all the stateful information needed by the consensus to do its job. Finally, with all of these items in place, call loop.Spin, passing these items, in order to launch the consensus loop. Once this is called, the consensus will progress until an error is encountered, or until it is cancelled through a context cancellation.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrMaxStepsReached = errors.New("consensus reached max number of steps without moving forward")

ErrMaxStepsReached is triggered when the consensus loop reaches the maximum amount of steps without reaching an Agreement. This means that the network is highly asynchronous or we are under attack.

Functions

func CreateInitialStep

func CreateInitialStep(e *consensus.Emitter, consensusTimeOut time.Duration, bg blockgenerator.BlockGenerator, verifyFn consensus.CandidateVerificationFunc, db database.DB, requestor *candidate.Requestor) consensus.Phase

CreateInitialStep creates the selection step by injecting a BlockGenerator interface to it.

func CreateStateMachine

func CreateStateMachine(e *consensus.Emitter, db database.DB, consensusTimeOut time.Duration, pubKey *keys.PublicKey, verifyFn consensus.CandidateVerificationFunc, requestor *candidate.Requestor) (consensus.Phase, consensus.Controller, error)

CreateStateMachine creates and link the steps in the consensus. It is kept separated from consensus.New so to ease mocking the consensus up when testing.

Types

type Consensus

type Consensus struct {
	*consensus.Emitter
	*candidate.Requestor
	// contains filtered or unexported fields
}

Consensus is the state machine that runs the steps of consensus. Rather than trying to coordinate the various steps, it lets them execute and indicate which should be the following status, until completion. Each round is run separately and in a synchronous, blocking fashion (except the Agreement which should be run asynchronously by design).

func New

func New(e *consensus.Emitter, pubKey *keys.PublicKey) *Consensus

New creates a new Consensus struct. The legacy StopConsensus and RoundUpdate are now replaced with context cancellation and direct function call operated by the chain component.

func (*Consensus) CreateStateMachine

func (c *Consensus) CreateStateMachine(db database.DB, consensusTimeOut time.Duration, verifyFn consensus.CandidateVerificationFunc) (consensus.Phase, consensus.Controller, error)

CreateStateMachine uses Consensus parameters as a shorthand for the static CreateStateMachine.

func (*Consensus) Spin

Spin the consensus state machine. The consensus runs for the whole round until either a new round is produced or the node needs to re-sync. The Agreement loop (acting roundwise) runs concurrently with the generation-selection-reduction loop (acting step-wise). TODO: consider stopping the phase loop with a Done phase, instead of nil.

Jump to

Keyboard shortcuts

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