Documentation ¶
Overview ¶
Implementation of multi-valued consensus in the likeness of PBFT.
Index ¶
- type MessageState
- func (sms *MessageState) GenerateProofs(sigCount int, round types.ConsensusRound, _ types.BinVal, pub sig.Pub, ...) (messages.MsgHeader, error)
- func (sms *MessageState) GetValidMessageCount(round types.ConsensusRound) (echoMsgCount, commitMsgCount int)
- func (sms *MessageState) GotMsg(hdrFunc consinterface.HeaderFunc, deser *deserialized.DeserializedItem, ...) ([]*deserialized.DeserializedItem, error)
- func (sms *MessageState) New(idx types.ConsensusIndex) consinterface.MessageState
- type MvCons2
- func (sc *MvCons2) CanStartNext() bool
- func (sc *MvCons2) Collect()
- func (*MvCons2) GenerateMessageState(gc *generalconfig.GeneralConfig) consinterface.MessageState
- func (*MvCons2) GenerateNewItem(index types.ConsensusIndex, items *consinterface.ConsInterfaceItems, ...) consinterface.ConsItem
- func (sc *MvCons2) GetBinState(localOnly bool) ([]byte, error)
- func (sc *MvCons2) GetBufferCount(hdr messages.MsgIDHeader, _ *generalconfig.GeneralConfig, ...) (int, int, messages.MsgID, error)
- func (sc *MvCons2) GetCommitProof() []messages.MsgHeader
- func (sc *MvCons2) GetConsType() types.ConsType
- func (sc *MvCons2) GetDecision() (sig.Pub, []byte, types.ConsensusIndex, types.ConsensusIndex)
- func (*MvCons2) GetHeader(emptyPub sig.Pub, gc *generalconfig.GeneralConfig, ...) (messages.MsgHeader, error)
- func (sc *MvCons2) GetNextInfo() (prevIdx types.ConsensusIndex, proposer sig.Pub, preDecision []byte, ...)
- func (sc *MvCons2) GetPrevCommitProof() (cordPub sig.Pub, proof []messages.MsgHeader)
- func (sc *MvCons2) GetProposalIndex() (prevIdx types.ConsensusIndex, ready bool)
- func (sc *MvCons2) GetProposeHeaderID() messages.HeaderID
- func (sc *MvCons2) GotProposal(hdr messages.MsgHeader, mainChannel channelinterface.MainChannel) error
- func (sc *MvCons2) HasDecided() bool
- func (sc *MvCons2) HasValidStarted() bool
- func (sc *MvCons2) NeedsCompletionConcurrentProposals() types.ConsensusInt
- func (sc *MvCons2) PrevHasBeenReset()
- func (sc *MvCons2) ProcessMessage(deser *deserialized.DeserializedItem, isLocal bool, ...) (bool, bool)
- func (sc *MvCons2) SetInitialState([]byte, storage.StoreInterface)
- func (sc *MvCons2) SetNextConsItem(consinterface.ConsItem)
- func (sc *MvCons2) ShouldCreatePartial(headerType messages.HeaderID) bool
- func (sc *MvCons2) Start(finishedLastRound bool)
- type MvCons2Config
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type MessageState ¶
type MessageState struct { *messagestate.SimpleMessageStateWrapper // the simple message state is used to track the actual messages // contains filtered or unexported fields }
MvCons2Message state stores the message of MvCons, including that of the binary consesnsus that it reduces to.
func NewMvCons2MessageState ¶
func NewMvCons2MessageState(gc *generalconfig.GeneralConfig) *MessageState
NewMvCons2MessageState generates a new MvCons2MessageStateObject.
func (*MessageState) GenerateProofs ¶
func (sms *MessageState) GenerateProofs(sigCount int, round types.ConsensusRound, _ types.BinVal, pub sig.Pub, mc *consinterface.MemCheckers) (messages.MsgHeader, error)
Generate proofs returns a signed message with signatures supporting the input values, it can be a MvEchoMessage.
func (*MessageState) GetValidMessageCount ¶
func (sms *MessageState) GetValidMessageCount(round types.ConsensusRound) (echoMsgCount, commitMsgCount int)
GetValidMessage count returns the number of signed echo and commit messages received from different processes in round round.
func (*MessageState) GotMsg ¶
func (sms *MessageState) GotMsg(hdrFunc consinterface.HeaderFunc, deser *deserialized.DeserializedItem, gc *generalconfig.GeneralConfig, mc *consinterface.MemCheckers) ([]*deserialized.DeserializedItem, error)
GotMessage takes a deserialized message and the member checker for the current consensus index. If the message contains no new valid signatures then an error is returned. The value newTotalSigCount is the new number of signatures for the specific message, the value newMsgIDSigCount is the number of signatures for the MsgID of the message (see messages.MsgID). The valid message types are (1) HdrMvInit - the leaders proposal, here is ensures the message comes from the correct leader (2) HdrMvEcho - echo messages (3) HdrMvCommit - commit messages (4) HdrMvRequestRecover - unsigned message asking for the init message received for a given hash
func (*MessageState) New ¶
func (sms *MessageState) New(idx types.ConsensusIndex) consinterface.MessageState
New inits and returns a new MvCons2MessageState object for the given consensus index.
type MvCons2 ¶
type MvCons2 struct { cons.AbsConsItem cons.AbsMVRecover // contains filtered or unexported fields }
MvCons2 is a simple rotating-coordinator-based multi-value consensus. Assuming the coordinator is correct and the timeout configured correctly, termination happens in 3 message steps. Otherwise a "view change" happens where the next coordinator proposes a value (it can be a new value if it has proof that no value was decided previously, otherwise it must be a value that was previously proposed). The consensus executes in round each with the following steps. (1) an init message broadcast from the leader (2) an all to all echo message containing the hash of the init if the init is a valid message (3) an all to all commit message If a timeout runs out between (1) and (2), then a node broadcasts an echo message with a zero hash. Following the first round, nodes only support valid init/echo messages as follows: (1) n-t commit messages supporting 0 from the previous round, then an echo with any hash is valid (2) n-t echo messages supporting a value from the previous round, then an echo with this value is valid Furthermore we only pass to the this round when one of these conditions is valid.
decision (termination) we decide when n-t non-zero commit
safety - if we get n-t commit 0, then no-one decided - because no one got n-t different value commit by majority - if we don't get n-t commit 0, then a non-faulty must have gotten n-t same echo, so we support this - we can only get n-t echo/commit of a single value (by 2/3 majority)
livness - leader changes each round by rotating coordinator (a) we go from init to echo on timeout (if we have no echo to send we send nothing) (b) we go from echo to commit on timeout (c) we proceed to next round if we get n-t echo and commit, where either n-t commit 0, or n-t same echo. (d) if we are leader for round then we use the messages that passed condition (c) to send init proofs == a, b are always true by timer, c by follows: if a non-faulty gets n-t same echo it sends commit with a val, otherwise it sends commit with a 0. Now all non-faulty will get n-t commit 0, or n-t echo, since non-faulty send all info on timeout (or include proofs). Now all will have proofs for the next round. Will eventually reach a round with fast enough and correct leader by increasing timeout => termination If a non-faulty node terminated in a previous round, then all will eventually terminate as it broadcasts all msgs received so far which is enough for all nodes to terminate.
func (*MvCons2) CanStartNext ¶
CanStartNext should return true if it is safe to start the next consensus instance (if parallel instances are enabled)
func (*MvCons2) Collect ¶
func (sc *MvCons2) Collect()
Collect is called when the item is being garbage collected.
func (*MvCons2) GenerateMessageState ¶
func (*MvCons2) GenerateMessageState(gc *generalconfig.GeneralConfig) consinterface.MessageState
GenerateMessageState generates a new message state object given the inputs.
func (*MvCons2) GenerateNewItem ¶
func (*MvCons2) GenerateNewItem(index types.ConsensusIndex, items *consinterface.ConsInterfaceItems, mainChannel channelinterface.MainChannel, prevItem consinterface.ConsItem, broadcastFunc consinterface.ByzBroadcastFunc, gc *generalconfig.GeneralConfig) consinterface.ConsItem
GenerateNewItem creates a new cons item.
func (*MvCons2) GetBinState ¶
GetBinState returns the entire state of the consensus as a string of bytes using MessageState.GetMsgState() as the list of all messages, with a messagetypes.ConsBinStateMessage header appended to the beginning).
func (*MvCons2) GetBufferCount ¶
func (sc *MvCons2) GetBufferCount(hdr messages.MsgIDHeader, _ *generalconfig.GeneralConfig, memberChecker *consinterface.MemCheckers) (int, int, messages.MsgID, error)
GetBufferCount checks a MessageID and returns the thresholds for which it should be forwarded using the BufferForwarder (see forwardchecker.ForwardChecker interface). The messages are: (1) HdrMvInit returns 0, 0 if generalconfig.MvBroadcastInitForBufferForwarder is true (meaning don't forward the message)
otherwise returns 1, 1 (meaning forward the message right away)
(2) HdrMvEcho returns n-t, n for the thresholds. (3) HdrMvCommit returns n-t, n for the thresholds.
func (*MvCons2) GetCommitProof ¶
GetCommitProof returns a signed message header that counts at the commit message for this consensus.
func (*MvCons2) GetConsType ¶
GetConsType returns the type of consensus this instance implements.
func (*MvCons2) GetDecision ¶
func (sc *MvCons2) GetDecision() (sig.Pub, []byte, types.ConsensusIndex, types.ConsensusIndex)
GetDecision returns the decided value as a byte slice.
func (*MvCons2) GetHeader ¶
func (*MvCons2) GetHeader(emptyPub sig.Pub, gc *generalconfig.GeneralConfig, headerType messages.HeaderID) (messages.MsgHeader, error)
GetHeader return blank message header for the HeaderID, this object will be used to deserialize a message into itself (see consinterface.DeserializeMessage). The valid headers are HdrMvInit, HdrMvEcho, HdrMvCommit, HdrMvRequestRecover.
func (*MvCons2) GetNextInfo ¶
func (sc *MvCons2) GetNextInfo() (prevIdx types.ConsensusIndex, proposer sig.Pub, preDecision []byte, hasInfo bool)
GetNextInfo will be called after CanStartNext returns true. It returns sc.Index - 1, nil. If false is returned then the next is started, but the current instance has no state machine created. // TODO
func (*MvCons2) GetPrevCommitProof ¶
GetPrevCommitProof returns a signed message header that counts at the commit message for the previous consensus. This should only be called after DoneKeep has been called on this instance. cordPub is the expected public key of the coordinator of the current round (used for collect broadcast)
func (*MvCons2) GetProposalIndex ¶
func (sc *MvCons2) GetProposalIndex() (prevIdx types.ConsensusIndex, ready bool)
GetProposalIndex returns sc.Index - 1. It returns false until start is called.
func (*MvCons2) GetProposeHeaderID ¶
GetProposeHeaderID returns the HeaderID messages.HdrMvPropose that will be input to GotProposal.
func (*MvCons2) GotProposal ¶
func (sc *MvCons2) GotProposal(hdr messages.MsgHeader, mainChannel channelinterface.MainChannel) error
GotProposal takes the proposal, and broadcasts it if it is the leader.
func (*MvCons2) HasDecided ¶
HasDecided should return true if this consensus item has reached a decision.
func (*MvCons2) HasValidStarted ¶
HasReceivedProposal returns true if the cons has received a valid proposal.
func (*MvCons2) NeedsCompletionConcurrentProposals ¶
func (sc *MvCons2) NeedsCompletionConcurrentProposals() types.ConsensusInt
NeedsConcurrent returns 1.
func (*MvCons2) PrevHasBeenReset ¶
func (sc *MvCons2) PrevHasBeenReset()
PrevHasBeenReset is called when the previous consensus index has been reset to a new index
func (*MvCons2) ProcessMessage ¶
func (sc *MvCons2) ProcessMessage( deser *deserialized.DeserializedItem, isLocal bool, senderChan *channelinterface.SendRecvChannel) (bool, bool)
ProcessMessage is called on every message once it has been checked that it is a valid message (using the static method ConsItem.DerserializeMessage), that it comes from a member of the consensus and that it is not a duplicate message (using the MemberChecker and MessageState objects). This function processes the message and update the state of the consensus. For this consensus implementation messageState must be an instance of BinConsMessageStateInterface. It returns true in first position if made progress towards decision, or false if already decided, and return true in second position if the message should be forwarded. The following are the valid message types: messages.HdrMvInit is the leader proposal, once this is received an echo is sent containing the hash, and starts the echo timeoutout. messages.HdrMvInitTimeout the init timeout is started in GotProposal, if we don't receive a hash before the timeout, we support 0 in bin cons. messages.HdrMvEcho is the echo message, when these are received we run CheckEchoState. messages.HdrMvEchoTimeout once the echo timeout runs out, without receiving n-t equal echo messages, start the commit timeout, otherwise sending a commit message. messages.HdrMvCommit is the commit message, when these are received we run CheckCommitState. messages.HdrMvCommitTimeout once the commit timeout runs out, without receiving n-t equal commit messages, we move to the next round if possible, otherwise we decide. messages.HdrMvRequestRecover a node terminated bin cons with 1, but didn't get the init message, so if we have it we send it. messages.HdrMvRecoverTimeout if a node terminated bin cons with 1, but didn't get the init mesage this timeout is started, once it runs out, we ask other nodes to send the init message.
func (*MvCons2) SetInitialState ¶
func (sc *MvCons2) SetInitialState([]byte, storage.StoreInterface)
SetInitialState does noting for this algorithm.
func (*MvCons2) SetNextConsItem ¶
func (sc *MvCons2) SetNextConsItem(consinterface.ConsItem)
SetNextConsItem gives a pointer to the next consensus item at the next consensus instance, it is called when the next instance is created
func (*MvCons2) ShouldCreatePartial ¶
ShouldCreatePartial returns true if the message type should be sent as a partial message
type MvCons2Config ¶
type MvCons2Config struct {
cons.StandardMvConfig
}