Documentation
¶
Index ¶
- func WithBroadcast[H Hash](f func(m ConsensusPayload[H])) func(config *Config[H])
- func WithCurrentBlockHash[H Hash](f func() H) func(config *Config[H])
- func WithCurrentHeight[H Hash](f func() uint32) func(config *Config[H])
- func WithGetBlock[H Hash](f func(h H) Block[H]) func(config *Config[H])
- func WithGetKeyPair[H Hash](f func(pubs []PublicKey) (int, PrivateKey, PublicKey)) func(config *Config[H])
- func WithGetTx[H Hash](f func(h H) Transaction[H]) func(config *Config[H])
- func WithGetValidators[H Hash](f func(txs ...Transaction[H]) []PublicKey) func(config *Config[H])
- func WithGetVerified[H Hash](f func() []Transaction[H]) func(config *Config[H])
- func WithLogger[H Hash](log *zap.Logger) func(config *Config[H])
- func WithNewBlockFromContext[H Hash](f func(ctx *Context[H]) Block[H]) func(config *Config[H])
- func WithNewChangeView[H Hash](f func(newViewNumber byte, reason ChangeViewReason, ts uint64) ChangeView) func(config *Config[H])
- func WithNewCommit[H Hash](f func(signature []byte) Commit) func(config *Config[H])
- func WithNewConsensusPayload[H Hash](f func(ctx *Context[H], typ MessageType, msg any) ConsensusPayload[H]) func(config *Config[H])
- func WithNewPrepareRequest[H Hash](f func(ts uint64, nonce uint64, transactionsHashes []H) PrepareRequest[H]) func(config *Config[H])
- func WithNewPrepareResponse[H Hash](f func(preparationHash H) PrepareResponse[H]) func(config *Config[H])
- func WithNewRecoveryMessage[H Hash](f func() RecoveryMessage[H]) func(config *Config[H])
- func WithNewRecoveryRequest[H Hash](f func(ts uint64) RecoveryRequest) func(config *Config[H])
- func WithProcessBlock[H Hash](f func(b Block[H])) func(config *Config[H])
- func WithRequestTx[H Hash](f func(h ...H)) func(config *Config[H])
- func WithSecondsPerBlock[H Hash](d time.Duration) func(config *Config[H])
- func WithStopTxFlow[H Hash](f func()) func(config *Config[H])
- func WithTimer[H Hash](t Timer) func(config *Config[H])
- func WithTimestampIncrement[H Hash](u uint64) func(config *Config[H])
- func WithVerifyBlock[H Hash](f func(b Block[H]) bool) func(config *Config[H])
- func WithVerifyPrepareRequest[H Hash](f func(prepareReq ConsensusPayload[H]) error) func(config *Config[H])
- func WithVerifyPrepareResponse[H Hash](f func(prepareResp ConsensusPayload[H]) error) func(config *Config[H])
- func WithWatchOnly[H Hash](f func() bool) func(config *Config[H])
- type Block
- type ChangeView
- type ChangeViewReason
- type Commit
- type Config
- type ConsensusMessage
- type ConsensusPayload
- type Context
- func (c *Context[H]) BlockSent() bool
- func (c *Context[H]) CommitSent() bool
- func (c *Context[H]) CountCommitted() (count int)
- func (c *Context[H]) CountFailed() (count int)
- func (c *Context[H]) CreateBlock() Block[H]
- func (c *Context[H]) F() int
- func (c *Context[H]) Fill()
- func (c *Context[H]) GetPrimaryIndex(viewNumber byte) uint
- func (c *Context[H]) IsBackup() bool
- func (c *Context[H]) IsPrimary() bool
- func (c *Context[H]) M() int
- func (c *Context[H]) MakeHeader() Block[H]
- func (c *Context[H]) MoreThanFNodesCommittedOrLost() bool
- func (c *Context[H]) N() int
- func (c *Context[H]) NotAcceptingPayloadsDueToViewChanging() bool
- func (c *Context[H]) RequestSentOrReceived() bool
- func (c *Context[H]) ResponseSent() bool
- func (c *Context[H]) ViewChanging() bool
- func (c *Context[H]) WatchOnly() bool
- type DBFT
- type Hash
- type HeightView
- type MessageType
- type PrepareRequest
- type PrepareResponse
- type PrivateKey
- type PublicKey
- type RecoveryMessage
- type RecoveryRequest
- type Timer
- type Transaction
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 ¶
WithCurrentBlockHash sets CurrentBlockHash.
func WithCurrentHeight ¶
WithCurrentHeight sets CurrentHeight.
func WithGetBlock ¶
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 ¶
WithLogger sets Logger.
func WithNewBlockFromContext ¶
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 ¶
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 ¶
WithProcessBlock sets ProcessBlock.
func WithRequestTx ¶
WithRequestTx sets RequestTx.
func WithSecondsPerBlock ¶
WithSecondsPerBlock sets SecondsPerBlock.
func WithStopTxFlow ¶
WithStopTxFlow sets StopTxFlow.
func WithTimestampIncrement ¶
WithTimestampIncrement sets TimestampIncrement.
func WithVerifyBlock ¶
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 ¶
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 ¶
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 ¶
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 ¶
CountCommitted returns number of received Commit messages not only for the current epoch but also for any other epoch.
func (*Context[H]) CountFailed ¶
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 ¶
CreateBlock returns resulting block for the current epoch.
func (*Context[H]) Fill ¶
func (c *Context[H]) Fill()
Fill initializes consensus when node is a speaker.
func (*Context[H]) GetPrimaryIndex ¶
GetPrimaryIndex returns index of a primary node for the specified view.
func (*Context[H]) IsPrimary ¶
IsPrimary returns true iff node is primary for current height and view.
func (*Context[H]) MakeHeader ¶
MakeHeader returns half-filled block for the current epoch. All hashable fields will be filled.
func (*Context[H]) MoreThanFNodesCommittedOrLost ¶
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]) NotAcceptingPayloadsDueToViewChanging ¶
NotAcceptingPayloadsDueToViewChanging returns true if node should not accept new payloads.
func (*Context[H]) RequestSentOrReceived ¶
RequestSentOrReceived returns true iff PrepareRequest was sent or received for the current epoch.
func (*Context[H]) ResponseSent ¶
ResponseSent returns true iff Prepare* message was sent for the current epoch.
func (*Context[H]) ViewChanging ¶
ViewChanging returns true iff node is in a process of changing view.
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 ¶
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 ¶
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]) OnTransaction ¶
func (d *DBFT[H]) OnTransaction(tx Transaction[H])
OnTransaction notifies service about receiving new transaction.
func (*DBFT[H]) Reset ¶
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.
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 ¶
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 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.
Source Files
¶
- block.go
- change_view.go
- change_view_reason.go
- change_view_reason_string.go
- check.go
- commit.go
- config.go
- consensus_message.go
- consensus_message_type.go
- consensus_payload.go
- context.go
- dbft.go
- helpers.go
- identity.go
- prepare_request.go
- prepare_response.go
- recovery_message.go
- recovery_request.go
- send.go
- timer.go
- transaction.go
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. |