consinterface

package
v0.0.0-...-ff61ee7 Latest Latest
Warning

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

Go to latest
Published: Dec 5, 2020 License: GPL-3.0 Imports: 22 Imported by: 0

Documentation

Overview

The consinterface package defines the interfaces for implementations of the consensus objects. It also contains the core functionalities that will be used by most consensus object, including message tracking, membership checking, and message forwarding.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckCoord

func CheckCoord(pub sig.Pub, mc *MemCheckers, rnd types.ConsensusRound,
	msgID messages.MsgID) (randValue uint64, coordPub sig.Pub, err error)

CheckCoord checks if pub is a coordinator, for the round and MsgID, returning an error if it is not. If pub is nil, then it returns the coordinator pub for the inputs. It will fail if pub is nil and random VRF membership is set. randValue is the randomValue from the VRF for the inputs. It should be used by the consensus implementations.

func CheckLocalDeserializedMessage

func CheckLocalDeserializedMessage(di *deserialized.DeserializedItem, ci ConsItem, memberCheckerState ConsStateInterface) ([]*deserialized.DeserializedItem, error)

CheckLocalDeserializedMessage can be called after successful derserialization, it checks with the member checker and messages state if the message is signed by a member and is not a duplicate.

func CheckMember

CheckMemberLocalMsg checks if the pub is a member for the index, and validates the signature with the pub, and returns a new pub object that has all the values filled.

func CheckMemberCoord

func CheckMemberCoord(mc *MemCheckers, rnd types.ConsensusRound,
	sigItem *sig.SigItem, msg *sig.MultipleSignedMessage) error

CheckMemberCoord checks if the sigItem is the coordinator returning an error if it is not. It sets the random VRF for this sigItem if enabled. It is called within the message state checks.

func CheckMemberCoordHdr

func CheckMemberCoordHdr(mc *MemCheckers, rnd types.ConsensusRound, msg messages.MsgHeader) error

CheckMemberCoordHdr checks if the message comes from the coordinator, returning an error if not. It sets the random VRF for this sigItem if enabled. It is called within the message state checks.

func CheckMemberLocal

func CheckMemberLocal(mc *MemCheckers) bool

CheckMemberLocal returns true if the local node is a member of the consensus.

func CheckRandMember

func CheckRandMember(mc MemberChecker, pub sig.Pub, hdr messages.InternalSignedMsgHeader, msgId messages.MsgID, isLocal bool) error

CheckRandMember checks if the public key is a member for the given consensus instance and message type. It should only be called after CheckMember. Note that CheckMember already calls this function internally to if random membership is supported. Random membership means that out of the known members only a certain set will be chosen randomly for this specific consensus/message pair.

func CreateGeneralConfig

func CreateGeneralConfig(testId int, eis generalconfig.ExtraInitState,
	statsInt stats.StatsInterface, to types.TestOptions, initHeaders []messages.MsgHeader,
	priv sig.Priv) *generalconfig.GeneralConfig

SetTestConfig is run before tests to set any options specific to the consensus. It should be run before InitAbsState

func DeserializeMessage

DeserializeMessage deserializes a message for the consensus type. This is a static method, and can be called concurrently.

func FinishUnwrapMessage

func FinishUnwrapMessage(isLocal types.LocalMessageType, w messages.MsgHeader, msg sig.EncodedMsg, unmarFunc types.ConsensusIndexFuncs,
	consItem ConsItem, memberCheckerState ConsStateInterface) (
	[]*deserialized.DeserializedItem, error)

FinishUnwrapMessage is called after UnwrapMessage and ProcessConsMessageList. If the consensus is ready then it does the actual deserialization and returns the list of de-serialized messages. If the consensus is not ready to deserialize the message (for example if it does not know who the members of the consensus are then the IsDeserialzed flag of the return value is set to false. This is a static method, and can be called concurrently.

func GetForwardAllFunc

func GetForwardAllFunc() func(sendChans []channelinterface.SendChannel) []channelinterface.SendChannel

GetForwardAllFunc returns the forward function that sends to all connections. It is used in case a consensus wants to send a special message to all connections at once.

func NormalBroadcast

func NormalBroadcast(nextCoordPub sig.Pub,
	ci *ConsInterfaceItems,
	msg messages.InternalSignedMsgHeader,
	signMessage bool,
	forwardFunc channelinterface.NewForwardFuncFilter,
	mainChannel channelinterface.MainChannel,
	gc *generalconfig.GeneralConfig,
	additionalMsgs ...messages.MsgHeader)

func ProcessConsMessageList

func ProcessConsMessageList(isLocal types.LocalMessageType, unmarFunc types.ConsensusIndexFuncs,
	ci ConsItem, msg sig.EncodedMsg,
	memberCheckerState ConsStateInterface) ([]*deserialized.DeserializedItem, []error)

ProcessConsMessageList takes a list of one or more serialzed consensus messages, then breaks them into individual ones and processes them. Only the staic methods of ConsItem should be used. This is a static method, and can be called concurrently.

func ShouldWaitForRndCoord

func ShouldWaitForRndCoord(memberType types.RndMemberType, gc *generalconfig.GeneralConfig) bool

func UnwrapMessage

func UnwrapMessage(msg sig.EncodedMsg,
	unmarFunc types.ConsensusIndexFuncs, isLocal types.LocalMessageType,
	consItem ConsItem, memberCheckerState ConsStateInterface) ([]*deserialized.DeserializedItem, []error)

UnwrapMessage is called each time a message is received from the network or from a local send. It can be called by many different threads concurrently, it is responsible for de-serializing a message, checking if it is valid, checking if it from a valid consensus member and is a new message. If all those requirements are satisfied, the message is de-serialized and sent to be processed by the main consensus loop. Only the static methods of ConsItem should be used. This is a static method, and can be called concurrently.

Types

type AdditionalForwardCheckerOps

type AdditionalForwardCheckerOps interface {
	// ShouldForward determines is forwarding is necessary based on if a message has made progress
	// towards a decision in consensus. For example in all to all communication
	// pattern it should return false since forwarding is not necessary.
	// Is proposal messages is true if the message is a proposal.
	ShouldForward(progress bool, isProposalMessage bool) bool
	// GetFanOut returns the number of nodes messages are forwarded to.
	GetFanOut() int

	// GetForwardList is called before a message is broadcast, it takes as input the list of all nodes in the system.
	// It returns the list of public keys to which the message should be sent.
	GetNewForwardListFunc() channelinterface.NewForwardFuncFilter

	// GetHalfHalfForwardListFunc is the same as GetNewForwardListFunc except is returns functions that broadcast
	// to half of the participants.
	GetHalfHalfForwardListFunc() (firstHalf, secondHalf channelinterface.NewForwardFuncFilter)

	// GetNoProgressForwardFunc is called before a noprogress message is broadcast.
	GetNoProgressForwardFunc() channelinterface.NewForwardFuncFilter
}

type BasicConsItem

type BasicConsItem interface {
	// GetHeader should a blank message header for the HeaderID, this object will be used to deserialize a message into itself (see consinterface.DeserializeMessage).
	GetHeader(emptyPub sig.Pub, generalConfig *generalconfig.GeneralConfig, headerID messages.HeaderID) (messages.MsgHeader, error)
	// GetBufferCount checks a MessageID and returns the thresholds for which it should be forwarded using the BufferForwarder (see forwardchecker.ForwardChecker interface).
	// endThreshold is the number of signatures needed to fully support this message (for example a leader message would be 1, and an echo message would be n-t),
	// maxPossible is the maximum different possible signatures valid for this message (for example a leader message would be 1, and an echo message would be n),
	// msgid is the MsgID of the message.
	// Forward thresholds are computed by nextThreshold*Forwarder.GetFanOut() (i.e. it grows exponentionally), until the message is forwarded after maxPossible has been reached.
	// If endThreshold < 1, then the message is not forwarded (i.e. we expect the original sender to handling the sending to all nodes).
	GetBufferCount(messages.MsgIDHeader, *generalconfig.GeneralConfig, *MemCheckers) (endThreshold int, maxPossible int, msgid messages.MsgID, err error) // How many of the same msg to buff before forwarding
}

type BufferCountFunc

type BufferCountFunc func(messages.MsgIDHeader, *generalconfig.GeneralConfig, *MemCheckers) (
	endThreshold int, maxPossible int, msgid messages.MsgID, err error)

See BasicConsItem.GetBufferCount interface

type ByzBroadcastFunc

type ByzBroadcastFunc func(nextCoordPub sig.Pub,
	ci *ConsInterfaceItems,
	msg messages.InternalSignedMsgHeader,
	signMessage bool,
	filter channelinterface.NewForwardFuncFilter,
	mainChannel channelinterface.MainChannel,
	gc *generalconfig.GeneralConfig,
	additionalMsgs ...messages.MsgHeader)

type CausalConsInterfaceState

type CausalConsInterfaceState struct {
	ProposalInfo map[types.ParentConsensusHash]CausalStateMachineInterface // Interface to the state machine.

	// Set of proposals to be validated.
	// It is a map from a child index to a list of proposals.
	// Proposals that try to consume a non-existing child output will be added here.
	// When the child output is created after a decision these will be reprocessed.
	// TODO if a proposal arrives after the child item is consumed it will remain here forever, need to do GC
	ProposalsToValidate map[types.ConsensusHash][]*channelinterface.RcvMsg

	IsInStorageInit bool // Used during initialization, when recovering from disk this is set to true so we don't send messages when we reply to values received.

	DecidedMap  map[types.ParentConsensusHash]bool // TODO clean this up
	LastDecided types.ParentConsensusHash
	// contains filtered or unexported fields
}

func NewCausalConsInterfaceState

func NewCausalConsInterfaceState(initItem ConsItem,
	initMemberChecker MemberChecker,
	initSpecialMemberChecker SpecialPubMemberChecker,
	initMessageState MessageState,
	initForwardChecker ForwardChecker,
	storage storage.StoreInterface,
	genRandBytes bool,
	emptyPub sig.Pub, broadcastFunc ByzBroadcastFunc,
	gc *generalconfig.GeneralConfig) *CausalConsInterfaceState

func (*CausalConsInterfaceState) AddFutureMessage

func (mcs *CausalConsInterfaceState) AddFutureMessage(rcvMsg *channelinterface.RcvMsg)

func (*CausalConsInterfaceState) CheckGenMemberChecker

func (mcs *CausalConsInterfaceState) CheckGenMemberChecker(idx types.ConsensusIndex) (*ConsInterfaceItems, error)

func (*CausalConsInterfaceState) CheckSendEcho

CheckSendEcho should be called when an echo is sent. If none of the indices have sent an echo before then nil is returned. Otherwise an error is returned.

func (*CausalConsInterfaceState) CheckValidateProposal

func (mcs *CausalConsInterfaceState) CheckValidateProposal(item *deserialized.DeserializedItem,
	sendRecvChan *channelinterface.SendRecvChannel, isLocal bool) (readyToProcess bool, err error)

CheckValidateProposal checks if item is a proposal that needs to be validated by the SM. If it is not true, nil is returned. It it is, but the state machine is not ready to validate it then false, nil is returned. (This object will take care of reprocessing the message in this case.) If it is ready then true is returned. If there is an error processing the message then an error is returned. It validates the sent value with each of the hashes given by the signed message in indices and AdditionalIndices

func (*CausalConsInterfaceState) Collect

func (mcs *CausalConsInterfaceState) Collect()

Collect is called when the item is being garbage collected.

func (*CausalConsInterfaceState) DoneIndex

func (mcs *CausalConsInterfaceState) DoneIndex(cid types.ConsensusIndex,
	proposer sig.Pub, dec []byte) (updatedDec []byte)

DoneIndex is called with consensus has finished at idx, binstate is the value decided, which is passed to the member checker's UpdateState method. It allocates the objects for new consensus instances and garbage collects old ones as necessary. It returns the decided value (the state machine may modify the decided value) It is concurrent safe with GetMemberChecker.

func (*CausalConsInterfaceState) GenChildIndices

func (mcs *CausalConsInterfaceState) GenChildIndices(cid types.ConsensusIndex, isUnconsumedOutput bool,
	maxCount int) (ret [][]byte, err error)

GetChildIndices returns the decided children that consumed an output from this item.

func (*CausalConsInterfaceState) GetCausalDecisions

func (mcs *CausalConsInterfaceState) GetCausalDecisions() (root *utils.StringNode, orderedDecisions [][]byte)

// checkProposalNeeded will check if item needs a proposal, and will request one if needed from the SM

func (cs *CausalConsInterfaceState) CheckProposalNeeded(nextIdx types.ConsensusID) {
	nextItem, err := cs.GetConsItem(nextIdx)
	if err != nil {
		panic(err)
	}

	if _, ready := nextItem.GetProposalIndex(); ready && !cs.GotProposal[nextIdx] {
		pi := cs.ProposalInfo[nextIdx]
		pi.GetProposal()
		cs.GotProposal[nextIdx] = true
	}
}

GetCausalDecisions returns the decided values in causal order tree.

func (*CausalConsInterfaceState) GetConsItem

func (mcs *CausalConsInterfaceState) GetConsItem(idx types.ConsensusIndex) (ConsItem, error)

func (*CausalConsInterfaceState) GetConsensusIndexFuncs

func (mcs *CausalConsInterfaceState) GetConsensusIndexFuncs() types.ConsensusIndexFuncs

GetComputeConsensusIDFunc returns types.GenerateParentHash.

func (*CausalConsInterfaceState) GetGeneralConfig

func (mcs *CausalConsInterfaceState) GetGeneralConfig() *generalconfig.GeneralConfig

GetGeneralConfig returns the GeneralConfig object.

func (*CausalConsInterfaceState) GetInitItem

func (*CausalConsInterfaceState) GetLastDecidedItem

func (mcs *CausalConsInterfaceState) GetLastDecidedItem() *ConsInterfaceItems

getConsInterfaceItems returns the last decided consInterfaceItems.

func (*CausalConsInterfaceState) GetMemberChecker

func (mcs *CausalConsInterfaceState) GetMemberChecker(cid types.ConsensusIndex) (*ConsInterfaceItems, error)

GetMemberChecker returns the member checkers, messages state, and forward checker for the given index. If useLock is true, then accesses are protected by a lock.

func (*CausalConsInterfaceState) GetNewPub

func (mcs *CausalConsInterfaceState) GetNewPub() sig.Pub

GetNewPub returns an empty public key object.

func (*CausalConsInterfaceState) GetSortedParChi

func (mcs *CausalConsInterfaceState) GetSortedParChi() sort.StringSlice

func (*CausalConsInterfaceState) GetTimeoutItems

func (mcs *CausalConsInterfaceState) GetTimeoutItems() (decidedTimeoutItems,
	startedTimeoutItems, startedItems []*ConsInterfaceItems)

GetTimeoutItems returns two lists of ConsInterfaceItems, each item in the lists has not had its LastProgress time updated for more than the config.ProgressTimeout. The first list contains items that have been decided, but not yet garbage collected (i.e. they still have unconsumed output items). The second contains are items that have received a valid proposal, but not yet decided (and have passed a timeout). The third list is the same as the second list except contains items even if they have not passed the timeout

func (*CausalConsInterfaceState) GetUnconsumedOutputs

func (mcs *CausalConsInterfaceState) GetUnconsumedOutputs(idx types.ParentConsensusHash) []types.ConsensusHash

getUnconsumedOutputs returns the unconsumed outputs for the given consensus item.

func (*CausalConsInterfaceState) InitSM

func (*CausalConsInterfaceState) SetMainChannel

func (mcs *CausalConsInterfaceState) SetMainChannel(mainChannel channelinterface.MainChannel)

SetMainChannel must be called before the object is used.

func (*CausalConsInterfaceState) UpdateProgressTime

func (mcs *CausalConsInterfaceState) UpdateProgressTime(index types.ConsensusIndex)

type CausalStateMachineInterface

type CausalStateMachineInterface interface {
	GeneralStateMachineInterface

	CheckOK()

	// Init is called to initialize the object, lastProposal is the number of consensus instances to run, after which a message should be sent
	// on doneChan telling the consensus to shut down.
	// If basic init is true, then the SM will just be used for checking stats and checking decisions.
	Init(gc *generalconfig.GeneralConfig, endAfter types.ConsensusInt, memberCheckerState ConsStateInterface,
		mainChannel channelinterface.MainChannel, doneChan chan channelinterface.ChannelCloseType, basicInit bool)

	// GenerateNewSM is called on this init SM to generate a new SM given the items to be consumed.
	// It should just generate the item, it should not change the state of any of the parentSMs.
	// This will be called on the initial CausalStateMachineInterface passed to the system
	GenerateNewSM(consumedIndices []types.ConsensusID, parentSMs []CausalStateMachineInterface) CausalStateMachineInterface

	// HasEchoed should return true if this SM has echoed a proposal
	// HasEchoed() bool
	// GetDependentItems returns a  list of items dependent from this SM.
	// This list must be the same as the list returned from HasDecided
	GetDependentItems() []sig.ConsIDPub

	// HasDecided is called each time a consensus decision takes place, given the index and the decided vaule.
	// Proposer is the public key of the node that proposed the decision.
	// Owners are the owners of the input consensus indices.
	// It returns a list of causally dependent ids and public keys of the owners of those ids,
	// and the decided value (in case the state machine wants to change it).
	HasDecided(proposer sig.Pub, index types.ConsensusIndex, owners []sig.Pub,
		decision []byte) (outputs []sig.ConsIDPub, updatedDecision []byte)

	// CheckDecisions is for testing and will be called at the end of the test with
	// a causally ordered tree of all the decided values, it should then check if the
	// decided values are valid.
	CheckDecisions(root *utils.StringNode) (errors []error)

	// FailAfter is for testing, once index is reached, it should send a message on doneChan (the input from Init), telling the consensus to shutdown.
	FailAfter(index types.ConsensusInt)

	// GetInitialFirstIndex returns the hash of some unique string for the first instance of the state machine.
	GetInitialFirstIndex() types.ConsensusID

	// StartInit is called on the init state machine to start the program.
	StartInit(memberCheckerState ConsStateInterface)
}

type CoinItemInterface

type CoinItemInterface interface {
	BasicConsItem

	// CheckCoinMessage should be called from within ProcessMessage of the ConsensusItem that is using this coin.
	// It returns the round the coin corresponds to and true in first boolean position if made progress towards decision,
	// or false if already decided, and return true in second position if the message should be forwarded.
	// A message is returned if a message should be sent.
	// If the message is invalid an error is returned.
	CheckCoinMessage(deser *deserialized.DeserializedItem, isLocal bool, alwaysGenerate bool, consItem ConsItem,
		coinMsgState CoinMessageStateInterface, msgState MessageState) (round types.ConsensusRound,
		ret messages.MsgHeader, progress, shouldForward bool, err error)

	GenerateCoinMessage(round types.ConsensusRound, alwaysGenerate bool, consItem ConsItem,
		coinMsgState CoinMessageStateInterface, msgState MessageState) (ret messages.MsgHeader)
}

type CoinMessageStateInterface

type CoinMessageStateInterface interface {
	// CheckFinishedMessage checks if the message is for the coin and if the coin is already know.
	// If so true is returned, false otherwise.
	CheckFinishedMessage(deser *deserialized.DeserializedItem) bool

	// GetCoinSignType returns what type of signature is used to sign coin messages.
	GetCoinSignType() types.SignType

	// GotMsg is called by the MessageState of the consensus using this coin.
	// deser is the deserialized message object.
	// It returns an error if the message is invalid.
	GotMsg(msgState MessageState, deser *deserialized.DeserializedItem,
		gc *generalconfig.GeneralConfig, mc *MemCheckers) (types.ConsensusRound, error)

	// GetCoins returns the set of binary coin values that are currently valid.
	GetCoins(round types.ConsensusRound) []types.BinVal

	New(idx types.ConsensusIndex, presets []struct {
		Round types.ConsensusRound
		Val   types.BinVal
	}) CoinMessageStateInterface
}

type ConsInterfaceItems

type ConsInterfaceItems struct {
	ConsItem   ConsItem // The consensus item.
	MC         *MemCheckers
	MsgState   MessageState
	FwdChecker ForwardChecker
	// LastProgress is used with causal, and is set to the time the index last made progress
	LastProgress time.Time
	// ProgressListIndex is the index of the item in the list sorted by LastProgress for causal.
	ProgressListIndex int
}

type ConsInterfaceState

type ConsInterfaceState struct {

	// StartedIndex       types.ConsensusInt                                // The maximum consensus index that has been started
	LocalIndex       types.ConsensusInt // The current consensus index.
	PredecisionIndex types.ConsensusInt // The maximum consensus index that has gotten a decided or possible decided value

	StartedIndex types.ConsensusInt // The maximum consensus index that has been started

	PreDecisions        map[types.ConsensusInt][]byte
	SupportIndex        map[types.ConsensusInt]types.ConsensusInt
	ProposalInfo        map[types.ConsensusInt]StateMachineInterface      // Interface to the state machine.
	GotProposal         map[types.ConsensusInt]bool                       // set to true if received a proposal for the index
	ProposalsToValidate map[types.ConsensusInt][]*channelinterface.RcvMsg // set of proposals to be validated

	IsInStorageInit bool // Used during initialization, when recovering from disk this is set to true so we don't send messages when we reply to values received.

	SharedLock sync.Mutex // Shared with cons item
	// contains filtered or unexported fields
}

ConsInterfaceState creates, keeps and deletes the member checkers, the message state object, and the forward checker objects for the current (generalconfig.KeepTotal) consensus instances. Objects for older consensus objects are garbage collected, and their state must be loaded from storage if they are needed.

func NewConsInterfaceState

func NewConsInterfaceState(initItem ConsItem,
	initMemberChecker MemberChecker,
	initSpecialMemberChecker SpecialPubMemberChecker,
	initMessageState MessageState,
	initForwardChecker ForwardChecker,
	allowConcurrent types.ConsensusInt,
	genRandBytes bool,
	emptyPub sig.Pub, broadcastFunc ByzBroadcastFunc,
	gc *generalconfig.GeneralConfig) *ConsInterfaceState

Init updates the fields of the member checker state

func (*ConsInterfaceState) CheckGenMemberChecker

func (mcs *ConsInterfaceState) CheckGenMemberChecker(cid types.ConsensusIndex) (*ConsInterfaceItems, error)
func (mcs *ConsInterfaceState) GetConsItem(idIdx types.ConsensusIndex) (ConsItem, error) {
	if mcs.mainChannel == nil {
		panic("must set main channel")
	}
	idx := idIdx.Index.(types.ConsensusInt)

	if idx < types.ConsensusInt(utils.SubOrZero(uint64(mcs.LocalIndex), uint64(mcs.gc.KeepPast))) {
		return nil, types.ErrIndexTooOld
	}

	// mcs.mutex.RLock()
	// defer mcs.mutex.RUnlock()
	mcs.mutex.Lock()
	defer mcs.mutex.Unlock()

	items := mcs.getIndex(idx, true)
	items.MC.MC.CheckIndex(items.ConsItem.GetIndex())
	return items.ConsItem, nil
}

func (*ConsInterfaceState) CheckPreDecision

func (mcs *ConsInterfaceState) CheckPreDecision()

CheckPreDecision will check if index has a possible decided value ready and allocates any necessary objects. This should only be called from the main thread.

func (*ConsInterfaceState) CheckProposalNeeded

func (mcs *ConsInterfaceState) CheckProposalNeeded(nextIdx types.ConsensusInt)

CheckProposalNeeded will check if item needs a proposal, and will request one if needed from the SM. This should only be called from the main thread.

func (*ConsInterfaceState) CheckValidateProposal

func (mcs *ConsInterfaceState) CheckValidateProposal(item *deserialized.DeserializedItem,
	sendRecvChan *channelinterface.SendRecvChannel, isLocal bool) (readyToProcess bool, err error)

CheckValidateProposal checks if item is a proposal that needs to be validated by the SM. If it is not true, nil is returned. It it is, but the state machine is not ready to validate it then false, nil is returned. (This object will take care of reprocessing the message in this case.) If it is ready then true is returned. If there is an error processing the message then an error is returned. This should only be called from the main message thread.

func (*ConsInterfaceState) Collect

func (mcs *ConsInterfaceState) Collect()

Collect is called when the process is terminating.

func (*ConsInterfaceState) DoneIndex

func (mcs *ConsInterfaceState) DoneIndex(nextIdxID, supportIndex, futureDependentIndex types.ConsensusID,
	proposer sig.Pub, dec []byte) (finishedLastRound bool)

DoneIndex is called with consensus has finished at idx, binstate is the value decided, which is passed to the member checker's UpdateState method. It allocates the objects for new consensus instances and garbage collects old ones as necessary. It is concurrent safe with GetMemberChecker. This should only be called from the main thread. It returns true if the last consensus index has finished.

func (*ConsInterfaceState) GetConsensusIndexFuncs

func (mcs *ConsInterfaceState) GetConsensusIndexFuncs() types.ConsensusIndexFuncs

GetConsIDUnmarFunc returns the function used to unmarshal consensus IDs.

func (*ConsInterfaceState) GetGeneralConfig

func (mcs *ConsInterfaceState) GetGeneralConfig() *generalconfig.GeneralConfig

GetGeneralConfig returns the GeneralConfig object.

func (*ConsInterfaceState) GetMemberChecker

func (mcs *ConsInterfaceState) GetMemberChecker(cid types.ConsensusIndex) (*ConsInterfaceItems, error)

GetMemberChecker returns the member checkers, messages state, and forward checker for the given index. If useLock is true, then accesses are protected by a lock.

func (*ConsInterfaceState) GetNewPub

func (mcs *ConsInterfaceState) GetNewPub() sig.Pub

GetNewPub returns an empty public key object.

func (*ConsInterfaceState) GetOldestMemberCheckerIdx

func (mcs *ConsInterfaceState) GetOldestMemberCheckerIdx() types.ConsensusInt

GetOldestMemberChecker returns the oldest member checkers, messages state, and forward checker.

func (*ConsInterfaceState) IncrementStartedIndex

func (mcs *ConsInterfaceState) IncrementStartedIndex()

func (*ConsInterfaceState) SetInitSM

func (mcs *ConsInterfaceState) SetInitSM(initStateMachine StateMachineInterface)

func (*ConsInterfaceState) SetMainChannel

func (mcs *ConsInterfaceState) SetMainChannel(mainChannel channelinterface.MainChannel)

SetMainChannel must be called before the object is used.

type ConsItem

type ConsItem interface {
	BasicConsItem
	GetGeneralConfig() *generalconfig.GeneralConfig
	// 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 should process the message and update the
	// state of the consensus.
	// It should return 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.
	ProcessMessage(item *deserialized.DeserializedItem, isLocal bool,
		senderChan *channelinterface.SendRecvChannel) (progress, shouldForward bool)
	// HasDecided should return true if this consensus item has reached a decision.
	HasDecided() bool
	// GetBinState should return the entire state of the consensus as a string of bytes using the MessageState object (normally this would just be MessageState.GetMsgState() as the list
	// of all messages, with a messagetypes.ConsBinStateMessage header appended to the beginning), this value will be stored to disk and used to send the state to other nodes.
	// If localOnly is true then only messages signed by the local node should be included.
	GetBinState(localOnly bool) ([]byte, error)
	// PrintState()
	// GetDecision should return the decided value of the consensus. It should only be called after HasDecided returns true.
	// Proposer it the node that proposed the decision, prvIdx is the index of the decision that preceeded this decision
	// (normally this is the current index - 1), futureFixed is the first larger index that this decision does not depend
	// on (normally this is the current index + 1). prvIdx and futureFixed are different for MvCons3 as that
	// consensus piggybacks consensus instances on top of eachother.
	GetDecision() (proposer sig.Pub, decision []byte, prvIdx, futureFixed types.ConsensusIndex)
	// GetPreHeader returns the serialized header that is attached to all messages sent by this consensus item.
	// It is normally nil.
	GetPreHeader() []messages.MsgHeader
	// AddPreHeader appends a header that will be attached to all messages sent by this consensus item.
	AddPreHeader(messages.MsgHeader)
	// Start is called exactly once for each consensus instance, after start is called, the consensus may return
	// true from GetProposalInfo as soon as it is ready for a proposal from the application.
	// Note that messages may be sent to the consensus before Start is called, they should be processed as necessary.
	// Finished last index is true once the last index has decided (some consensus instances may start after the last index
	// has decided to ensure all items eventually decide)
	Start(finishedLastIndex bool)
	// HasStarted returns true if start has been called
	HasStarted() bool
	// GetProposalIndex returns the previous consensus index from which this index will use (must be at least 1
	// smaller than the current index). The value is used only if ready is true. Ready should be false until
	// this consensus index needs a proposal (this cannot return true before start is called).
	GetProposalIndex() (prevIdx types.ConsensusIndex, ready bool)
	// GotProposal is called at most once for each consensus index after start by the application as the local input to the consensus. The hdr value will be used as the input to the consensus.
	GotProposal(hdr messages.MsgHeader, mainChannel channelinterface.MainChannel) error
	// InitState is called once before running the first consensus iteration. The input values are expected to remain the same across all consensus iterations.
	// GenerateInitState(preHeaders []messages.MsgHeader, priv sig.Priv, eis ExtraInitState, stats stats.StatsInterface)
	// ResetState should reset any stored state for the current consensus index, and prepare for the new consensus index given by the input.
	GenerateNewItem(index types.ConsensusIndex, consItems *ConsInterfaceItems, mainChannel channelinterface.MainChannel,
		prevItem ConsItem, broadcastFunc ByzBroadcastFunc, gc *generalconfig.GeneralConfig) ConsItem
	// SetNextConsItem gives a pointer to the next consensus item at the next consensus instance, it is called when the next instance is created
	SetNextConsItem(next ConsItem)
	// CanStartNext should return true if it is safe to start the next consensus instance (if parallel instances are enabled),
	// in most consensus algorithms this will always return true. In MvCons3 this will return true once this consensus instance
	// know what instance it follows (i.e. the accepted init message points to), or when a timer has run out.
	CanStartNext() bool
	// GetNextInfo will be called after CanStartNext returns true.
	// It is used to get information about how the state machine for this instance will be generated.
	// prevIdx should be the index that this consensus index will follow (normally this is just idx - 1).
	// preDecision is either nil or the value that will be decided if a non-nil value is decided.
	// hasInfo returns true if the values for proposer and preDecision are ready.
	// If false is returned then the next is started, but the current instance has no state machine created.
	// This function is mainly used for MvCons3 since the order of state machines depends on depends on the execution
	// of the consensus instances.
	// For other consensus algorithms prevIdx should return (idx - 1) and hasInfo should be false unless
	// AllowConcurrent is enabled.
	GetNextInfo() (prevIdx types.ConsensusIndex, proposer sig.Pub, preDecision []byte, hasInfo bool)
	// SetInitialState should be called on the initial consensus index (1) to set the initial state.
	SetInitialState([]byte, storage.StoreInterface)
	GetIndex() types.ConsensusIndex // GetIndex returns the consensus index of the item.
	// HasValidStarted returns true if this cons item has processed a valid proposal, or if it know other nodes
	// have (i.e. if the binary reduction has terminated)
	HasValidStarted() bool
	// GetCustomRecoverMsg is called when there is no progress after a timeout. If the standard
	// recovery message is used (messagetypes.NoProgressMessage) then the recovery is handled by the
	// consensus state objects.
	// Otherwise the returned message is sent to the peers and the consensus must handle
	// the recovery itself.
	// If createEmpty is true then the message will be used to deserialize a received message.
	GetCustomRecoverMsg(createEmpty bool) messages.MsgHeader
	// GetRecoverMsgType returns the HeaderID of the recovery messages used by this consensus.
	// If messages.HdrNoProgress is returned then the default recover is used
	GetRecoverMsgType() messages.HeaderID
	// ProcessCustomRecoveryMessage is called when a valid custom recover message equal of the type
	// returned by GetCustomRecoverMessage (that is not messagetypes.NoProgressMessage).
	// The consensus should then perform the appropriate recovery.
	// Note that the message is not checked with member checkers/signatures, etc.
	ProcessCustomRecoveryMessage(item *deserialized.DeserializedItem,
		senderChan *channelinterface.SendRecvChannel)
	// GetCommitProof returns a signed message header that counts at the commit message for this consensus.
	GetCommitProof() []messages.MsgHeader
	// SetCommitProof takes the value returned from GetCommitProof of the previous consensus instance once it has decided.
	// The consensus can then use this as needed.
	SetCommitProof(prf []messages.MsgHeader)
	// 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)
	GetPrevCommitProof() (cordPub sig.Pub, proof []messages.MsgHeader)
	// Broadcast a value.
	// If nextCoordPub is nil the message will only be sent to that node, otherwise it will be sent
	// as normal (nextCoordPub is used when CollectBroadcast is true in test options).
	Broadcast(nextCoordPub sig.Pub, msg messages.InternalSignedMsgHeader,
		signMessage bool,
		forwardFunc channelinterface.NewForwardFuncFilter,
		mainChannel channelinterface.MainChannel,
		additionalMsgs ...messages.MsgHeader)
	// CheckMemberLocalMsg checks if the local node is a member of the consensus for this message type
	CheckMemberLocalMsg(hdr messages.InternalSignedMsgHeader) bool
	// CheckMemberLocal checks if the node is a member of the consensus.
	CheckMemberLocal() bool
	// GetConsInterfaceItems returns the ConsInterfaceItems for this consesnsus instance.
	GetConsInterfaceItems() *ConsInterfaceItems

	// PrevHasBeenReset is called when the previous consensus index has been reset to a new index
	PrevHasBeenReset()
	// SetTestConfig is run before tests to set any options specific to the consensus.
	// Test id should be the index of the node in the test.
	// SetTestConfig(testId int, options types.TestOptions)
	// GetConsType returns the type of consensus this instance implements.
	GetConsType() types.ConsType
	// Collect is called when the item is about to be garbage collected.
	Collect()
	// ForwardOldIndices should return true if messages from old consensus indices should be forwarded
	// even after decision.
	ForwardOldIndices() bool

	// NeedsCompletionConcurrentProposals returns the number of concurrent instances the consensus needs to run correctly where
	// the possible value that can be decided must be known before the next proposal is made (i.e. either that
	// value or nil is decided). Normally this returns 1.
	// Currently only MvCons3 needs a higher value since it makes concurrent proposals once the possible value
	// of the previous proposal is known.
	NeedsCompletionConcurrentProposals() types.ConsensusInt
	// ComputeDecidedValue is a static method that should return the decided value, state comes from ConsItem.GetBinState, decision comes from ConsItem.GetDecision.
	ComputeDecidedValue(state []byte, decision []byte) []byte
	// GetProposeHeaderID returns the HeaderID for the message type that will be input to GotProposal.
	GetProposeHeaderID() messages.HeaderID
	// GenerateMessageState generates a new message state object given the inputs.
	GenerateMessageState(gc *generalconfig.GeneralConfig) MessageState
	// ShouldCreatePartial returns true if the message type should be sent as a partial message
	ShouldCreatePartial(headerType messages.HeaderID) bool
}

ConsItem represents an implementation of a consensus algorithm. Certain methods must be implemnted as static methods. Each iteration of consensus will use a single instance of this object. When the system is done with a consensus iteration, it will call ResetState(index) on the object, the object should the reinitialize its as the object will be reused for a new consensus iteration. There are generalconfig.KeepTotal instaces of these objects created throughout the life of the application, and they are just reused by calling ResetState(index).

type ConsStateInterface

type ConsStateInterface interface {
	GetMemberChecker(cid types.ConsensusIndex) (*ConsInterfaceItems, error)
	// GetConsItem(idIdx types.ConsensusIndex) (ConsItem, error)
	GetNewPub() sig.Pub
	GetGeneralConfig() *generalconfig.GeneralConfig
	CheckGenMemberChecker(cid types.ConsensusIndex) (*ConsInterfaceItems, error)
	GetConsensusIndexFuncs() types.ConsensusIndexFuncs
	SetMainChannel(mainChannel channelinterface.MainChannel)
}

type ForwardChecker

type ForwardChecker interface {
	AdditionalForwardCheckerOps
	// forwardchecker.internalForwardChecker
	// CheckForward is called each time a message is successfully processes by ConsState, sndRcvChan is the channel who sent the message, progress is given by the consensus
	// object after the message is processesed and is true if the message made progress in the consensus.
	// The inputs endThreshold, maxPossible int, msgID messages.MsgID should come from item.GetBufferCount called on the msg.
	// The input sigCount is the number of signatures received for this MsgID so for for this consensus.
	// The input memberChecker correspond to the consensus instance this message is from.
	// The forward checker should then keep this message if it should be forwarded later, messages are only forwarded when they are returned from GetNextForwardItem
	// Is propose message should be true if the message is a proposal message.
	CheckForward(sndRcvChan *channelinterface.SendRecvChannel, msg *deserialized.DeserializedItem, shouldForward bool,
		isProposalMessage bool, endThreshold, maxPossible, sigCount int,
		msgID messages.MsgID, memberChecker *MemCheckers)
	// GetNextForward item is called by ConsState after a consensus message is successfully processed and after a timeout.
	// If there is a message to be forwareded, it should return that.
	// It will be called in a loop until msg is nil. The forwardFunc function takes the list of nodes the node is connected to and returns the set
	// of nodes to forward the message to. The returned message and function are used as input to MainChannel.Send.
	GetNextForwardItem(stats.NwStatsInterface) (msg []*deserialized.DeserializedItem, forwardFunc channelinterface.NewForwardFuncFilter)
	// New creates a new ForwardChecker for the consensus index. It will be always be called on an "initialForwardChecker" that is given as input to
	// MemberCheckerState.Init. ParticipantCount is the number of nodes in the system.
	New(idx types.ConsensusIndex, participants, allPubs sig.PubList) ForwardChecker
	// ConsDecided is called when the consensus has decided, after this is called, GetNextForwardItem will be called until it returns nil.
	// This should finish any items pending to be forwarded.
	ConsDecided(stats.NwStatsInterface)
}

ForwardChecker keeps track of successfully processes consensus messages and decides if they should be forwarded on the network or not. There is one created for each consensus instance. Each time a valid message is processes it will be sent to the forward checker through CheckForward. ConsState will check for messages to be forwared by calling GetNextForwardItem. GetNextForwardItem is called repetably on a timeout for the most recent consensus instance. It is also called each time a message is received on the instance that the message corresponds to. (TODO maybe also call old consensus instances on a timeout to help other nodes progress faster?) ForwardChecker should be called by cons_state and net_main_channel but only from a single thread, so no synchronization needed (TODO be sure this remains true)

type GeneralStateMachineInterface

type GeneralStateMachineInterface interface {
	// FinishedLastRound returns true if the last test index has finished.
	FinishedLastRound() bool
	// GetIndex returns the index for this consensus
	GetIndex() types.ConsensusIndex
	// ValidateProposal should return nil if the input proposal is valid, otherwise an error.
	// Proposer is the public key of the node that proposed the value.
	// It is called on the parent state machine instance of the proposal after it has decided.
	ValidateProposal(proposer sig.Pub, proposal []byte) error
	// GetByzProposal should generate a byzantine proposal based on the configuration
	GetByzProposal(originProposal []byte, gc *generalconfig.GeneralConfig) (byzProposal []byte)
	// GetInitialState returns the initial state of the program.
	GetInitialState() []byte
	// StatsString returns statistics for the state machine.
	StatsString(testDuration time.Duration) string
	// GetDecided returns true if the SM has decided.
	GetDecided() bool
	// GetSMStats returns the statistics object for the SM.
	GetSMStats() SMStats
	// GetRand returns 32 random bytes if supported by the state machine type.
	// It should only be called after HasDecided.
	GetRand() [32]byte
	// DoneClear should be called if the instance of the state machine will no longer be used (it should perform any cleanup).
	DoneClear()
	// DoneKeep should be called if the instance of the state machine will be kept.
	DoneKeep()
	// Collect is called when the item is about to be garbage collected and is used as a sanity check.
	Collect()
	// EndTest is called when the test is finished
	EndTest()
}

type HeaderFunc

See BasicConsItem.GetHeader interface

type MemCheckers

type MemCheckers struct {
	MC  MemberChecker           // the member checker
	SMC SpecialPubMemberChecker // the special member checker
}

MemCheckers holds the member checker and special member checker for a consensus instance.

type MemberChecker

type MemberChecker interface {
	New(id types.ConsensusIndex) MemberChecker // New generates a new member checker for the index, this is called on the inital member checker each time.
	IsReady() bool                             // IsReady should return true if the member check knows all the members. It needs to be concurrent safe.

	AllowsChange() bool // AllowsChange returns true if the member checker allows changing members, used as a sanity check.

	// CheckMemberBytes checks the the pub key is a member and returns corresponding pub key object, nil if it is not a member
	CheckMemberBytes(types.ConsensusIndex, sig.PubKeyID) sig.Pub
	// CheckMemberBytes checks the the bytes using GetPubString and returns corresponding pub key object, nil if it is not a member
	// CheckPubString(types.ConsensusIndex, sig.PubKeyID) sig.Pub
	// CheckRandMember can be called after CheckMemberBytes is successful when ChooseRandomMember is enabled.
	// MsgID is the id of the message being checked.
	// IsProposal is true if msgID corresponds to a proposal message for the current consensus type.
	CheckRandMember(pub sig.Pub, hdr messages.InternalSignedMsgHeader, msgID messages.MsgID, isLocal bool) error
	// SelectRandMembers returns true if the member checker is selecting random members.
	RandMemberType() types.RndMemberType
	GetRnd() [32]byte

	// UpdateState is called when the previous consensus instance decides, the input is the decision plus the previous member checker.
	// Calling this should not change what IsReady returns, only after FinishUpdateState should IsReady always return true.
	// The reason is that after UpdateState is called, and before FinishUpdateState is called, SpecialMemberChecker.Update state is called.
	// Update state returns two lists of pubs.
	// fixedCoord is non-nil if we have a fixed coordinator for this instance.
	// newAllPubs are the list of all pubs in the system.
	// newMemberPubs pubs are the public keys that will now participate in consensus.
	// newMemberPubs must be a equal to or a subset of newAllPubs.
	// If membership is not changed since the previous consensus instance then nil is returned for these items.
	// Proof is the vrf proof of the current node if random membership is enabled.
	// futureFixed the same value returned by consinterface.ConsItem GetDecision(),
	// i.e. the first larger index that this decision does not depend
	// on (normally this is the current index + 1). prvIdx and futureFixed are different for MvCons3 as that
	// consensus piggybacks consensus instances on top of eachother.
	// The return values are nil if the membership has not changed.
	// ChangedMembership must be true if either of the other return values are non-nil.
	// Even if they are nil, but the membership could have changed in a different way (i.e. by random membership)
	// it must return true
	UpdateState(fixedCoord sig.Pub, prevDec []byte, randBytes [32]byte,
		prevMember MemberChecker, prevSM GeneralStateMachineInterface,
		futureFixed types.ConsensusID) (newMemberPubs, newAllPubs []sig.Pub, changedMembership bool)
	// DoneNextUpdateState is called when the member checker will no longer be used as input to generate a new member checker
	// as the prevMemberChecker to update state.
	DoneNextUpdateState() error
	// Invalidated is called if the member checker has been made invalid.
	// This happens if a different set of members was chosen then was initial proposed.
	// Currently this is only supported when using total ordering.
	Invalidated() error

	// GotVrf should be called when a node's VRF proof is received for this consensus instance.
	// If the VRF was valid it returns the uint64 that represents the vrf // TODO is it sufficient to just use the first 8 bytes of the rand?
	GotVrf(pub sig.Pub, isProposal bool, msgID messages.MsgID, proof sig.VRFProof) error
	// GetMyVRF returns the vrf proof for the local node.
	GetMyVRF(isProposal bool, id messages.MsgID) sig.VRFProof

	// GetNewPub returns an empty public key object.
	GetNewPub() sig.Pub
	GetIndex() types.ConsensusIndex
	FinishUpdateState()                         // FinishUpdate state is called after UpdateState. After this call, IsReady should always return true.
	CheckIndex(index types.ConsensusIndex) bool // CheckIndex should return true if the index is the same as the one used in New, it is for testing.
	GetMemberCount() int                        // GetMemberCount returns the number of consensus members.
	GetFaultCount() int                         // GetFaultCount returns the number of possilbe faultly nodes that the consensus can handle.
	GetParticipants() sig.PubList               // GetParticipant return the pub key of the participants.
	GetAllPubs() sig.PubList                    // GetAllPub returns all pubs in the system
	GetMyPriv() sig.Priv                        // GetMyPriv returns the local nodes private key
	// CheckRoundCoord checks if checkPub the/a coordinator for round. If it is, err is returned as nil, otherwise an
	// error is returned. If checkPub is nil, then it will return the known coordinator in coordPub.
	// Note this should only be called after the pub is verified to be a member with CheckMemberBytes
	CheckRoundCoord(msgID messages.MsgID, checkPub sig.Pub, round types.ConsensusRound) (coordPub sig.Pub, err error)
	// CheckEstimatedRoundCoordNextIndex returns the estimated public key of the coordinator for round round for the following consensus index.
	// It might not return the correct coordinator for the next index because the decision might change the membership
	// for the next index. This function should not be used if it needs to know the next coordinator for certain.
	CheckEstimatedRoundCoordNextIndex(checkPub sig.Pub,
		round types.ConsensusRound) (coordPub sig.Pub, err error)
	// CheckRandRoundCoord should be called instead of CheckRoundCoord if random membership selection is enabled.
	// If using VRFs then checkPub must not be nil.
	// If checkPub is nil, then it will return the known coordinator in coordPub.
	// If VRF is enabled randValue is the VRF random value for the inputs.
	// Note this should be called after CheckRandMember for the same pub.
	CheckRandRoundCoord(msgID messages.MsgID, checkPub sig.Pub, round types.ConsensusRound) (randValue uint64,
		coordPub sig.Pub, err error)

	// CheckFixedCoord checks if checkPub the/a coordinator for round. If it is, err is returned as nil, otherwise an
	// error is returned. If checkPub is nil, then it will return the fixed coordinator in coordPub.
	// If there is no fixedCoordinator, then an error types.ErrNoFixedCoord is returned.
	// Note this should only be called after the pub is verified to be a member with CheckMemberBytes
	CheckFixedCoord(pub sig.Pub) (coordPub sig.Pub, err error)
	GetStats() stats.StatsInterface

	// SetStats(stats.StatsInterface) // SetStats sets the stats object that will be used to keep stats, TODO clean this up
	Validated(types.SignType) // ValidatedItem is called for stats to let it know a signature was validated. TODO cleanup.

	// AddPubKeys is used for adding the public keys to the very inital member checker, and should not
	// be called on later member checkers, as they should change pub keys through the call to UpdateState.
	// priv is the local nodes private key.
	// fixedCoord is non-nil if we have a fixed coordinator for this instance.
	// allPubs are the list of all pubs in the system.
	// memberPubs pubs are the public keys that will now participate in consensus.
	// memberPubs must be equal to or a subset of newAllPubs.
	// If shared is non-nil then the local nodes on the machine will share the same initial member objects
	// (to save memory for experiments that run many nodes on the same machine).
	AddPubKeys(fixedCoord sig.Pub, memberPubKeys, allPubKeys sig.PubList, initRandBytes [32]byte, shared *Shared)

	// SetMainChannel is called on the initial member checker to inform it of the network channel object
	SetMainChannel(mainChannel channelinterface.MainChannel)
}

A MemberChecker is created for each consensus instance. It is responsible for tracking who can participate in consensus by having a list of their public keys. Once consensus is completed for the previous index, this member check receives the decision through UpdateState to see if its members should change, this depends on the implementation. Once UpdateState is called, IsReady should always return true. IsReady may want to return true before this, if for example the consensus uses a fixed set of members, this will allow received messages to be processed earlier. MemberChecker needs to be concurrent safe for the IsReady method. CheckMemberBytes will be called by different threads after IsReady is true, if they are not read only then they will need some sync. If CheckMemberBytes return nil (a member is not found), then SpecialPubMemberChecker.CheckMemberLocalMsg will be called. An initial member checker is input to ConsState. Each member checker will then be created by calling new on this initial member checker. The member checker will not know about state changes since the initial state until UpdateState is called on it.

type MessageState

type MessageState interface {
	// 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).
	// If the message is not a signed type message (not type *sig.MultipleSignedMessage then (0, 0, nil) is returned).
	GotMsg(HeaderFunc,
		*deserialized.DeserializedItem, *generalconfig.GeneralConfig, *MemCheckers) ([]*deserialized.DeserializedItem, error)
	// GetMsgState should return the serialized state of all the valid messages received for this consensus instance.
	// This should be able to be processed by UnwrapMessage.
	// If generalconfig.UseFullBinaryState is true it returns the received signed messages together in a list.
	// Otherwise it returns each unique message with the list of signatures for each message behind it.
	// bufferContFunc is the same as consinterface.ConsItem.GetBufferCount(), the returned value endThreshold will
	// determine how many of each signature is added for each message type.
	// If localOnly is true then only proposal messages and signatures from the local node will be included.
	GetMsgState(priv sig.Priv, localOnly bool,
		bufferCountFunc BufferCountFunc,
		mc *MemCheckers) ([]byte, error)
	// New creates a new empty MessageState object for the consensus index idx.
	New(idx types.ConsensusIndex) MessageState
	// GetIndex returns the consensus index.
	GetIndex() types.ConsensusIndex
	// SetupSigned message takes a messages.InternalSignedMsgHeader, serializes the message appending signatures
	// creating and returning a new *sig.MultipleSignedMessage.
	// If generateMySig is true, the serialized message will include the local nodes signature.
	// Up to addOtherSigs number of signatures received so far for this message will additionally be appended.
	SetupSignedMessage(hdr messages.InternalSignedMsgHeader, generateMySig bool, addOthersSigsCount int, mc *MemCheckers) (*sig.MultipleSignedMessage, error)
	SetupUnsignedMessage(hdr messages.InternalSignedMsgHeader,
		mc *MemCheckers) (*sig.UnsignedMessage, error)
	// SetupSignedMessageDuplicates takes a list of headers that are assumed to have the same set of bytes to sign
	// (i.e. the signed parts are all the same though they may have different contents following the signed part,
	// for example this is true with partial messages)
	SetupSignedMessagesDuplicates(combined *messagetypes.CombinedMessage, hdrs []messages.InternalSignedMsgHeader,
		mc *MemCheckers) (combinedSigned *sig.MultipleSignedMessage, partialsSigned []*sig.MultipleSignedMessage, err error)
	GetSigCountMsg(types.HashStr) int                                                           // GetSigCountMsg returns the number of signatures received for this message.
	GetSigCountMsgHeader(header messages.InternalSignedMsgHeader, mc *MemCheckers) (int, error) // GetSigCountMsgHeader returns the number of signatures received for this header.
	GetSigCountMsgID(messages.MsgID) int                                                        // GetSigCountMsgID returns the number of sigs for this message's MsgID (see messages.MsgID).
	// GetSigCountMsgIDList returns list of received messages that have msgID for their MsgID and how many signatures have been received for each.
	GetSigCountMsgIDList(msgID messages.MsgID) []MsgIDCount
	// GetThreshSig returns the threshold signature for the message ID (if supported).
	GetThreshSig(hdr messages.InternalSignedMsgHeader, threshold int, mc *MemCheckers) (*sig.SigItem, error)
	// GetCoinVal returns the threshold coin value for the message ID (if supported).
	GetCoinVal(hdr messages.InternalSignedMsgHeader, threshold int, mc *MemCheckers) (coinVal types.BinVal, ready bool, err error)
}

MessageState tracks the signed messages received for each consensus instance.

type MsgIDCount

type MsgIDCount struct {
	MsgHeader *sig.MultipleSignedMessage
	Count     int // Count is the number of signatures received for MsgHeader.
}

MsgIDCount is used for the return value of MessageState.GetSigCountMsgIDList. It contains a header and the number of signatures received so far for that MsgID.

type SMStats

type SMStats interface {
	StatsString(testDuration time.Duration) string
}

type Shared

type Shared struct {
	PubKeys   sig.PubList    // The sorted list of public keys
	DSSShared *ed.CoinShared // Information for threshold keys
	BlsShare  *bls.BlsShared // state of Shared generated keys when using threshold BLS
	BlsShare2 *bls.BlsShared // state of Shared generated keys when using threshold BLS
	// contains filtered or unexported fields
}

func (*Shared) AfterSortPubs

func (sh *Shared) AfterSortPubs(myPriv sig.Priv, fixedCoord sig.Pub, members sig.PubList,
	otherPubs sig.PubList) (newMyPriv sig.Priv, coord sig.Pub, newMembers,
	newOtherPubs []sig.Pub, memberMap map[sig.PubKeyID]sig.Pub, allPubs []sig.Pub)

func (*Shared) GetAllPubKeys

func (sh *Shared) GetAllPubKeys(to types.TestOptions, privKey sig.Priv, parReg network.ParRegClientInterface,
) error

func (*Shared) GetStaticNodeMaps

func (sh *Shared) GetStaticNodeMaps(t assert.TestingT, to types.TestOptions, allPubs []sig.Pub,
	parRegs ...network.PregInterface) []map[sig.PubKeyStr]channelinterface.NetNodeInfo

func (*Shared) InitialKeySetup

func (sh *Shared) InitialKeySetup(to types.TestOptions, parReg network.ParRegClientInterface) error

type SortedTimeConsInterfaceItems

type SortedTimeConsInterfaceItems []*ConsInterfaceItems

func (SortedTimeConsInterfaceItems) Len

Len is the number of elements in the collection.

func (SortedTimeConsInterfaceItems) Less

func (si SortedTimeConsInterfaceItems) Less(i, j int) bool

Less reports whether the element with index i should sort before the element with index j.

func (SortedTimeConsInterfaceItems) Swap

func (si SortedTimeConsInterfaceItems) Swap(i, j int)

Swap swaps the elements with indexes i and j.

type SpecialPubMemberChecker

type SpecialPubMemberChecker interface {
	New(id types.ConsensusIndex) SpecialPubMemberChecker                                     // New generates a new member checker for the index, this is called on the inital special member checker each time.
	UpdateState(newPubs sig.PubList, randBytes [32]byte, prevMember SpecialPubMemberChecker) // UpdateState is called after MemberCheck.Update state. New pubs should be nil if they didn't change from the previous iteration.
	// CheckMemberLocalMsg checks if pub is a special member and returns new pub that has all the values filled.
	// This is called after MemberChecker.CheckMemberBytes in case a normal member is not found.
	// This sould be safe to be called concurrently.
	// It should also check if the member is a random member by calling CheckRandMember before returning successfullly.
	// TODO use a special pub type?
	// TODO this should be called with just they bytes like MemberChecker.CheckMemberBytes
	CheckMember(idx types.ConsensusIndex, pub sig.Pub, mc MemberChecker,
		hdr messages.InternalSignedMsgHeader, msgID messages.MsgID) (sig.Pub, error)
}

SpecialPubMemberChecker is used for keys that do not follow the rules of 1 key = 1 participant. For example multisignatures or threshold signatures. It should keep track of these keys, CheckMemberLocalMsg will only be called once MemberChecker.IsReady returns true. CheckMemberLocalMsg is called after MemberChecker.CheckMemberBytes in case a normal member is not found.

type StateMachineInterface

type StateMachineInterface interface {
	GeneralStateMachineInterface

	// GetProposal is called when a consensus index is ready for a proposal.
	// It should send the proposal for the consensus index by calling mainChannel.HasProposal().
	GetProposal()
	// HasDecided is called each time a consensus decision takes place, given the index and the decided vaule.
	// The indecies can be expected to be called in order starting at 1.
	// Proposer is the public key of the node that proposed the decision.
	HasDecided(proposer sig.Pub, index types.ConsensusInt, decision []byte)
	// StartIndex is called when the previous consensus index has finished.
	// It is called on the previous consensus index with the index of next state machine.
	// This might be called multiple times with multiple indicies as allowed by certain consensuses (e.g. mvcons3).
	// It should return the state machine instance for index index.
	StartIndex(index types.ConsensusInt) StateMachineInterface
	// FailAfter is for testing, once index is reached, it should send a message on doneChan (the input from Init), telling the consensus to shutdown.
	FailAfter(index types.ConsensusInt)
	// Init is called to initialize the object, lastProposal is the number of consensus instances to run, after which a message should be sent
	// on doneChan telling the consensus to shut down.
	// Need concurrent is the number of consensus indicies that need to be additionally run for the consensus to complete.
	// If basic init is true, then the SM will just be used for checking stats and checking decisions.
	Init(generalConfig *generalconfig.GeneralConfig, lastProposal types.ConsensusInt, needsConcurrent types.ConsensusInt,
		mainChannel channelinterface.MainChannel, doneChan chan channelinterface.ChannelCloseType, basicInit bool) // To set state
	// GetDone returns the done status of this SM.
	GetDone() types.DoneType
	// CheckDecisions is for testing and will be called at the end of the test with the ordered list of all the decided values, it should then check if the
	// decided values are valid.
	// Out of order errors are caused by committing proposals that did not see the previous proposal, which may be allowed by some consensuses.
	CheckDecisions([][]byte) (outOfOrderErrors, errors []error)
	// CheckStartStatsRecording is called before allocating an index to check if stats recording should start.
	CheckStartStatsRecording(index types.ConsensusInt)
}

StateMachineInterface represents the object running the application on top of the consensus. It is responsible for sending proposals to the consensus, it should do this by calling spi.mainChannel.HasProposal(). It should not call HasProposal for a consensus index until the previous index has completed.

Directories

Path Synopsis
ForwardCheckers keep track of successfully processes consensus messages and decide if they should be forwarded on the network or not.
ForwardCheckers keep track of successfully processes consensus messages and decide if they should be forwarded on the network or not.
Membercheckers are responsible for tracking who can participate in consensus by having a list of their public keys.
Membercheckers are responsible for tracking who can participate in consensus by having a list of their public keys.
MessageState tracks the signed messages received for each consensus instance, and does things like reject duplicates and check message thresholds.
MessageState tracks the signed messages received for each consensus instance, and does things like reject duplicates and check message thresholds.

Jump to

Keyboard shortcuts

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