common

package
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2023 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SerializePreprepareForHashing

func SerializePreprepareForHashing(preprepare *pbftpbtypes.Preprepare) *hasherpbtypes.HashData

SerializePreprepareForHashing returns a slice of byte slices representing the contents of a Preprepare message that can be passed to the Hasher module. Note that the view number is *not* serialized, as hashes must be consistent across views. Even though the preprepare argument is a protocol buffer, this function is required to guarantee that the serialization is deterministic, since the protobuf native serialization does not provide this guarantee.

func SerializeViewChangeForSigning

func SerializeViewChangeForSigning(vc *pbftpbtypes.ViewChange) *cryptopbtypes.SignedData

Types

type ModuleParams

type ModuleParams struct {
	// The ID of this node.
	OwnID types.NodeID

	// PBFT-specific configuration parameters (e.g. view change timeout, etc.)
	Config *PBFTConfig
}

type PBFTConfig

type PBFTConfig struct {

	// The IDs of all nodes that execute this instance of the protocol.
	// Must not be empty.
	Membership []t.NodeID

	// The maximum time duration between two proposals of new certificatees during normal operation.
	// This parameter caps the waiting time in order to bound latency.
	// When MaxProposeDelay has elapsed since the last proposal,
	// the protocol tries to propose a new availability certificate.
	// Must not be negative.
	MaxProposeDelay time.Duration

	// When a node has committed all certificates in a segment, it will periodically send the Done message
	// in intervals of DoneResendPeriod.
	DoneResendPeriod time.Duration

	// After a node learns about a quorum of other nodes finishing a segment,
	// it waits for CatchUpDelay before requesting missing committed certificates from other nodes.
	CatchUpDelay time.Duration

	// Maximal number of bytes used for message backlogging buffers
	// (only message payloads are counted towards MsgBufCapacity).
	// Same as ModuleParams.MsgBufCapacity, but used only for one instance of PBFT.
	// Must not be negative.
	MsgBufCapacity int

	// Per-sequence-number view change timeout for view 0.
	// If no certificate is delivered by a PBFT instance within this timeout, the node triggers a view change.
	// With each new view, the timeout doubles (without changing this value)
	ViewChangeSNTimeout time.Duration

	// View change timeout for view 0 for the whole segment.
	// If not all certificates of the associated segment are delivered by a PBFT instance within this timeout,
	// the node triggers a view change.
	// With each new view, the timeout doubles (without changing this value)
	ViewChangeSegmentTimeout time.Duration

	// Time period between resending a ViewChange message.
	// ViewChange messages need to be resent periodically to preserve liveness.
	// Otherwise, the system could get stuck if a ViewChange message is dropped by the network.
	ViewChangeResendPeriod time.Duration

	// The current epoch number
	EpochNr tt.EpochNr
}

PBFTConfig holds PBFT-specific configuration parameters used by a concrete instance of PBFT. They are mostly inherited from the ISS configuration at the time of creating the PBFT instance.

type PbftProposalState

type PbftProposalState struct {

	// Tracks the number of proposals already made.
	// Used to calculate the sequence number of the next proposal (from the associated segment's sequence numbers)
	// and to stop proposing when a proposal has been made for all sequence numbers.
	ProposalsMade int

	// Flag indicating whether a new certificate has been requested from ISS.
	// This effectively means that a proposal is in progress and no new proposals should be started.
	// This is required, since the PBFT implementation does not assemble availability certificates itself
	// (which, in general, do not exclusively concern the State and are thus managed by ISS directly).
	// Instead, when the PBFT instance is ready to propose,
	// it requests a new certificate from the enclosing ISS implementation.
	CertRequested bool

	// If CertRequested is true, CertRequestedView indicates the PBFT view
	// in which the PBFT protocol was when the certificate was requested.
	// When the certificate is ready, the protocol needs to check whether it is still in the same view
	// as when the certificate was requested.
	// If the view advanced in the meantime, the proposal must be aborted and the contained transactions resurrected
	// If CertRequested is false, CertRequestedView must not be used.
	CertRequestedView ot.ViewNr

	// the number of proposals for which the timeout has passed.
	// If this number is higher than proposalsMade, a new certificate can be proposed.
	ProposalTimeout int
}

PbftProposalState tracks the state of the pbftInstance related to proposing certificates. The proposal state is only used if this node is the leader of this instance of PBFT.

type PbftSegmentChkp

type PbftSegmentChkp struct {

	// This flag is set once the retransmission of missing committed entries is requested.
	// It serves preventing redundant retransmission entries when more than a quorum of Done messages are received.
	CatchingUp bool
	// contains filtered or unexported fields
}

PbftSegmentChkp groups data structures pertaining to an instance-local checkpoint created when all slots have been committed. If correct nodes stop participating in the protocol immediately after having delivered all certificates in a segment, a minority of nodes might get stuck in higher views if they did not deliver all certificates yet, never finding enough support for finishing a view change. The high-level checkpoints (encompassing all segments) are not enough to resolve this problem, because multiple segments can block each other, each with its own majority of nodes that finish it, but with too few nodes that finished all segments. If, for example, each segment only has one node that fails to complete it, no high-level checkpoint can be constructed, as too few nodes will have delivered everything from all the segments. Thus, local instance-level checkpoints are required, so nodes can catch up on each segment separately.

func NewPbftSegmentChkp

func NewPbftSegmentChkp() *PbftSegmentChkp

NewPbftSegmentChkp returns a pointer to a new instance of PbftSegmentChkp

func (*PbftSegmentChkp) Digests

func (chkp *PbftSegmentChkp) Digests() map[types2.SeqNr][]byte

Digests returns, for each sequence number of the associated segment, the digest of the committed certificate (more precisely, the digest of the corresponding Preprepare message). If the information is not yet available (not enough Done messages have been received), Digests returns nil.

func (*PbftSegmentChkp) DoneNodes

func (chkp *PbftSegmentChkp) DoneNodes() []types.NodeID

DoneNodes returns a list of IDs of Nodes from which a matching Done message has been received. If a quorum of Done messages has not yet been received, DoneNodes returns nil.

func (*PbftSegmentChkp) NodeDone

func (chkp *PbftSegmentChkp) NodeDone(nodeID types.NodeID, doneDigests [][]byte, segment *common.Segment)

NodeDone registers a Done message received from a node. Once NodeDone has been called with matching Done messages for a quorum of nodes, the instance-level checkpoint will become stable.

func (*PbftSegmentChkp) SetDone

func (chkp *PbftSegmentChkp) SetDone()

SetDone marks the local checkpoint as done. It must be called after all slots of the segment have been committed. This is a necessary condition for the checkpoint to be considered stable.

func (*PbftSegmentChkp) Stable

func (chkp *PbftSegmentChkp) Stable(membership *trantorpbtypes.Membership) bool

Stable returns true if the instance-level checkpoint is stable, i.e., if all slots have been committed and a strong quorum of matching Done messages has been received. This ensures that at least a weak quorum of correct nodes has a local checkpoint and thus evey correct node will be able to catch up.

type PbftSlot

type PbftSlot struct {

	// The received preprepare message.
	Preprepare *pbftpbtypes.Preprepare

	// Prepare messages received, indexed by sending node's ID.
	// A nil entry signifies that an invalid message has been discarded.
	PrepareDigests map[t.NodeID][]byte

	// Valid prepare messages received, indexed by sending node's ID.
	// Serves mostly as an optimization to not re-validate already validated messages.
	ValidPrepareDigests map[t.NodeID][]byte

	// Commit messages received, indexed by sending node's ID.
	CommitDigests map[t.NodeID][]byte

	// Valid commit messages received, indexed by sending node's ID.
	// Serves mostly as an optimization to not re-validate already validated messages.
	ValidCommitDigests map[t.NodeID][]byte

	// The digest of the proposed (preprepared) certificate
	Digest []byte

	// Flags denoting whether a certificate has been, respectively, preprepared, prepared, and committed in this slot.
	// Note that Preprepared == true is not equivalent to Preprepare != nil, since the Preprepare message is stored
	// before the node preprepares the proposal (it first has to hash the contents of the message
	// and only then can preprepare the proposal and send the Prepare messages).
	Preprepared bool
	Prepared    bool
	Committed   bool
	// contains filtered or unexported fields
}

PbftSlot tracks the state of the agreement protocol for one sequence number, such as messages received, progress of the reliable broadcast, etc.

func NewPbftSlot

func NewPbftSlot(membership *trantorpbtypes.Membership) *PbftSlot

NewPbftSlot allocates a new PbftSlot object and returns it, initializing all its fields.

func (*PbftSlot) CatchUp

func (slot *PbftSlot) CatchUp(preprepare *pbftpbtypes.Preprepare, digest []byte)

Note: The Preprepare's view must match the view this slot is assigned to!

func (*PbftSlot) CheckCommitted

func (slot *PbftSlot) CheckCommitted() bool

CheckCommitted evaluates whether the PbftSlot fulfills the conditions to be committed. The slot can be committed when it has been prepared and when enough valid Commit messages have been received.

func (*PbftSlot) CheckPrepared

func (slot *PbftSlot) CheckPrepared() bool

CheckPrepared evaluates whether the PbftSlot fulfills the conditions to be prepared. The slot can be prepared when it has been preprepared and when enough valid Prepare messages have been received.

func (*PbftSlot) GetPreprepare

func (slot *PbftSlot) GetPreprepare(digest []byte) *pbftpbtypes.Preprepare

func (*PbftSlot) PopulateFromPrevious

func (slot *PbftSlot) PopulateFromPrevious(prevSlot *PbftSlot, view ot.ViewNr)

PopulateFromPrevious carries over state from a PbftSlot used in the previous view to this PbftSlot, based on the state of the previous slot. This is used during view change, when the protocol initializes a new PBFT view.

type PbftViewChangeState

type PbftViewChangeState struct {
	Membership        *trantorpbtypes.Membership
	SignedViewChanges map[t.NodeID]*pbftpbtypes.SignedViewChange

	// Digests of Preprepares that need to be repropsed in a new view.
	// At initialization, an explicit nil entry is created for each sequence number of the segment.
	// Based on received ViewChange messages, each value will eventually be set to
	// - either a non-zero-length byte slice representing a digest to be re-proposed
	// - or a zero-length byte slice marking it safe to re-propose a special fresh value
	// (in the current implementation, the fresh value is a pre-configured proposal
	// or, if none has been specified, an empty byte slice).
	Reproposals map[tt.SeqNr][]byte

	// Preprepare messages to be reproposed in the new view.
	// At initialization, an explicit nil entry is created for each sequence number of the segment.
	// Based on received ViewChange messages, each value will eventually be set to
	// a new Preprepare message to be re-proposed (with a correctly set view number).
	// This also holds for sequence numbers for which nothing was prepared in the previous view,
	// in which case the value is set to a fresh Preprepare (as configured) and the "aborted" flag set.
	Preprepares map[tt.SeqNr]*pbftpbtypes.Preprepare

	PrepreparedIDs map[tt.SeqNr][]t.NodeID
}

PbftViewChangeState tracks the state of the view change sub-protocol in PBFT. It is only associated with a single view transition, e.g., the transition from view 1 to view 2. The transition from view 2 to view 3 will be tracked by a different instance of PbftViewChangeState.

func NewPbftViewChangeState

func NewPbftViewChangeState(seqNrs []tt.SeqNr, membership *trantorpbtypes.Membership) *PbftViewChangeState

func (*PbftViewChangeState) AddSignedViewChange

func (vcState *PbftViewChangeState) AddSignedViewChange(svc *pbftpbtypes.SignedViewChange, from t.NodeID, logger logging.Logger)

func (*PbftViewChangeState) EnoughViewChanges

func (vcState *PbftViewChangeState) EnoughViewChanges() bool

func (*PbftViewChangeState) HasAllPreprepares

func (vcState *PbftViewChangeState) HasAllPreprepares() bool

func (*PbftViewChangeState) SetEmptyPreprepareDigests

func (vcState *PbftViewChangeState) SetEmptyPreprepareDigests(digests [][]byte) error

func (*PbftViewChangeState) SetEmptyPreprepares

func (vcState *PbftViewChangeState) SetEmptyPreprepares(view ot.ViewNr, proposals map[tt.SeqNr][]byte) []*hasherpbtypes.HashData

func (*PbftViewChangeState) SetLocalPreprepares

func (vcState *PbftViewChangeState) SetLocalPreprepares(state *State, view ot.ViewNr)

type State

type State struct {

	// The segment governing this SB instance, specifying the leader, the set of sequence numbers, etc.
	Segment *common.Segment

	// Buffers representing a backlog of messages destined to future views.
	// A node that already transitioned to a newer view might send messages,
	// while this node is behind (still in an older view) and cannot process these messages yet.
	// Such messages end up in this buffer (if there is buffer space) for later processing.
	// The buffer is checked after each view change.
	MessageBuffers map[types.NodeID]*messagebuffer.MessageBuffer

	// Tracks the state related to proposing availability certificates.
	Proposal PbftProposalState

	// For each view, slots contains one PbftSlot per sequence number this State is responsible for.
	// Each slot tracks the state of the agreement protocol for one sequence number.
	Slots map[ot.ViewNr]map[tt.SeqNr]*PbftSlot

	// Tracks the state of the segment-local checkpoint.
	SegmentCheckpoint *PbftSegmentChkp

	// PBFT view
	View ot.ViewNr

	// Flag indicating whether this node is currently performing a view change.
	// It is set on sending the ViewChange message and cleared on accepting a new view.
	InViewChange bool

	// For each view transition, stores the state of the corresponding PBFT view change sub-protocol.
	// The map itself is allocated on creation of the pbftInstance, but the entries are initialized lazily,
	// only when needed (when the node initiates a view change).
	ViewChangeStates map[ot.ViewNr]*PbftViewChangeState
}

State represents a PBFT State. It implements the sbInstance (instance of Sequenced broadcast) interface and thus can be used as an State for ISS.

func (*State) AllCommitted

func (state *State) AllCommitted() bool

AllCommitted returns true if all slots of this pbftInstance in the current view are in the committed state (i.e., have the committed flag set).

func (*State) InitView

func (state *State) InitView(
	m dsl.Module,
	params *ModuleParams,
	moduleConfig common.ModuleConfig,
	view ot.ViewNr,
	logger logging.Logger,
) error

func (*State) LookUpPreprepare

func (state *State) LookUpPreprepare(sn tt.SeqNr, digest []byte) *pbftpbtypes.Preprepare

func (*State) NumCommitted

func (state *State) NumCommitted(view ot.ViewNr) int

NumCommitted returns the number of slots that are already committed in the given view.

type ViewChangePSet

type ViewChangePSet map[tt.SeqNr]*pbftpbtypes.PSetEntry

ViewChangePSet represents the P set of a PBFT view change message. For each sequence number, it holds the digest of the last prepared value, along with the view in which it was prepared.

func (ViewChangePSet) PbType

func (pSet ViewChangePSet) PbType() []*pbftpbtypes.PSetEntry

PbType returns a protobuf type representation (not a raw protobuf, but the generated type) of a viewChangePSet, Where all entries are stored in a simple list. The list is sorted for repeatability.

type ViewChangeQSet

type ViewChangeQSet map[tt.SeqNr]map[string]ot.ViewNr

The Q set of a PBFT view change message. For each sequence number, it holds the digests (encoded as string map keys) of all values preprepared for that sequence number, along with the latest view in which each of them was preprepared.

func (ViewChangeQSet) PbType

func (qSet ViewChangeQSet) PbType() []*pbftpbtypes.QSetEntry

PbType returns a protobuf tye representation (not a raw protobuf, but the generated type) of a ViewChangeQSet, where all entries, represented as (sn, view, digest) tuples, are stored in a simple list. The list is sorted for repeatability.

Jump to

Keyboard shortcuts

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