Documentation ¶
Index ¶
- Constants
- Variables
- func ControllerIdToMessageID(identifier []byte) types.MessageID
- func HasPartialQuorum(share *types.Share, msgs []*SignedMessage) bool
- func HasQuorum(share *types.Share, msgs []*SignedMessage) bool
- func IsDecidedMsg(share *types.Share, signedDecided *SignedMessage) bool
- func RoundRobinProposer(state *State, round Round) types.OperatorID
- func ValidateDecided(config IConfig, signedDecided *SignedMessage, share *types.Share) error
- func ValidateFutureMsg(config IConfig, msg *SignedMessage, operators []*types.Operator) error
- type CommitData
- type Config
- func (c *Config) GetNetwork() Network
- func (c *Config) GetProposerF() ProposerF
- func (c *Config) GetSignatureDomainType() types.DomainType
- func (c *Config) GetSigner() types.SSVSigner
- func (c *Config) GetSigningPubKey() []byte
- func (c *Config) GetTimer() Timer
- func (c *Config) GetValueCheckF() ProposedValueCheckF
- type Controller
- func (c *Controller) BaseMsgValidation(msg *SignedMessage) error
- func (c *Controller) CanStartInstance() error
- func (c *Controller) Decode(data []byte) error
- func (c *Controller) Encode() ([]byte, error)
- func (c *Controller) GetConfig() IConfig
- func (c *Controller) GetIdentifier() []byte
- func (c *Controller) GetRoot() ([]byte, error)
- func (c *Controller) InstanceForHeight(height Height) *Instance
- func (c *Controller) ProcessMsg(msg *SignedMessage) (*SignedMessage, error)
- func (c *Controller) StartNewInstance(value []byte) error
- func (c *Controller) UponDecided(msg *SignedMessage) (*SignedMessage, error)
- func (c *Controller) UponExistingInstanceMsg(msg *SignedMessage) (*SignedMessage, error)
- func (c *Controller) UponFutureMsg(msg *SignedMessage) (*SignedMessage, error)
- type Height
- type IConfig
- type Instance
- func (i *Instance) BaseMsgValidation(msg *SignedMessage) error
- func (i *Instance) Broadcast(msg *SignedMessage) error
- func (i *Instance) Decode(data []byte) error
- func (i *Instance) Encode() ([]byte, error)
- func (i *Instance) GetConfig() IConfig
- func (i *Instance) GetHeight() Height
- func (i *Instance) GetRoot() ([]byte, error)
- func (i *Instance) IsDecided() (bool, []byte)
- func (i *Instance) ProcessMsg(msg *SignedMessage) (decided bool, decidedValue []byte, aggregatedCommit *SignedMessage, err error)
- func (i *Instance) Start(value []byte, height Height)
- func (i *Instance) UponCommit(signedCommit *SignedMessage, commitMsgContainer *MsgContainer) (bool, []byte, *SignedMessage, error)
- func (i *Instance) UponRoundTimeout() error
- type InstanceContainer
- type Message
- func (msg *Message) Decode(data []byte) error
- func (msg *Message) Encode() ([]byte, error)
- func (msg *Message) GetCommitData() (*CommitData, error)
- func (msg *Message) GetPrepareData() (*PrepareData, error)
- func (msg *Message) GetProposalData() (*ProposalData, error)
- func (msg *Message) GetRoot() ([]byte, error)
- func (msg *Message) GetRoundChangeData() (*RoundChangeData, error)
- func (msg *Message) Validate() error
- type MessageType
- type MsgContainer
- func (c *MsgContainer) AddFirstMsgForSignerAndRound(msg *SignedMessage) (bool, error)
- func (c *MsgContainer) AddMsg(msg *SignedMessage)
- func (c *MsgContainer) AllMessaged() []*SignedMessage
- func (c *MsgContainer) Decode(data []byte) error
- func (c *MsgContainer) Encode() ([]byte, error)
- func (c *MsgContainer) LongestUniqueSignersForRoundAndValue(round Round, value []byte) ([]types.OperatorID, []*SignedMessage)
- func (c *MsgContainer) MessagesForRound(round Round) []*SignedMessage
- func (c *MsgContainer) MessagesForRoundAndValue(round Round, value []byte) []*SignedMessage
- type Network
- type PrepareData
- type ProposalData
- type ProposedValueCheckF
- type ProposerF
- type Round
- type RoundChangeData
- type SignedMessage
- func CreateCommit(state *State, config IConfig, value []byte) (*SignedMessage, error)
- func CreatePrepare(state *State, config IConfig, newRound Round, value []byte) (*SignedMessage, error)
- func CreateProposal(state *State, config IConfig, value []byte, ...) (*SignedMessage, error)
- func CreateRoundChange(state *State, config IConfig, newRound Round, instanceStartValue []byte) (*SignedMessage, error)
- func (signedMsg *SignedMessage) Aggregate(sig types.MessageSignature) error
- func (signedMsg *SignedMessage) CommonSigners(ids []types.OperatorID) bool
- func (signedMsg *SignedMessage) Decode(data []byte) error
- func (signedMsg *SignedMessage) DeepCopy() *SignedMessage
- func (signedMsg *SignedMessage) Encode() ([]byte, error)
- func (signedMsg *SignedMessage) GetRoot() ([]byte, error)
- func (signedMsg *SignedMessage) GetSignature() types.Signature
- func (signedMsg *SignedMessage) GetSigners() []types.OperatorID
- func (signedMsg *SignedMessage) MatchedSigners(ids []types.OperatorID) bool
- func (signedMsg *SignedMessage) Validate() error
- type State
- type Syncer
- type Timer
Constants ¶
const ( NoRound Round = 0 // NoRound represents a nil/ zero round FirstRound Round = 1 // FirstRound value is the first round in any QBFT instance start FirstHeight Height = 0 )
Variables ¶
var SignMsg = func(sk *bls.SecretKey, id types.OperatorID, msg *Message) *SignedMessage { domain := types.PrimusTestnet sigType := types.QBFTSignatureType r, _ := types.ComputeSigningRoot(msg, types.ComputeSignatureDomain(domain, sigType)) sig := sk.SignByte(r) return &SignedMessage{ Message: msg, Signers: []types.OperatorID{id}, Signature: sig.Serialize(), } }
var TestingMessage = &Message{ MsgType: ProposalMsgType, Height: FirstHeight, Round: FirstRound, Identifier: []byte{1, 2, 3, 4}, Data: []byte{1, 2, 3, 4}, }
Functions ¶
func ControllerIdToMessageID ¶
func HasPartialQuorum ¶
func HasPartialQuorum(share *types.Share, msgs []*SignedMessage) bool
HasPartialQuorum returns true if a unique set of signers has partial quorum
func HasQuorum ¶
func HasQuorum(share *types.Share, msgs []*SignedMessage) bool
HasQuorum returns true if a unique set of signers has quorum
func IsDecidedMsg ¶
func IsDecidedMsg(share *types.Share, signedDecided *SignedMessage) bool
IsDecidedMsg returns true if signed commit has all quorum sigs
func RoundRobinProposer ¶
func RoundRobinProposer(state *State, round Round) types.OperatorID
RoundRobinProposer returns the proposer for the round. Each new height starts with the first proposer and increments by 1 with each following round. Each new height has a different first round proposer which is +1 from the previous height. First height starts with index 0
func ValidateDecided ¶
func ValidateDecided( config IConfig, signedDecided *SignedMessage, share *types.Share, ) error
func ValidateFutureMsg ¶
func ValidateFutureMsg( config IConfig, msg *SignedMessage, operators []*types.Operator, ) error
Types ¶
type CommitData ¶
type CommitData struct {
Data []byte
}
func (*CommitData) Decode ¶
func (d *CommitData) Decode(data []byte) error
Decode returns error if decoding failed
func (*CommitData) Encode ¶
func (d *CommitData) Encode() ([]byte, error)
Encode returns a msg encoded bytes or error
func (*CommitData) Validate ¶
func (d *CommitData) Validate() error
Validate returns error if msg validation doesn't pass. Msg validation checks the msg, it's variables for validity.
type Config ¶
type Config struct { Signer types.SSVSigner SigningPK []byte Domain types.DomainType ValueCheckF ProposedValueCheckF ProposerF ProposerF Network Network Timer Timer }
func (*Config) GetNetwork ¶
GetNetwork returns a p2p Network instance
func (*Config) GetProposerF ¶
GetProposerF returns func used to calculate proposer
func (*Config) GetSignatureDomainType ¶
func (c *Config) GetSignatureDomainType() types.DomainType
GetSignatureDomainType returns the Domain type used for signatures
func (*Config) GetSigningPubKey ¶
GetSigningPubKey returns the public key used to sign all QBFT messages
func (*Config) GetValueCheckF ¶
func (c *Config) GetValueCheckF() ProposedValueCheckF
GetValueCheckF returns value check instance
type Controller ¶
type Controller struct { Identifier []byte Height Height // incremental Height for InstanceContainer // StoredInstances stores the last HistoricalInstanceCapacity in an array for message processing purposes. StoredInstances InstanceContainer // FutureMsgsContainer holds all msgs from a higher height FutureMsgsContainer map[types.OperatorID]Height // maps msg signer to height of higher height received msgs Domain types.DomainType // contains filtered or unexported fields }
Controller is a QBFT coordinator responsible for starting and following the entire life cycle of multiple QBFT InstanceContainer
func NewController ¶
func NewController( identifier []byte, share *types.Share, domain types.DomainType, config IConfig, ) *Controller
func (*Controller) BaseMsgValidation ¶
func (c *Controller) BaseMsgValidation(msg *SignedMessage) error
BaseMsgValidation returns error if msg is invalid (base validation)
func (*Controller) CanStartInstance ¶
func (c *Controller) CanStartInstance() error
CanStartInstance returns nil if controller can start a new instance
func (*Controller) GetConfig ¶
func (c *Controller) GetConfig() IConfig
func (*Controller) GetIdentifier ¶
func (c *Controller) GetIdentifier() []byte
GetIdentifier returns QBFT Identifier, used to identify messages
func (*Controller) GetRoot ¶
func (c *Controller) GetRoot() ([]byte, error)
GetRoot returns the state's deterministic root
func (*Controller) InstanceForHeight ¶
func (c *Controller) InstanceForHeight(height Height) *Instance
func (*Controller) ProcessMsg ¶
func (c *Controller) ProcessMsg(msg *SignedMessage) (*SignedMessage, error)
ProcessMsg processes a new msg, returns decided message or error
func (*Controller) StartNewInstance ¶
func (c *Controller) StartNewInstance(value []byte) error
StartNewInstance will start a new QBFT instance, if can't will return error
func (*Controller) UponDecided ¶
func (c *Controller) UponDecided(msg *SignedMessage) (*SignedMessage, error)
UponDecided returns decided msg if decided, nil otherwise
func (*Controller) UponExistingInstanceMsg ¶
func (c *Controller) UponExistingInstanceMsg(msg *SignedMessage) (*SignedMessage, error)
func (*Controller) UponFutureMsg ¶
func (c *Controller) UponFutureMsg(msg *SignedMessage) (*SignedMessage, error)
type IConfig ¶
type IConfig interface { // GetValueCheckF returns value check function GetValueCheckF() ProposedValueCheckF // GetProposerF returns func used to calculate proposer GetProposerF() ProposerF // GetNetwork returns a p2p Network instance GetNetwork() Network // GetTimer returns round timer GetTimer() Timer // contains filtered or unexported methods }
type Instance ¶
Instance is a single QBFT instance that starts with a Start call (including a value). Every new msg the ProcessMsg function needs to be called
func NewInstance ¶
func (*Instance) BaseMsgValidation ¶
func (i *Instance) BaseMsgValidation(msg *SignedMessage) error
func (*Instance) Broadcast ¶
func (i *Instance) Broadcast(msg *SignedMessage) error
func (*Instance) ProcessMsg ¶
func (i *Instance) ProcessMsg(msg *SignedMessage) (decided bool, decidedValue []byte, aggregatedCommit *SignedMessage, err error)
ProcessMsg processes a new QBFT msg, returns non nil error on msg processing error
func (*Instance) UponCommit ¶
func (i *Instance) UponCommit(signedCommit *SignedMessage, commitMsgContainer *MsgContainer) (bool, []byte, *SignedMessage, error)
UponCommit returns true if a quorum of commit messages was received. Assumes commit message is valid!
func (*Instance) UponRoundTimeout ¶
type InstanceContainer ¶
type InstanceContainer []*Instance
func (InstanceContainer) FindInstance ¶
func (i InstanceContainer) FindInstance(height Height) *Instance
type Message ¶
type Message struct { MsgType MessageType Height Height // QBFT instance Height Round Round // QBFT round for which the msg is for Identifier []byte // instance Identifier this msg belongs to Data []byte }
func (*Message) GetCommitData ¶
func (msg *Message) GetCommitData() (*CommitData, error)
GetCommitData returns commit specific data
func (*Message) GetPrepareData ¶
func (msg *Message) GetPrepareData() (*PrepareData, error)
GetPrepareData returns prepare specific data
func (*Message) GetProposalData ¶
func (msg *Message) GetProposalData() (*ProposalData, error)
GetProposalData returns proposal specific data
func (*Message) GetRoundChangeData ¶
func (msg *Message) GetRoundChangeData() (*RoundChangeData, error)
GetRoundChangeData returns round change specific data
type MessageType ¶
type MessageType int
const ( ProposalMsgType MessageType = iota PrepareMsgType CommitMsgType RoundChangeMsgType )
type MsgContainer ¶
type MsgContainer struct {
Msgs map[Round][]*SignedMessage
}
func NewMsgContainer ¶
func NewMsgContainer() *MsgContainer
func (*MsgContainer) AddFirstMsgForSignerAndRound ¶
func (c *MsgContainer) AddFirstMsgForSignerAndRound(msg *SignedMessage) (bool, error)
AddFirstMsgForSignerAndRound will add the first msg for each signer for a specific round, consequent msgs will not be added
func (*MsgContainer) AddMsg ¶
func (c *MsgContainer) AddMsg(msg *SignedMessage)
AddMsg will add any message regardless of signers
func (*MsgContainer) AllMessaged ¶
func (c *MsgContainer) AllMessaged() []*SignedMessage
AllMessaged returns all messages
func (*MsgContainer) Decode ¶
func (c *MsgContainer) Decode(data []byte) error
Decode returns error if decoding failed
func (*MsgContainer) Encode ¶
func (c *MsgContainer) Encode() ([]byte, error)
Encode returns the encoded struct in bytes or error
func (*MsgContainer) LongestUniqueSignersForRoundAndValue ¶
func (c *MsgContainer) LongestUniqueSignersForRoundAndValue(round Round, value []byte) ([]types.OperatorID, []*SignedMessage)
LongestUniqueSignersForRoundAndValue returns the longest set of unique signers and msgs for a specific round and value
func (*MsgContainer) MessagesForRound ¶
func (c *MsgContainer) MessagesForRound(round Round) []*SignedMessage
MessagesForRound returns all msgs for Height and round, empty slice otherwise
func (*MsgContainer) MessagesForRoundAndValue ¶
func (c *MsgContainer) MessagesForRoundAndValue(round Round, value []byte) []*SignedMessage
MessagesForRoundAndValue returns all msgs for round and value, empty slice otherwise
type Network ¶
type Network interface { Syncer p2p.Broadcaster }
Network is the interface for networking across QBFT components
type PrepareData ¶
type PrepareData struct {
Data []byte
}
func (*PrepareData) Decode ¶
func (d *PrepareData) Decode(data []byte) error
Decode returns error if decoding failed
func (*PrepareData) Encode ¶
func (d *PrepareData) Encode() ([]byte, error)
Encode returns a msg encoded bytes or error
func (*PrepareData) Validate ¶
func (d *PrepareData) Validate() error
Validate returns error if msg validation doesn't pass. Msg validation checks the msg, it's variables for validity.
type ProposalData ¶
type ProposalData struct { Data []byte RoundChangeJustification []*SignedMessage PrepareJustification []*SignedMessage }
func (*ProposalData) Decode ¶
func (d *ProposalData) Decode(data []byte) error
Decode returns error if decoding failed
func (*ProposalData) Encode ¶
func (d *ProposalData) Encode() ([]byte, error)
Encode returns a msg encoded bytes or error
func (*ProposalData) Validate ¶
func (d *ProposalData) Validate() error
Validate returns error if msg validation doesn't pass. Msg validation checks the msg, it's variables for validity.
type ProposedValueCheckF ¶
type RoundChangeData ¶
type RoundChangeData struct { PreparedValue []byte PreparedRound Round RoundChangeJustification []*SignedMessage }
func (*RoundChangeData) Decode ¶
func (d *RoundChangeData) Decode(data []byte) error
Decode returns error if decoding failed
func (*RoundChangeData) Encode ¶
func (d *RoundChangeData) Encode() ([]byte, error)
Encode returns a msg encoded bytes or error
func (*RoundChangeData) Prepared ¶
func (d *RoundChangeData) Prepared() bool
func (*RoundChangeData) Validate ¶
func (d *RoundChangeData) Validate() error
Validate returns error if msg validation doesn't pass. Msg validation checks the msg, it's variables for validity.
type SignedMessage ¶
type SignedMessage struct { Signature types.Signature Signers []types.OperatorID Message *Message // message for which this signature is for }
func CreateCommit ¶
func CreateCommit(state *State, config IConfig, value []byte) (*SignedMessage, error)
CreateCommit * Commit(
signCommit( UnsignedCommit( |current.blockchain|, current.round, signHash(hashBlockForCommitSeal(proposedBlock), current.id), digest(proposedBlock)), current.id ) );
func CreatePrepare ¶
func CreatePrepare(state *State, config IConfig, newRound Round, value []byte) (*SignedMessage, error)
CreatePrepare * Prepare(
signPrepare( UnsignedPrepare( |current.blockchain|, newRound, digest(m.proposedBlock)), current.id ) );
func CreateProposal ¶
func CreateProposal(state *State, config IConfig, value []byte, roundChanges, prepares []*SignedMessage) (*SignedMessage, error)
CreateProposal *
Proposal( signProposal( UnsignedProposal( |current.blockchain|, newRound, digest(block)), current.id), block, extractSignedRoundChanges(roundChanges), extractSignedPrepares(prepares));
func CreateRoundChange ¶
func CreateRoundChange(state *State, config IConfig, newRound Round, instanceStartValue []byte) (*SignedMessage, error)
CreateRoundChange * RoundChange(
signRoundChange( UnsignedRoundChange( |current.blockchain|, newRound, digestOptionalBlock(current.lastPreparedBlock), current.lastPreparedRound), current.id), current.lastPreparedBlock, getRoundChangeJustification(current) )
func (*SignedMessage) Aggregate ¶
func (signedMsg *SignedMessage) Aggregate(sig types.MessageSignature) error
Aggregate will aggregate the signed message if possible (unique signers, same digest, valid)
func (*SignedMessage) CommonSigners ¶
func (signedMsg *SignedMessage) CommonSigners(ids []types.OperatorID) bool
CommonSigners returns true if there is at least 1 common signer
func (*SignedMessage) Decode ¶
func (signedMsg *SignedMessage) Decode(data []byte) error
Decode returns error if decoding failed
func (*SignedMessage) DeepCopy ¶
func (signedMsg *SignedMessage) DeepCopy() *SignedMessage
DeepCopy returns a new instance of SignedMessage, deep copied
func (*SignedMessage) Encode ¶
func (signedMsg *SignedMessage) Encode() ([]byte, error)
Encode returns a msg encoded bytes or error
func (*SignedMessage) GetRoot ¶
func (signedMsg *SignedMessage) GetRoot() ([]byte, error)
GetRoot returns the root used for signing and verification
func (*SignedMessage) GetSignature ¶
func (signedMsg *SignedMessage) GetSignature() types.Signature
func (*SignedMessage) GetSigners ¶
func (signedMsg *SignedMessage) GetSigners() []types.OperatorID
func (*SignedMessage) MatchedSigners ¶
func (signedMsg *SignedMessage) MatchedSigners(ids []types.OperatorID) bool
MatchedSigners returns true if the provided signer ids are equal to GetSignerIds() without order significance
func (*SignedMessage) Validate ¶
func (signedMsg *SignedMessage) Validate() error
Validate returns error if msg validation doesn't pass. Msg validation checks the msg, it's variables for validity.
type State ¶
type State struct { ID []byte // instance Identifier Round Round Height Height LastPreparedRound Round LastPreparedValue []byte ProposalAcceptedForCurrentRound *SignedMessage Decided bool DecidedValue []byte ProposeContainer *MsgContainer PrepareContainer *MsgContainer CommitContainer *MsgContainer RoundChangeContainer *MsgContainer }