dbft

package module
v0.0.0-...-989d409 Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2024 License: MIT Imports: 8 Imported by: 0

README

Codecov Report License

EpicChain

Welcome to the EpicChain repository! This project contains the implementation of the EpicChain blockchain, including its consensus algorithm, models, and related components. EpicChain aims to deliver a robust and scalable blockchain infrastructure with high performance and flexibility, providing a solid foundation for decentralized applications and smart contracts.

Overview

The EpicChain project encompasses various critical elements necessary for building and maintaining a blockchain network. Our implementation focuses on providing a secure and efficient framework for consensus, data integrity, and interoperability. Below, you will find a detailed breakdown of the design and structure of the EpicChain implementation.

Design and Structure

  1. Core Package:

    • The core control flow is managed in the main epicchain package. This package is designed with high flexibility and extendability in mind. It abstracts external communication and event handling behind interfaces, callbacks, and generic parameters. Detailed descriptions of configuration options can be found in the config.go file, enabling you to customize and adjust settings according to your needs.
  2. Cryptography:

    • The epicchain package includes interfaces for PrivateKey and PublicKey, allowing developers to integrate their own cryptographic solutions for signing blocks during the commit stage. For more information on these interfaces, refer to identity.go. Note that no default cryptographic implementations are provided, giving you the freedom to choose or implement your preferred cryptographic methods.
  3. Hashing:

    • Similarly, the epicchain package provides a Hash interface that enables the use of custom hashing algorithms without additional overhead for conversions. You can instantiate EpicChain with a custom hash implementation that aligns with your requirements. Details about the Hash interface are available in identity.go, and again, no default implementation is provided.
  4. Abstractions:

    • The epicchain package includes Block and Transaction abstractions, defined in block.go and transaction.go. These abstractions ensure that every block can be signed, verified, and accessed for essential fields. Transactions are entities that can be hashed, and entities with matching hashes are considered equivalent. No default implementations are provided, allowing for customization according to your project's needs.
  5. Payloads:

    • The repository also contains generic interfaces for payloads, but no default implementations are provided. This design allows for flexible payload handling suited to various use cases.
  6. Timers:

    • A Timer interface is included for managing time-related operations. The timer package offers a default Timer provider suitable for production environments. The interface is primarily designed for testing scenarios that involve time-dependent behavior in EpicChain.
  7. Custom Implementations:

    • The internal directory features examples of custom identity types and payload implementations, used to demonstrate the application of EpicChain with a 6-node consensus model. You can find type-specific implementations and tests in the internal subpackages. The internal/simulation folder provides an example of how to use the EpicChain library effectively.
  8. Formal Models:

    • The formal-models directory contains a set of models for EpicChain written in TLA⁺ language. These models are accompanied by instructions on how to run and verify them. For more details, refer to the README in the formal-models directory.

Usage

To utilize the EpicChain library, you must implement your own event loop. The library provides five critical callbacks that influence the state of the consensus process:

  • Start(): Initializes the internal EpicChain structures.
  • Reset(): Reinitializes the consensus process to handle a new height or state.
  • OnTransaction(): Should be called whenever a new transaction appears, allowing the system to process and include it in the blockchain.
  • OnReceive(): Should be invoked every time a new payload is received, ensuring that the system processes incoming data.
  • OnTimer(): Must be called whenever a timer event occurs, managing time-related tasks within the consensus process.

A minimal working example is available in internal/simulation/main.go, demonstrating basic usage and setup of the EpicChain library.

Additional Resources

For further information and in-depth understanding, you can explore the following resources:

  • EpicChain Consensus Overview: A high-level description of the consensus mechanism used in EpicChain. Learn more
  • EpicChain Research Paper: Detailed documentation and research paper outlining the theoretical foundation and design principles of EpicChain. Read the paper

Notes

  1. Memory Pool Model:

    • The EpicChain implementation supports a memory pool model, where transaction hashes are proposed initially, and transactions are synchronized in the background. Some callbacks are configured to support this use case, but it is easy to extend PrepareRequest to include proposed transactions if needed.
  2. Validator Management:

    • EpicChain includes functionality for managing validators, which are responsible for verifying blocks. The GetValidators callback is called at the start of each epoch to retrieve the list of validators. In scenarios where validators are constant, this callback can return the same value consistently.
  3. Block Processing:

    • The ProcessBlock callback is invoked synchronously whenever a new block is accepted. It is responsible for persisting the block and updating the blockchain state if required. The library does not automatically initialize EpicChain for the next height after block collection; this responsibility lies with the caller, who must ensure proper initialization and state updates before proceeding.

Feel free to explore the repository, and don't hesitate to reach out to the EpicChain community if you have any questions or need further assistance with your implementation.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithBroadcast

func WithBroadcast[H Hash](f func(m ConsensusPayload[H])) func(config *Config[H])

WithBroadcast sets Broadcast.

func WithCurrentBlockHash

func WithCurrentBlockHash[H Hash](f func() H) func(config *Config[H])

WithCurrentBlockHash sets CurrentBlockHash.

func WithCurrentHeight

func WithCurrentHeight[H Hash](f func() uint32) func(config *Config[H])

WithCurrentHeight sets CurrentHeight.

func WithGetBlock

func WithGetBlock[H Hash](f func(h H) Block[H]) func(config *Config[H])

WithGetBlock sets GetBlock.

func WithGetKeyPair

func WithGetKeyPair[H Hash](f func(pubs []PublicKey) (int, PrivateKey, PublicKey)) func(config *Config[H])

WithGetKeyPair sets GetKeyPair.

func WithGetTx

func WithGetTx[H Hash](f func(h H) Transaction[H]) func(config *Config[H])

WithGetTx sets GetTx.

func WithGetValidators

func WithGetValidators[H Hash](f func(txs ...Transaction[H]) []PublicKey) func(config *Config[H])

WithGetValidators sets GetValidators.

func WithGetVerified

func WithGetVerified[H Hash](f func() []Transaction[H]) func(config *Config[H])

WithGetVerified sets GetVerified.

func WithLogger

func WithLogger[H Hash](log *zap.Logger) func(config *Config[H])

WithLogger sets Logger.

func WithNewBlockFromContext

func WithNewBlockFromContext[H Hash](f func(ctx *Context[H]) Block[H]) func(config *Config[H])

WithNewBlockFromContext sets NewBlockFromContext.

func WithNewChangeView

func WithNewChangeView[H Hash](f func(newViewNumber byte, reason ChangeViewReason, ts uint64) ChangeView) func(config *Config[H])

WithNewChangeView sets NewChangeView.

func WithNewCommit

func WithNewCommit[H Hash](f func(signature []byte) Commit) func(config *Config[H])

WithNewCommit sets NewCommit.

func WithNewConsensusPayload

func WithNewConsensusPayload[H Hash](f func(ctx *Context[H], typ MessageType, msg any) ConsensusPayload[H]) func(config *Config[H])

WithNewConsensusPayload sets NewConsensusPayload.

func WithNewPrepareRequest

func WithNewPrepareRequest[H Hash](f func(ts uint64, nonce uint64, transactionsHashes []H) PrepareRequest[H]) func(config *Config[H])

WithNewPrepareRequest sets NewPrepareRequest.

func WithNewPrepareResponse

func WithNewPrepareResponse[H Hash](f func(preparationHash H) PrepareResponse[H]) func(config *Config[H])

WithNewPrepareResponse sets NewPrepareResponse.

func WithNewRecoveryMessage

func WithNewRecoveryMessage[H Hash](f func() RecoveryMessage[H]) func(config *Config[H])

WithNewRecoveryMessage sets NewRecoveryMessage.

func WithNewRecoveryRequest

func WithNewRecoveryRequest[H Hash](f func(ts uint64) RecoveryRequest) func(config *Config[H])

WithNewRecoveryRequest sets NewRecoveryRequest.

func WithProcessBlock

func WithProcessBlock[H Hash](f func(b Block[H])) func(config *Config[H])

WithProcessBlock sets ProcessBlock.

func WithRequestTx

func WithRequestTx[H Hash](f func(h ...H)) func(config *Config[H])

WithRequestTx sets RequestTx.

func WithSecondsPerBlock

func WithSecondsPerBlock[H Hash](d time.Duration) func(config *Config[H])

WithSecondsPerBlock sets SecondsPerBlock.

func WithStopTxFlow

func WithStopTxFlow[H Hash](f func()) func(config *Config[H])

WithStopTxFlow sets StopTxFlow.

func WithTimer

func WithTimer[H Hash](t Timer) func(config *Config[H])

WithTimer sets Timer.

func WithTimestampIncrement

func WithTimestampIncrement[H Hash](u uint64) func(config *Config[H])

WithTimestampIncrement sets TimestampIncrement.

func WithVerifyBlock

func WithVerifyBlock[H Hash](f func(b Block[H]) bool) func(config *Config[H])

WithVerifyBlock sets VerifyBlock.

func WithVerifyPrepareRequest

func WithVerifyPrepareRequest[H Hash](f func(prepareReq ConsensusPayload[H]) error) func(config *Config[H])

WithVerifyPrepareRequest sets VerifyPrepareRequest.

func WithVerifyPrepareResponse

func WithVerifyPrepareResponse[H Hash](f func(prepareResp ConsensusPayload[H]) error) func(config *Config[H])

WithVerifyPrepareResponse sets VerifyPrepareResponse.

func WithWatchOnly

func WithWatchOnly[H Hash](f func() bool) func(config *Config[H])

WithWatchOnly sets WatchOnly.

Types

type Block

type Block[H Hash] interface {
	// Hash returns block hash.
	Hash() H
	// PrevHash returns previous block hash.
	PrevHash() H
	// MerkleRoot returns a merkle root of the transaction hashes.
	MerkleRoot() H
	// Index returns block index.
	Index() uint32

	// Signature returns block's signature.
	Signature() []byte
	// Sign signs block and sets it's signature.
	Sign(key PrivateKey) error
	// Verify checks if signature is correct.
	Verify(key PublicKey, sign []byte) error

	// Transactions returns block's transaction list.
	Transactions() []Transaction[H]
	// SetTransactions sets block's transaction list.
	SetTransactions([]Transaction[H])
}

Block is a generic interface for a block used by dbft.

type ChangeView

type ChangeView interface {
	// NewViewNumber returns proposed view number.
	NewViewNumber() byte

	// Reason returns change view reason.
	Reason() ChangeViewReason
}

ChangeView represents dBFT ChangeView message.

type ChangeViewReason

type ChangeViewReason byte

ChangeViewReason represents a view change reason code.

const (
	CVTimeout               ChangeViewReason = 0x0  // Timeout
	CVChangeAgreement       ChangeViewReason = 0x1  // ChangeAgreement
	CVTxNotFound            ChangeViewReason = 0x2  // TxNotFound
	CVTxRejectedByPolicy    ChangeViewReason = 0x3  // TxRejectedByPolicy
	CVTxInvalid             ChangeViewReason = 0x4  // TxInvalid
	CVBlockRejectedByPolicy ChangeViewReason = 0x5  // BlockRejectedByPolicy
	CVUnknown               ChangeViewReason = 0xff // Unknown
)

These constants define various reasons for view changing. They're following Neo 3 except the Unknown value which is left for compatibility with Neo 2.

func (ChangeViewReason) String

func (i ChangeViewReason) String() string

type Commit

type Commit interface {
	// Signature returns commit's signature field
	// which is a block signature for the current epoch.
	Signature() []byte
}

Commit is an interface for dBFT Commit message.

type Config

type Config[H Hash] struct {
	// Logger
	Logger *zap.Logger
	// Timer
	Timer Timer
	// SecondsPerBlock is the number of seconds that
	// need to pass before another block will be accepted.
	SecondsPerBlock time.Duration
	// TimestampIncrement increment is the amount of units to add to timestamp
	// if current time is less than that of previous context.
	// By default use millisecond precision.
	TimestampIncrement uint64
	// GetKeyPair returns an index of the node in the list of validators
	// together with it's key pair.
	GetKeyPair func([]PublicKey) (int, PrivateKey, PublicKey)
	// NewBlockFromContext should allocate, fill from Context and return new block.Block.
	NewBlockFromContext func(ctx *Context[H]) Block[H]
	// RequestTx is a callback which is called when transaction contained
	// in current block can't be found in memory pool.
	RequestTx func(h ...H)
	// StopTxFlow is a callback which is called when the process no longer needs
	// any transactions.
	StopTxFlow func()
	// GetTx returns a transaction from memory pool.
	GetTx func(h H) Transaction[H]
	// GetVerified returns a slice of verified transactions
	// to be proposed in a new block.
	GetVerified func() []Transaction[H]
	// VerifyBlock verifies if block is valid.
	VerifyBlock func(b Block[H]) bool
	// Broadcast should broadcast payload m to the consensus nodes.
	Broadcast func(m ConsensusPayload[H])
	// ProcessBlock is called every time new block is accepted.
	ProcessBlock func(b Block[H])
	// GetBlock should return block with hash.
	GetBlock func(h H) Block[H]
	// WatchOnly tells if a node should only watch.
	WatchOnly func() bool
	// CurrentHeight returns index of the last accepted block.
	CurrentHeight func() uint32
	// CurrentBlockHash returns hash of the last accepted block.
	CurrentBlockHash func() H
	// GetValidators returns list of the validators.
	// When called with a transaction list it must return
	// list of the validators of the next block.
	// If this function ever returns 0-length slice, dbft will panic.
	GetValidators func(...Transaction[H]) []PublicKey
	// NewConsensusPayload is a constructor for payload.ConsensusPayload.
	NewConsensusPayload func(*Context[H], MessageType, any) ConsensusPayload[H]
	// NewPrepareRequest is a constructor for payload.PrepareRequest.
	NewPrepareRequest func(ts uint64, nonce uint64, transactionHashes []H) PrepareRequest[H]
	// NewPrepareResponse is a constructor for payload.PrepareResponse.
	NewPrepareResponse func(preparationHash H) PrepareResponse[H]
	// NewChangeView is a constructor for payload.ChangeView.
	NewChangeView func(newViewNumber byte, reason ChangeViewReason, timestamp uint64) ChangeView
	// NewCommit is a constructor for payload.Commit.
	NewCommit func(signature []byte) Commit
	// NewRecoveryRequest is a constructor for payload.RecoveryRequest.
	NewRecoveryRequest func(ts uint64) RecoveryRequest
	// NewRecoveryMessage is a constructor for payload.RecoveryMessage.
	NewRecoveryMessage func() RecoveryMessage[H]
	// VerifyPrepareRequest can perform external payload verification and returns true iff it was successful.
	VerifyPrepareRequest func(p ConsensusPayload[H]) error
	// VerifyPrepareResponse performs external PrepareResponse verification and returns nil if it's successful.
	VerifyPrepareResponse func(p ConsensusPayload[H]) error
}

Config contains initialization and working parameters for dBFT.

type ConsensusMessage

type ConsensusMessage[H Hash] interface {
	// ViewNumber returns view number when this message was originated.
	ViewNumber() byte
	// Type returns type of this message.
	Type() MessageType
	// Payload returns this message's actual payload.
	Payload() any

	// GetChangeView returns payload as if it was ChangeView.
	GetChangeView() ChangeView
	// GetPrepareRequest returns payload as if it was PrepareRequest.
	GetPrepareRequest() PrepareRequest[H]
	// GetPrepareResponse returns payload as if it was PrepareResponse.
	GetPrepareResponse() PrepareResponse[H]
	// GetCommit returns payload as if it was Commit.
	GetCommit() Commit
	// GetRecoveryRequest returns payload as if it was RecoveryRequest.
	GetRecoveryRequest() RecoveryRequest
	// GetRecoveryMessage returns payload as if it was RecoveryMessage.
	GetRecoveryMessage() RecoveryMessage[H]
}

ConsensusMessage is an interface for generic dBFT message.

type ConsensusPayload

type ConsensusPayload[H Hash] interface {
	ConsensusMessage[H]

	// ValidatorIndex returns index of validator from which
	// payload was originated from.
	ValidatorIndex() uint16

	// SetValidatorIndex sets validator index.
	SetValidatorIndex(i uint16)

	Height() uint32

	// Hash returns 32-byte checksum of the payload.
	Hash() H
}

ConsensusPayload is a generic payload type which is exchanged between the nodes.

type Context

type Context[H Hash] struct {
	// Config is dBFT's Config instance.
	Config *Config[H]

	// Priv is node's private key.
	Priv PrivateKey
	// Pub is node's public key.
	Pub PublicKey

	// BlockIndex is current block index.
	BlockIndex uint32
	// ViewNumber is current view number.
	ViewNumber byte
	// Validators is a current validator list.
	Validators []PublicKey
	// MyIndex is an index of the current node in the Validators array.
	// It is equal to -1 if node is not a validator or is WatchOnly.
	MyIndex int
	// PrimaryIndex is an index of the primary node in the current epoch.
	PrimaryIndex uint

	// PrevHash is a hash of the previous block.
	PrevHash H

	// Timestamp is a nanosecond-precision timestamp
	Timestamp uint64
	Nonce     uint64
	// TransactionHashes is a slice of hashes of proposed transactions in the current block.
	TransactionHashes []H
	// MissingTransactions is a slice of hashes containing missing transactions for the current block.
	MissingTransactions []H
	// Transactions is a map containing actual transactions for the current block.
	Transactions map[H]Transaction[H]

	// PreparationPayloads stores consensus Prepare* payloads for the current epoch.
	PreparationPayloads []ConsensusPayload[H]
	// CommitPayloads stores consensus Commit payloads sent throughout all epochs. It
	// is assumed that valid Commit payload can only be sent once by a single node per
	// the whole set of consensus epochs for particular block. Invalid commit payloads
	// are kicked off this list immediately (if PrepareRequest was received for the
	// current round, so it's possible to verify Commit against it) or stored till
	// the corresponding PrepareRequest receiving.
	CommitPayloads []ConsensusPayload[H]
	// ChangeViewPayloads stores consensus ChangeView payloads for the current epoch.
	ChangeViewPayloads []ConsensusPayload[H]
	// LastChangeViewPayloads stores consensus ChangeView payloads for the last epoch.
	LastChangeViewPayloads []ConsensusPayload[H]
	// LastSeenMessage array stores the height and view of the last seen message, for each validator.
	// If this node never heard a thing from validator i, LastSeenMessage[i] will be nil.
	LastSeenMessage []*HeightView
	// contains filtered or unexported fields
}

Context is a main dBFT structure which contains all information needed for performing transitions.

func (*Context[H]) BlockSent

func (c *Context[H]) BlockSent() bool

BlockSent returns true iff block was formed AND sent for the current height. Once block is sent, the consensus stops new transactions and messages processing as far as timeouts handling.

Implementation note: the implementation of BlockSent differs from the C#'s one. In C# algorithm they use ConsensusContext's Block.Transactions null check to define whether block was formed, and the only place where the block can be formed is in the ConsensusContext's CreateBlock function right after enough Commits receiving. On the contrary, in our implementation we don't have access to the block's Transactions field as far as we can't use block null check, because there are several places where the call to CreateBlock happens (one of them is right after PrepareRequest receiving). Thus, we have a separate Context.blockProcessed field for the described purpose.

func (*Context[H]) CommitSent

func (c *Context[H]) CommitSent() bool

CommitSent returns true iff Commit message was sent for the current epoch assuming that the node can't go further than current epoch after commit was sent.

func (*Context[H]) CountCommitted

func (c *Context[H]) CountCommitted() (count int)

CountCommitted returns number of received Commit messages not only for the current epoch but also for any other epoch.

func (*Context[H]) CountFailed

func (c *Context[H]) CountFailed() (count int)

CountFailed returns number of nodes with which no communication was performed for this view and that hasn't sent the Commit message at the previous views.

func (*Context[H]) CreateBlock

func (c *Context[H]) CreateBlock() Block[H]

CreateBlock returns resulting block for the current epoch.

func (*Context[H]) F

func (c *Context[H]) F() int

F returns number of validators which can be faulty.

func (*Context[H]) Fill

func (c *Context[H]) Fill()

Fill initializes consensus when node is a speaker.

func (*Context[H]) GetPrimaryIndex

func (c *Context[H]) GetPrimaryIndex(viewNumber byte) uint

GetPrimaryIndex returns index of a primary node for the specified view.

func (*Context[H]) IsBackup

func (c *Context[H]) IsBackup() bool

IsBackup returns true iff node is backup for current height and view.

func (*Context[H]) IsPrimary

func (c *Context[H]) IsPrimary() bool

IsPrimary returns true iff node is primary for current height and view.

func (*Context[H]) M

func (c *Context[H]) M() int

M returns number of validators which must function correctly.

func (*Context[H]) MakeHeader

func (c *Context[H]) MakeHeader() Block[H]

MakeHeader returns half-filled block for the current epoch. All hashable fields will be filled.

func (*Context[H]) MoreThanFNodesCommittedOrLost

func (c *Context[H]) MoreThanFNodesCommittedOrLost() bool

MoreThanFNodesCommittedOrLost returns true iff a number of nodes which either committed or are faulty is more than maximum amount of allowed faulty nodes. A possible attack can happen if the last node to commit is malicious and either sends change view after his commit to stall nodes in a higher view, or if he refuses to send recovery messages. In addition, if a node asking change views loses network or crashes and comes back when nodes are committed in more than one higher numbered view, it is possible for the node accepting recovery to commit in any of the higher views, thus potentially splitting nodes among views and stalling the network.

func (*Context[H]) N

func (c *Context[H]) N() int

N returns total number of validators.

func (*Context[H]) NotAcceptingPayloadsDueToViewChanging

func (c *Context[H]) NotAcceptingPayloadsDueToViewChanging() bool

NotAcceptingPayloadsDueToViewChanging returns true if node should not accept new payloads.

func (*Context[H]) RequestSentOrReceived

func (c *Context[H]) RequestSentOrReceived() bool

RequestSentOrReceived returns true iff PrepareRequest was sent or received for the current epoch.

func (*Context[H]) ResponseSent

func (c *Context[H]) ResponseSent() bool

ResponseSent returns true iff Prepare* message was sent for the current epoch.

func (*Context[H]) ViewChanging

func (c *Context[H]) ViewChanging() bool

ViewChanging returns true iff node is in a process of changing view.

func (*Context[H]) WatchOnly

func (c *Context[H]) WatchOnly() bool

WatchOnly returns true iff node takes no active part in consensus.

type DBFT

type DBFT[H Hash] struct {
	Context[H]
	Config[H]

	*sync.Mutex
	// contains filtered or unexported fields
}

DBFT is a dBFT implementation, it includes Context (main state) and Config (service configuration). Data exposed from these fields is supposed to be read-only, state is changed via methods of this structure.

func New

func New[H Hash](options ...func(config *Config[H])) (*DBFT[H], error)

New returns new DBFT instance with specified H and A generic parameters using provided options or nil and error if some of the options are missing or invalid. H and A generic parameters are used as hash and address representation for dBFT consensus messages, blocks and transactions.

func (*DBFT[H]) Header

func (d *DBFT[H]) Header() Block[H]

Header returns current header from context. May be nil in case if no header is constructed yet. Do not change the resulting header.

func (*DBFT[H]) OnReceive

func (d *DBFT[H]) OnReceive(msg ConsensusPayload[H])

OnReceive advances state machine in accordance with msg.

func (*DBFT[H]) OnTimeout

func (d *DBFT[H]) OnTimeout(height uint32, view byte)

OnTimeout advances state machine as if timeout was fired.

func (*DBFT[H]) OnTransaction

func (d *DBFT[H]) OnTransaction(tx Transaction[H])

OnTransaction notifies service about receiving new transaction.

func (*DBFT[H]) Reset

func (d *DBFT[H]) Reset(ts uint64)

Reset reinitializes dBFT instance with the given timestamp of the previous block. It's used if the current consensus state is outdated which happens after new block is processed by ledger (the block can come from dBFT or be received by other means). The height is to be derived from the configured CurrentHeight callback and view will be set to 0.

func (*DBFT[H]) Start

func (d *DBFT[H]) Start(ts uint64)

Start initializes dBFT instance and starts the protocol if node is primary. It accepts the timestamp of the previous block. It should be called once per DBFT lifetime.

type Hash

type Hash interface {
	comparable
	fmt.Stringer
}

Hash is a generic hash interface used by dbft for payloads, blocks and transactions identification. It is recommended to implement this interface using hash functions with low hash collision probability. The following requirements must be met: 1. Hashes of two equal payloads/blocks/transactions are equal. 2. Hashes of two different payloads/blocks/transactions are different.

type HeightView

type HeightView struct {
	Height uint32
	View   byte
}

HeightView is a block height/consensus view pair.

type MessageType

type MessageType byte

MessageType is a type for dBFT consensus messages.

const (
	ChangeViewType      MessageType = 0x00
	PrepareRequestType  MessageType = 0x20
	PrepareResponseType MessageType = 0x21
	CommitType          MessageType = 0x30
	RecoveryRequestType MessageType = 0x40
	RecoveryMessageType MessageType = 0x41
)

6 following constants enumerate all possible type of consensus message.

func (MessageType) String

func (m MessageType) String() string

String implements fmt.Stringer interface.

type PrepareRequest

type PrepareRequest[H Hash] interface {
	// Timestamp returns this message's timestamp.
	Timestamp() uint64
	// Nonce is a random nonce.
	Nonce() uint64
	// TransactionHashes returns hashes of all transaction in a proposed block.
	TransactionHashes() []H
}

PrepareRequest represents dBFT PrepareRequest message.

type PrepareResponse

type PrepareResponse[H Hash] interface {
	// PreparationHash returns the hash of PrepareRequest payload
	// for this epoch.
	PreparationHash() H
}

PrepareResponse represents dBFT PrepareResponse message.

type PrivateKey

type PrivateKey interface {
	// Sign returns msg's signature and error on failure.
	Sign(msg []byte) (sig []byte, err error)
}

PrivateKey is a generic private key interface used by dbft.

type PublicKey

type PublicKey any

PublicKey is a generic public key interface used by dbft.

type RecoveryMessage

type RecoveryMessage[H Hash] interface {
	// AddPayload adds payload from this epoch to be recovered.
	AddPayload(p ConsensusPayload[H])
	// GetPrepareRequest returns PrepareRequest to be processed.
	GetPrepareRequest(p ConsensusPayload[H], validators []PublicKey, primary uint16) ConsensusPayload[H]
	// GetPrepareResponses returns a slice of PrepareResponse in any order.
	GetPrepareResponses(p ConsensusPayload[H], validators []PublicKey) []ConsensusPayload[H]
	// GetChangeViews returns a slice of ChangeView in any order.
	GetChangeViews(p ConsensusPayload[H], validators []PublicKey) []ConsensusPayload[H]
	// GetCommits returns a slice of Commit in any order.
	GetCommits(p ConsensusPayload[H], validators []PublicKey) []ConsensusPayload[H]

	// PreparationHash returns has of PrepareRequest payload for this epoch.
	// It can be useful in case only PrepareResponse payloads were received.
	PreparationHash() *H
}

RecoveryMessage represents dBFT Recovery message.

type RecoveryRequest

type RecoveryRequest interface {
	// Timestamp returns this message's timestamp.
	Timestamp() uint64
}

RecoveryRequest represents dBFT RecoveryRequest message.

type Timer

type Timer interface {
	// Now returns current time.
	Now() time.Time
	// Reset resets timer to the specified block height and view.
	Reset(height uint32, view byte, d time.Duration)
	// Sleep stops execution for duration d.
	Sleep(d time.Duration)
	// Extend extends current timer with duration d.
	Extend(d time.Duration)
	// Stop stops timer.
	Stop()
	// Height returns current height set for the timer.
	Height() uint32
	// View returns current view set for the timer.
	View() byte
	// C returns channel for timer events.
	C() <-chan time.Time
}

Timer is an interface which implements all time-related functions. It can be mocked for testing.

type Transaction

type Transaction[H Hash] interface {
	// Hash must return cryptographic hash of the transaction.
	// Transactions which have equal hashes are considered equal.
	Hash() H
}

Transaction is a generic transaction interface.

Directories

Path Synopsis
internal
Package timer contains default implementation of [dbft.Timer] interface and provides all necessary timer-related functionality to [dbft.DBFT] service.
Package timer contains default implementation of [dbft.Timer] interface and provides all necessary timer-related functionality to [dbft.DBFT] service.

Jump to

Keyboard shortcuts

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