Documentation
¶
Index ¶
- Constants
- Variables
- func BlockRecord(bh BlockHeader, blockData []byte) []byte
- func IsFinalizationValid(eligibleSigners map[string]struct{}, finalization *Finalization, ...) bool
- func NewEmptyNotarizationRecord(emptyNotarization *EmptyNotarization) []byte
- func NewEmptyVoteRecord(emptyVote ToBeSignedEmptyVote) []byte
- func NewQuorumRecord(qc []byte, rawVote []byte, recordType uint16) []byte
- func NewScheduler(logger Logger) *scheduler
- func Quorum(n int) int
- type Block
- type BlockBuilder
- type BlockDeserializer
- type BlockHeader
- type BlockMessage
- type Communication
- type Digest
- type EmptyNotarization
- type EmptyVote
- type EmptyVoteSet
- type Epoch
- type EpochConfig
- type Finalization
- type FinalizeVote
- type Logger
- type Message
- type Monitor
- type NodeID
- type NodeIDs
- type Notarization
- type ProtocolMetadata
- type QCDeserializer
- type QuorumCertificate
- type QuorumRecord
- type QuorumRound
- type ReplicationRequest
- type ReplicationResponse
- type ReplicationState
- type Round
- type Segment
- type Signature
- type SignatureAggregator
- type SignatureVerifier
- type SignedMessage
- type Signer
- type Storage
- type TaskHeap
- type TimeoutHandler
- type TimeoutTask
- type ToBeSignedEmptyVote
- type ToBeSignedFinalization
- type ToBeSignedVote
- type VerifiedBlock
- type VerifiedBlockMessage
- type VerifiedFinalizedBlock
- type VerifiedQuorumRound
- type VerifiedReplicationResponse
- type Vote
- type WriteAheadLog
Constants ¶
const ( DefaultMaxRoundWindow = 10 DefaultMaxPendingBlocks = 20 DefaultMaxProposalWaitTime = 5 * time.Second DefaultReplicationRequestTimeout = 5 * time.Second DefaultEmptyVoteRebroadcastTimeout = 5 * time.Second EmptyVoteTimeoutID = "rebroadcast_empty_vote" )
const (
ProtocolMetadataLen = metadataVersionLen + metadataEpochLen + metadataRoundLen + metadataSeqLen + metadataPrevLen
)
Variables ¶
var ( ErrorNoVotes = errors.New("no votes to notarize") ErrorInvalidFinalizationDigest = errors.New("finalization digests do not match") )
var ErrAlreadyStarted = errors.New("epoch already started")
Functions ¶
func BlockRecord ¶
func BlockRecord(bh BlockHeader, blockData []byte) []byte
func IsFinalizationValid ¶
func IsFinalizationValid(eligibleSigners map[string]struct{}, finalization *Finalization, quorumSize int, logger Logger) bool
func NewEmptyNotarizationRecord ¶
func NewEmptyNotarizationRecord(emptyNotarization *EmptyNotarization) []byte
func NewEmptyVoteRecord ¶
func NewEmptyVoteRecord(emptyVote ToBeSignedEmptyVote) []byte
func NewScheduler ¶
func NewScheduler(logger Logger) *scheduler
Types ¶
type Block ¶
type Block interface {
// BlockHeader encodes a succinct and collision-free representation of a block.
BlockHeader() BlockHeader
// Verify verifies the block by speculatively executing it on top of its ancestor.
Verify(ctx context.Context) (VerifiedBlock, error)
}
func BlockFromRecord ¶
type BlockBuilder ¶
type BlockBuilder interface {
// BuildBlock blocks until some transactions are available to be batched into a block,
// in which case a block and true are returned.
// When the given context is cancelled by the caller, returns false.
BuildBlock(ctx context.Context, metadata ProtocolMetadata) (VerifiedBlock, bool)
// IncomingBlock returns when either the given context is cancelled,
// or when the application signals that a block should be built.
IncomingBlock(ctx context.Context)
}
type BlockDeserializer ¶
type BlockDeserializer interface {
// DeserializeBlock parses the given bytes and initializes a VerifiedBlock.
// Returns an error upon failure.
DeserializeBlock(ctx context.Context, bytes []byte) (Block, error)
}
BlockDeserializer deserializes blocks according to formatting enforced by the application.
type BlockHeader ¶
type BlockHeader struct {
ProtocolMetadata
// Digest returns a collision resistant short representation of the block's bytes
Digest Digest
}
BlockHeader encodes a succinct and collision-free representation of a block. It's included in votes and finalizations in order to convey which block is voted on, or which block is finalized.
func ParseBlockRecord ¶
func ParseBlockRecord(buff []byte) (BlockHeader, []byte, error)
func (*BlockHeader) Bytes ¶
func (bh *BlockHeader) Bytes() []byte
func (*BlockHeader) Equals ¶
func (bh *BlockHeader) Equals(other *BlockHeader) bool
func (*BlockHeader) FromBytes ¶
func (bh *BlockHeader) FromBytes(buff []byte) error
type BlockMessage ¶
type Communication ¶
type Communication interface {
// Nodes returns all nodes that participate in the epoch.
Nodes() []NodeID
// Send sends a message to the given destination node
Send(msg *Message, destination NodeID)
// Broadcast broadcasts the given message to all nodes.
// Does not send it to yourself.
Broadcast(msg *Message)
}
type EmptyNotarization ¶
type EmptyNotarization struct {
Vote ToBeSignedEmptyVote
QC QuorumCertificate
}
func EmptyNotarizationFromRecord ¶
func EmptyNotarizationFromRecord(record []byte, qd QCDeserializer) (EmptyNotarization, error)
func (*EmptyNotarization) Verify ¶
func (en *EmptyNotarization) Verify() error
type EmptyVote ¶
type EmptyVote struct {
Vote ToBeSignedEmptyVote
Signature Signature
}
EmptyVote represents a signed vote for an empty block.
type EmptyVoteSet ¶
type EmptyVoteSet struct {
// contains filtered or unexported fields
}
type Epoch ¶
type Epoch struct {
EpochConfig
// contains filtered or unexported fields
}
func NewEpoch ¶
func NewEpoch(conf EpochConfig) (*Epoch, error)
func (*Epoch) AdvanceTime ¶
AdvanceTime hints the engine that the given amount of time has passed.
func (*Epoch) HandleMessage ¶
HandleMessage notifies the engine about a reception of a message.
func (*Epoch) Metadata ¶
func (e *Epoch) Metadata() ProtocolMetadata
Metadata returns the metadata of the next expected block of the epoch.
type EpochConfig ¶
type EpochConfig struct {
MaxProposalWait time.Duration
MaxRebroadcastWait time.Duration
QCDeserializer QCDeserializer
Logger Logger
ID NodeID
Signer Signer
Verifier SignatureVerifier
BlockDeserializer BlockDeserializer
SignatureAggregator SignatureAggregator
Comm Communication
Storage Storage
WAL WriteAheadLog
BlockBuilder BlockBuilder
Epoch uint64
StartTime time.Time
ReplicationEnabled bool
}
type Finalization ¶
type Finalization struct {
Finalization ToBeSignedFinalization
QC QuorumCertificate
}
Finalization represents a block that has reached quorum on block. This means that block can be included in the chain and finalized.
func FinalizationFromRecord ¶
func FinalizationFromRecord(record []byte, qd QCDeserializer) (Finalization, error)
func NewFinalization ¶
func NewFinalization(logger Logger, signatureAggregator SignatureAggregator, finalizeVotes []*FinalizeVote) (Finalization, error)
NewFinalization builds a Finalization from [finalizeVotes].
func (*Finalization) Verify ¶
func (f *Finalization) Verify() error
type FinalizeVote ¶
type FinalizeVote struct {
Finalization ToBeSignedFinalization
Signature Signature
}
FinalizeVote represents a vote to finalize a block.
type Logger ¶
type Logger interface {
// Log that a fatal error has occurred. The program should likely exit soon
// after this is called
Fatal(msg string, fields ...zap.Field)
// Log that an error has occurred. The program should be able to recover
// from this error
Error(msg string, fields ...zap.Field)
// Log that an event has occurred that may indicate a future error or
// vulnerability
Warn(msg string, fields ...zap.Field)
// Log an event that may be useful for a user to see to measure the progress
// of the protocol
Info(msg string, fields ...zap.Field)
// Log an event that may be useful for understanding the order of the
// execution of the protocol
Trace(msg string, fields ...zap.Field)
// Log an event that may be useful for a programmer to see when debuging the
// execution of the protocol
Debug(msg string, fields ...zap.Field)
// Log extremely detailed events that can be useful for inspecting every
// aspect of the program
Verbo(msg string, fields ...zap.Field)
}
type Message ¶
type Message struct {
BlockMessage *BlockMessage
VerifiedBlockMessage *VerifiedBlockMessage
EmptyNotarization *EmptyNotarization
VoteMessage *Vote
EmptyVoteMessage *EmptyVote
Notarization *Notarization
FinalizeVote *FinalizeVote
Finalization *Finalization
ReplicationResponse *ReplicationResponse
VerifiedReplicationResponse *VerifiedReplicationResponse
ReplicationRequest *ReplicationRequest
}
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
func (*Monitor) AdvanceTime ¶
func (*Monitor) CancelFutureTask ¶
func (m *Monitor) CancelFutureTask()
func (*Monitor) CancelTask ¶
func (m *Monitor) CancelTask()
func (*Monitor) FutureTask ¶
type Notarization ¶
type Notarization struct {
Vote ToBeSignedVote
QC QuorumCertificate
}
Notarization represents a block that has reached a quorum of votes.
func NewNotarization ¶
func NewNotarization(logger Logger, signatureAggregator SignatureAggregator, votesForCurrentRound map[string]*Vote, blockHeader BlockHeader) (Notarization, error)
NewNotarization builds a Notarization for a block described by [blockHeader] from [votesForCurrentRound].
func NotarizationFromRecord ¶
func NotarizationFromRecord(record []byte, qd QCDeserializer) (Notarization, error)
func (*Notarization) Verify ¶
func (n *Notarization) Verify() error
type ProtocolMetadata ¶
type ProtocolMetadata struct {
// Version defines the version of the protocol this block was created with.
Version uint8
// Epoch returns the epoch in which the block was proposed
Epoch uint64
// Round returns the round number in which the block was proposed.
// Can also be an empty block.
Round uint64
// Seq is the order of the block among all blocks in the blockchain.
// Cannot correspond to an empty block.
Seq uint64
// Prev returns the digest of the previous data block
Prev Digest
}
ProtocolMetadata encodes information about the protocol state at a given point in time.
func ProtocolMetadataFromBytes ¶
func ProtocolMetadataFromBytes(buff []byte) (*ProtocolMetadata, error)
Serializes a ProtocolMetadata from a byte slice.
func (*ProtocolMetadata) Bytes ¶
func (md *ProtocolMetadata) Bytes() []byte
Bytes returns a byte encoding of the ProtocolMetadata. it is encoded as follows: [Version (1 byte), Epoch (8 bytes), Round (8 bytes), Seq (8 bytes), Prev (32 bytes)]
type QCDeserializer ¶
type QCDeserializer interface {
// DeserializeQuorumCertificate parses the given bytes and initializes a QuorumCertificate.
// Returns an error upon failure.
DeserializeQuorumCertificate(bytes []byte) (QuorumCertificate, error)
}
QCDeserializer deserializes QuorumCertificates according to formatting
type QuorumCertificate ¶
type QuorumCertificate interface {
// Signers returns who participated in creating this QuorumCertificate.
Signers() []NodeID
// Verify checks whether the nodes participated in creating this QuorumCertificate,
// signed the given message.
Verify(msg []byte) error
// Bytes returns a raw representation of the given QuorumCertificate.
Bytes() []byte
}
QuorumCertificate is equivalent to a collection of signatures from a quorum of nodes,
type QuorumRecord ¶
type QuorumRound ¶
type QuorumRound struct {
Block Block
Notarization *Notarization
Finalization *Finalization
EmptyNotarization *EmptyNotarization
}
QuorumRound represents a round that has acheived quorum on either (empty notarization), (block & notarization), or (block, finalization)
func (*QuorumRound) GetRound ¶
func (q *QuorumRound) GetRound() uint64
func (*QuorumRound) GetSequence ¶
func (q *QuorumRound) GetSequence() uint64
func (*QuorumRound) IsWellFormed ¶
func (q *QuorumRound) IsWellFormed() error
isWellFormed returns an error if the QuorumRound has either (block, notarization) or (block, finalization) or (empty notarization)
func (*QuorumRound) String ¶
func (q *QuorumRound) String() string
String returns a string representation of the QuorumRound. It is meant as a debugging aid for logs.
func (*QuorumRound) Verify ¶
func (q *QuorumRound) Verify() error
type ReplicationRequest ¶
type ReplicationResponse ¶
type ReplicationResponse struct {
Data []QuorumRound
LatestRound *QuorumRound
}
type ReplicationState ¶
type ReplicationState struct {
// contains filtered or unexported fields
}
func NewReplicationState ¶
func NewReplicationState(logger Logger, comm Communication, id NodeID, maxRoundWindow uint64, enabled bool, start time.Time) *ReplicationState
func (*ReplicationState) AdvanceTime ¶
func (r *ReplicationState) AdvanceTime(now time.Time)
func (*ReplicationState) GetFinalizedBlockForSequence ¶
func (r *ReplicationState) GetFinalizedBlockForSequence(seq uint64) (Block, Finalization, bool)
func (*ReplicationState) GetQuroumRoundWithSeq ¶
func (r *ReplicationState) GetQuroumRoundWithSeq(seq uint64) *QuorumRound
func (*ReplicationState) StoreQuorumRound ¶
func (r *ReplicationState) StoreQuorumRound(round QuorumRound)
type Round ¶
type Round struct {
// contains filtered or unexported fields
}
func NewRound ¶
func NewRound(block VerifiedBlock) *Round
func SetRound ¶
func SetRound(block VerifiedBlock, notarization *Notarization, finalization *Finalization) *Round
SetRound is a helper function that is used for tests to create a round.
type Segment ¶
func CompressSequences ¶
compressSequences takes a sorted slice of uint64 values representing missing sequence numbers and compresses consecutive numbers into segments. Each segment represents a continuous block of missing sequence numbers.
func DistributeSequenceRequests ¶
DistributeSequenceRequests evenly creates segments amongst [numNodes] over the range [start, end].
type Signature ¶
type Signature struct {
// Signer is the NodeID of the creator of the signature.
Signer NodeID
// Value is the byte representation of the signature.
Value []byte
}
Signature encodes a signature and the node that signed it, without the message it was signed on.
type SignatureAggregator ¶
type SignatureAggregator interface {
// Aggregate aggregates several signatures into a QuorumCertificate
Aggregate([]Signature) (QuorumCertificate, error)
}
SignatureAggregator aggregates signatures into a QuorumCertificate
type SignatureVerifier ¶
type SignedMessage ¶
type Storage ¶
type Storage interface {
Height() uint64
// Retrieve returns the block and finalization at [seq].
// If [seq] is not found, returns false.
Retrieve(seq uint64) (VerifiedBlock, Finalization, bool)
Index(block VerifiedBlock, certificate Finalization)
}
type TaskHeap ¶
type TaskHeap []*TimeoutTask
----------------------------------------------------------------------
type TimeoutHandler ¶
type TimeoutHandler struct {
// contains filtered or unexported fields
}
func NewTimeoutHandler ¶
func NewTimeoutHandler(log Logger, startTime time.Time, nodes []NodeID) *TimeoutHandler
NewTimeoutHandler returns a TimeoutHandler and starts a new goroutine that listens for ticks and executes TimeoutTasks.
func (*TimeoutHandler) AddTask ¶
func (t *TimeoutHandler) AddTask(task *TimeoutTask)
func (*TimeoutHandler) Close ¶
func (t *TimeoutHandler) Close()
func (*TimeoutHandler) GetTime ¶
func (t *TimeoutHandler) GetTime() time.Time
func (*TimeoutHandler) RemoveTask ¶
func (t *TimeoutHandler) RemoveTask(nodeID NodeID, ID string)
func (*TimeoutHandler) Tick ¶
func (t *TimeoutHandler) Tick(now time.Time)
type TimeoutTask ¶
type TimeoutTask struct {
NodeID NodeID
TaskID string
Task func()
Deadline time.Time
// for replication tasks
Start uint64
End uint64
// contains filtered or unexported fields
}
func FindReplicationTask ¶
func FindReplicationTask(t *TimeoutHandler, node NodeID, seqs []uint64) *TimeoutTask
FindReplicationTask returns a TimeoutTask assigned to [node] that contains the lowest sequence in [seqs]. A sequence is considered "contained" if it falls between a task's Start (inclusive) and End (inclusive).
type ToBeSignedEmptyVote ¶
type ToBeSignedEmptyVote struct {
ProtocolMetadata
}
func ParseEmptyNotarizationRecord ¶
func ParseEmptyNotarizationRecord(buff []byte) ([]byte, ToBeSignedEmptyVote, error)
func ParseEmptyVoteRecord ¶
func ParseEmptyVoteRecord(rawEmptyVote []byte) (ToBeSignedEmptyVote, error)
func (*ToBeSignedEmptyVote) Bytes ¶
func (v *ToBeSignedEmptyVote) Bytes() []byte
func (*ToBeSignedEmptyVote) FromBytes ¶
func (v *ToBeSignedEmptyVote) FromBytes(buff []byte) error
func (*ToBeSignedEmptyVote) Sign ¶
func (v *ToBeSignedEmptyVote) Sign(signer Signer) ([]byte, error)
func (*ToBeSignedEmptyVote) Verify ¶
func (v *ToBeSignedEmptyVote) Verify(signature []byte, verifier SignatureVerifier, signers NodeID) error
type ToBeSignedFinalization ¶
type ToBeSignedFinalization struct {
BlockHeader
}
func (*ToBeSignedFinalization) Sign ¶
func (f *ToBeSignedFinalization) Sign(signer Signer) ([]byte, error)
func (*ToBeSignedFinalization) Verify ¶
func (f *ToBeSignedFinalization) Verify(signature []byte, verifier SignatureVerifier, signers NodeID) error
type ToBeSignedVote ¶
type ToBeSignedVote struct {
BlockHeader
}
func ParseNotarizationRecord ¶
func ParseNotarizationRecord(r []byte) ([]byte, ToBeSignedVote, error)
ParseNotarizationRecordBytes parses a notarization record into the bytes of the QC and the vote
func (*ToBeSignedVote) Verify ¶
func (v *ToBeSignedVote) Verify(signature []byte, verifier SignatureVerifier, signers NodeID) error
type VerifiedBlock ¶
type VerifiedBlock interface {
// BlockHeader encodes a succinct and collision-free representation of a block.
BlockHeader() BlockHeader
// Bytes returns a byte encoding of the block
Bytes() ([]byte, error)
}
type VerifiedBlockMessage ¶
type VerifiedBlockMessage struct {
VerifiedBlock VerifiedBlock
Vote Vote
}
type VerifiedFinalizedBlock ¶
type VerifiedFinalizedBlock struct {
VerifiedBlock VerifiedBlock
Finalization Finalization
}
func RetrieveLastIndexFromStorage ¶
func RetrieveLastIndexFromStorage(s Storage) (*VerifiedFinalizedBlock, error)
RetrieveLastIndexFromStorage retrieves the latest block and finalization from storage. Returns an error if it cannot be retrieved but the storage has some block. Returns (nil, nil) if the storage is empty.
type VerifiedQuorumRound ¶
type VerifiedQuorumRound struct {
VerifiedBlock VerifiedBlock
Notarization *Notarization
Finalization *Finalization
EmptyNotarization *EmptyNotarization
}
func GetLatestVerifiedQuorumRound ¶
func GetLatestVerifiedQuorumRound(round *Round, emptyNotarization *EmptyNotarization, lastBlock *VerifiedFinalizedBlock) *VerifiedQuorumRound
GetLatestVerifiedQuorumRound returns the latest verified quorum round given a round, empty notarization, and last block. If all are nil, it returns nil.
func (*VerifiedQuorumRound) GetRound ¶
func (q *VerifiedQuorumRound) GetRound() uint64
type VerifiedReplicationResponse ¶
type VerifiedReplicationResponse struct {
Data []VerifiedQuorumRound
LatestRound *VerifiedQuorumRound
}
type Vote ¶
type Vote struct {
Vote ToBeSignedVote
Signature Signature
}
Vote represents a signed vote for a block.
