consensus

package
v0.0.9-alpha Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2024 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// RequestTimeout is the amount of time to wait for a response to a
	// query
	RequestTimeout = 1 * time.Minute

	// FinalizationScore is the confidence score we consider to be final
	FinalizationScore = 160

	// TimeStep is the amount of time to wait between event ticks
	TimeStep = time.Millisecond

	// MaxInflightPoll is the max outstanding requests that we can have
	// for any inventory item.
	MaxInflightPoll = FinalizationScore

	// DeleteInventoryAfter is the maximum time we'll keep a block in memory
	// if it hasn't been finalized by avalanche.
	DeleteInventoryAfter = time.Hour * 6

	// ConsensusProtocol is the libp2p network protocol ID
	ConsensusProtocol = "/consensus/"

	// ConsensusProtocolVersion is the version of the ConsensusProtocol
	ConsensusProtocolVersion = "1.0.0"

	// MinConnectedStakeThreshold is the minimum percentage of the weighted stake
	// set we must be connected to in order to finalize blocks.
	MinConnectedStakeThreshold = .5
)
View Source
const (
	// ResultNoChange means the vote did not produce any change
	// in the record state.
	ResultNoChange = iota
	// ResultFlipped means the preference of the record has flipped
	// as a result of the vote.
	ResultFlipped
	// ResultFinalized means the last vote caused a finalization
	ResultFinalized
)

Variables

This section is empty.

Functions

func UseLogger

func UseLogger(logger *logger.Logger)

UseLogger uses a specified Logger to output package logging info.

Types

type AssertError

type AssertError string

AssertError identifies an error that indicates an internal code consistency issue and should be treated as a critical and unrecoverable error.

func (AssertError) Error

func (e AssertError) Error() string

Error returns the assertion error as a human-readable string and satisfies the error interface.

type BackoffChooser

type BackoffChooser struct {
	// contains filtered or unexported fields
}

BackoffChooser wraps the WeightedRandomChooser with a map that tracks exponential backoffs for peer dials.

func NewBackoffChooser

func NewBackoffChooser(chooser blockchain.WeightedChooser, valconn ValidatorSetConnection) *BackoffChooser

NewBackoffChooser returns a new initialized BackoffChooser

func (*BackoffChooser) RegisterDialFailure

func (b *BackoffChooser) RegisterDialFailure(p peer.ID)

RegisterDialFailure increases the exponential backoff time for the given peer.

func (*BackoffChooser) RegisterDialSuccess

func (b *BackoffChooser) RegisterDialSuccess(p peer.ID)

RegisterDialSuccess deletes the exponential backoff for the given peer.

func (*BackoffChooser) WeightedRandomValidator

func (b *BackoffChooser) WeightedRandomValidator() peer.ID

WeightedRandomValidator returns a weighted random validator. If the selected validator is undergoing a backoff weight time then "" will be returned.

type BitVoteRecord

type BitVoteRecord struct {
	// contains filtered or unexported fields
}

BitVoteRecord is responsible for tracking and finalizing bits. We start with the most significant bit (MSB) and attempt to finalize a 0 or 1 based on the MSB of the block ID votes. Since we're only making a binary choice, one should eventually finalize. We record the finalized bits and move on to trying to finalize the 2nd MSB.

func (*BitVoteRecord) CompareBits

func (vr *BitVoteRecord) CompareBits(id types.ID) bool

CompareBits compares the ID to the bits we've already finalized and returns whether they match or not. It does not compare the active bit.

func (*BitVoteRecord) RecordVote

func (vr *BitVoteRecord) RecordVote(voteID types.ID) Result

RecordVote records a vote for active bit. If the bit finalizes we increment the active bit and reset the state to work on the next most significant bit.

func (*BitVoteRecord) SetActiveBit

func (vr *BitVoteRecord) SetActiveBit(yes bool)

SetActiveBit sets the value for the active bit

type BlockChoice

type BlockChoice struct {
	// contains filtered or unexported fields
}

BlockChoice represents a choice of blocks at a given height in the chain.

At every height there can be one or more blocks to chose from. This object tracks them all and makes a selection based on the recorded votes.

func NewBlockChoice

func NewBlockChoice(height uint32) *BlockChoice

NewBlockChoice returns a new BlockChoice for this height

func (*BlockChoice) AddNewBlock

func (bc *BlockChoice) AddNewBlock(blockID types.ID, isAcceptable bool)

AddNewBlock adds a new block at this height. If there currently is no preference, and if this block is acceptable, it will be selected as the new preference.

func (*BlockChoice) GetPreference

func (bc *BlockChoice) GetPreference() types.ID

GetPreference returns the current block preference at this height or a zero ID if there is no acceptable choice.

func (*BlockChoice) HasBlock

func (bc *BlockChoice) HasBlock(id types.ID) bool

HasBlock returns whether a block is currently saved at this height

func (*BlockChoice) HasFinalized

func (bc *BlockChoice) HasFinalized() bool

HasFinalized returns whether a block at this height has finalized.

func (*BlockChoice) RecordVote

func (bc *BlockChoice) RecordVote(voteID types.ID) (types.ID, bool)

RecordVote records a vote for this height. If the vote is a block ID then a YES will be recorded for that block and a NO for all other conflicting blocks. If it is a ZERO ID then neither YES nor NO will be recorded.

func (*BlockChoice) VotesNeededToFinalize

func (bc *BlockChoice) VotesNeededToFinalize() int

VotesNeededToFinalize returns the minimum number of votes needed to finalize a block given the current distribution of votes. More votes may ultimately be needed but this can be used to throttle inflight requests.

type BlockVoteRecord

type BlockVoteRecord struct {
	// contains filtered or unexported fields
}

BlockVoteRecord keeps track of votes for a single block ID

func (*BlockVoteRecord) RecordVote

func (vr *BlockVoteRecord) RecordVote(vote byte) Result

RecordVote records the votes for a block ID and computes whether a block is finalized.

Unlike bits, a block ID never finalizes as NO. It only remains in a NOT_PREFERRED state.

func (*BlockVoteRecord) Reset

func (vr *BlockVoteRecord) Reset(yes bool)

Reset resets the state of the vote and sets the preference to the bool argument.

func (*BlockVoteRecord) Status

func (vr *BlockVoteRecord) Status() (status Status)

Status returns the current status of the block ID

type ConsensusEngine

type ConsensusEngine struct {
	// contains filtered or unexported fields
}

ConsensusEngine implements a form of the avalanche consensus protocol. It primarily consists of an event loop that polls the weighted list of validators for any unfinalized blocks and records the responses. Blocks finalize when the confidence level exceeds the threshold.

func NewConsensusEngine

func NewConsensusEngine(ctx context.Context, opts ...Option) (*ConsensusEngine, error)

NewConsensusEngine returns a new ConsensusEngine

func (*ConsensusEngine) Close

func (eng *ConsensusEngine) Close()

Close gracefully shuts down the consensus engine

func (*ConsensusEngine) GetBlockFromPeer

func (eng *ConsensusEngine) GetBlockFromPeer(p peer.ID, blkID types.ID) (*blocks.Block, error)

GetBlockFromPeer requests the given block from the remote peer and returns the response or an error.

This is called from outside the package, rather than inside, specifically because we want to wrap the call in some extra logic regarding processing the block and (potentially) increasing the peer's banscore on bad responses.

func (*ConsensusEngine) HandleNewStream

func (eng *ConsensusEngine) HandleNewStream(s inet.Stream)

HandleNewStream handles incoming streams from peers. We use one stream for incoming and a separate one for outgoing.

func (*ConsensusEngine) NewBlock

func (eng *ConsensusEngine) NewBlock(header *blocks.BlockHeader, isAcceptable bool, callback chan<- Status)

NewBlock is used to pass new work in the engine. The callback channel will return the final status (either Finalized or Rejected). Unfinalized but NotPreffered blocks will remain active in the engine until a conflicting block at the same height is finalized. At that point the block will be marked as Rejected.

type GetBlockFunc

type GetBlockFunc func(blockID types.ID) (*blocks.Block, error)

GetBlockFunc returns the block for the given ID or error if it's not found.

type GetBlockIDFunc

type GetBlockIDFunc func(height uint32) (types.ID, error)

GetBlockIDFunc returns the blockID at the given height or an error if it's not found.

type Option

type Option func(cfg *config) error

Option is configuration option function for the blockchain

func Chooser

func Chooser(chooser blockchain.WeightedChooser) Option

Chooser is an implementation of the WeightedChooser used to select a validator to poll at random.

This option is required.

func GetBlock

func GetBlock(getBlockFunc GetBlockFunc) Option

GetBlock is a function which returns the block for the given ID or an error.

This option is required.

func GetBlockID

func GetBlockID(getBlockIDFunc GetBlockIDFunc) Option

GetBlockID is a function which returns the blockID at the given height or an error.

This option is required.

func Network

func Network(n *net.Network) Option

Network is the node's network implementation.

This option is required.

func Params

func Params(params *params.NetworkParams) Option

Params identifies which chain parameters the chain is associated with.

This option is required.

func PeerID

func PeerID(self peer.ID) Option

PeerID is the node's own peerID.

This option is required.

func RequestBlock

func RequestBlock(requestBlockFunc RequestBlockFunc) Option

RequestBlock is a function which requests to download a block from the given peer.

This option is required.

func ValidatorConnector

func ValidatorConnector(valConn ValidatorSetConnection) Option

ValidatorConnector is an implementation of the ValidatorSetConnection interface used to determine if we have a validator set connections to provide consensus.

This option is required.

type RequestBlockFunc

type RequestBlockFunc func(blockID types.ID, remotePeer peer.ID)

RequestBlockFunc is called when the engine receives a query from a peer about and unknown block. It should attempt to download the block from the remote peer, validate it, then pass it into the engine.

type RequestRecord

type RequestRecord struct {
	// contains filtered or unexported fields
}

RequestRecord is a poll request for more votes

func NewRequestRecord

func NewRequestRecord(timestamp int64, heights []uint32) RequestRecord

NewRequestRecord creates a new RequestRecord

func (RequestRecord) GetHeights

func (r RequestRecord) GetHeights() []uint32

GetHeights returns the heights that were requested in this request.

func (RequestRecord) GetTimestamp

func (r RequestRecord) GetTimestamp() int64

GetTimestamp returns the timestamp that the request was created

func (RequestRecord) IsExpired

func (r RequestRecord) IsExpired() bool

IsExpired returns true if the request has expired

type Result

type Result uint8

Result represents the result of a vote record operation

type Status

type Status int

Status is the status of consensus on a particular target

const (
	// StatusRejected means the target has been rejected. Note that blocks are
	// only considered rejected if a competing block has been finalized. If the
	// confidence is a 'no' result has crossed the finalization score, it will
	// remain in the StatusNotPreferred state until a competing block has been
	// finalized.
	StatusRejected Status = iota

	// StatusNotPreferred means the target is not currently preferred by the node
	StatusNotPreferred

	// StatusPreferred means the target is currently preferred by the node
	StatusPreferred

	// StatusFinalized means the target has been finalized in the affirmative.
	StatusFinalized
)

func (Status) String

func (s Status) String() string

String returns the String representation of the Status

type ValidatorSetConnection

type ValidatorSetConnection interface {
	ConnectedStakePercentage() float64
	RegisterDialSuccess(p peer.ID)
	RegisterDialFailure(p peer.ID)
}

Jump to

Keyboard shortcuts

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