bft

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2021 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	COMMITTED = iota
	PROPOSED
	PREPARED
	ABORT
)

These are the different phases

Variables

This section is empty.

Functions

func CheckInFlight

func CheckInFlight(messages []*protos.ViewData, f int, quorum int, N uint64, verifier api.Verifier) (ok, noInFlight bool, inFlightProposal *protos.Proposal, err error)

CheckInFlight checks if there is an in-flight proposal that needs to be decided on (because a node might decided on it already)

func CommitSignaturesDigest

func CommitSignaturesDigest(sigs []*protos.Signature) []byte

func MarshalOrPanic

func MarshalOrPanic(msg proto.Message) []byte

MarshalOrPanic marshals or panics when an error occurs

func MsgToString

func MsgToString(m *protos.Message) string

MsgToString converts a given message to a printable string

func ValidateInFlight

func ValidateInFlight(inFlightProposal *protos.Proposal, lastSequence uint64) error

ValidateInFlight validates the given in-flight proposal

func ValidateLastDecision

func ValidateLastDecision(vd *protos.ViewData, quorum int, N uint64, verifier api.Verifier) (lastSequence uint64, err error)

ValidateLastDecision validates the given decision, and returns its sequence when valid

Types

type ApplicationMock

type ApplicationMock interface {
	api.Application
}

ApplicationMock mock for the Application interface

type AssemblerMock

type AssemblerMock interface {
	api.Assembler
}

AssemblerMock mock for the Assembler interface

type BatchBuilder

type BatchBuilder struct {
	// contains filtered or unexported fields
}

BatchBuilder implements Batcher

func NewBatchBuilder

func NewBatchBuilder(pool RequestPool, submittedChan chan struct{}, maxMsgCount uint64, maxSizeBytes uint64, batchTimeout time.Duration) *BatchBuilder

NewBatchBuilder creates a new BatchBuilder

func (*BatchBuilder) Close

func (b *BatchBuilder) Close()

Close closes the close channel to stop NextBatch

func (*BatchBuilder) Closed

func (b *BatchBuilder) Closed() bool

Closed returns true if the batcher is closed

func (*BatchBuilder) NextBatch

func (b *BatchBuilder) NextBatch() [][]byte

NextBatch returns the next batch of requests to be proposed. The method returns as soon as the batch is full, in terms of request count or total size, or after a timeout. The method may block.

func (*BatchBuilder) Reset

func (b *BatchBuilder) Reset()

Reset reopens the close channel to allow calling NextBatch

type Batcher

type Batcher interface {
	NextBatch() [][]byte
	Close()
	Closed() bool
	Reset()
}

Batcher batches requests to eventually become a new proposal

type CheckpointRetriever

type CheckpointRetriever func() (protos.Proposal, []*protos.Signature)

type Comm

type Comm interface {
	api.Comm
	BroadcastConsensus(m *protos.Message)
}

Comm adds broadcast to the regular comm interface

type CommMock

type CommMock interface {
	api.Comm
	BroadcastConsensus(m *smartbftprotos.Message)
}

CommMock mock for the Comm interface

type Controller

type Controller struct {
	api.Comm
	// configuration
	ID                 uint64
	N                  uint64
	NodesList          []uint64
	LeaderRotation     bool
	DecisionsPerLeader uint64
	RequestPool        RequestPool
	Batcher            Batcher
	LeaderMonitor      LeaderMonitor
	Verifier           api.Verifier
	Logger             api.Logger
	Assembler          api.Assembler
	Application        api.Application
	FailureDetector    FailureDetector
	Synchronizer       api.Synchronizer
	Signer             api.Signer
	RequestInspector   api.RequestInspector
	WAL                api.WriteAheadLog
	ProposerBuilder    ProposerBuilder
	Checkpoint         *types.Checkpoint
	ViewChanger        *ViewChanger
	Collector          *StateCollector
	State              State

	ViewSequences *atomic.Value

	StartedWG *sync.WaitGroup
	// contains filtered or unexported fields
}

Controller controls the entire flow of the consensus

func (*Controller) AbortView

func (c *Controller) AbortView(view uint64)

AbortView makes the controller abort the current view

func (*Controller) BroadcastConsensus

func (c *Controller) BroadcastConsensus(m *protos.Message)

BroadcastConsensus broadcasts the message and informs the heartbeat monitor if necessary

func (*Controller) Decide

func (c *Controller) Decide(proposal types.Proposal, signatures []types.Signature, requests []types.RequestInfo)

Decide delivers the decision to the application

func (*Controller) GetLeaderID

func (c *Controller) GetLeaderID() uint64

func (*Controller) HandleRequest

func (c *Controller) HandleRequest(sender uint64, req []byte)

HandleRequest handles a request from the client

func (*Controller) MaybePruneRevokedRequests

func (c *Controller) MaybePruneRevokedRequests()

MaybePruneRevokedRequests prunes requests with different verification sequence

func (*Controller) OnAutoRemoveTimeout

func (c *Controller) OnAutoRemoveTimeout(requestInfo types.RequestInfo)

OnAutoRemoveTimeout is called when the auto-remove timeout expires. Called by the request-pool timeout goroutine.

func (*Controller) OnHeartbeatTimeout

func (c *Controller) OnHeartbeatTimeout(view uint64, leaderID uint64)

OnHeartbeatTimeout is called when the heartbeat timeout expires. Called by the HeartbeatMonitor goroutine.

func (*Controller) OnLeaderFwdRequestTimeout

func (c *Controller) OnLeaderFwdRequestTimeout(request []byte, info types.RequestInfo)

OnLeaderFwdRequestTimeout is called when the leader-forward timeout expires, and complains about the leader. Called by the request-pool timeout goroutine. Upon return, the auto-remove timeout is started.

func (*Controller) OnRequestTimeout

func (c *Controller) OnRequestTimeout(request []byte, info types.RequestInfo)

OnRequestTimeout is called when request-timeout expires and forwards the request to leader. Called by the request-pool timeout goroutine. Upon return, the leader-forward timeout is started.

func (*Controller) ProcessMessages

func (c *Controller) ProcessMessages(sender uint64, m *protos.Message)

ProcessMessages dispatches the incoming message to the required component

func (*Controller) Start

func (c *Controller) Start(startViewNumber uint64, startProposalSequence uint64, startDecisionsInView uint64, syncOnStart bool)

Start the controller

func (*Controller) Stop

func (c *Controller) Stop()

Stop the controller

func (*Controller) StopWithPoolPause

func (c *Controller) StopWithPoolPause()

Stop the controller but only stop the requests pool timers

func (*Controller) SubmitRequest

func (c *Controller) SubmitRequest(request []byte) error

SubmitRequest Submits a request to go through consensus.

func (*Controller) Sync

func (c *Controller) Sync()

Sync initiates a synchronization

func (*Controller) ViewChanged

func (c *Controller) ViewChanged(newViewNumber uint64, newProposalSequence uint64)

ViewChanged makes the controller abort the current view and start a new one with the given numbers

type Decider

type Decider interface {
	Decide(proposal types.Proposal, signatures []types.Signature, requests []types.RequestInfo)
}

Decider delivers the proposal with signatures to the application

type FailureDetector

type FailureDetector interface {
	Complain(viewNum uint64, stopView bool)
}

FailureDetector initiates a view change when there is a complaint

type HeartbeatEventHandler

type HeartbeatEventHandler interface {
	// OnHeartbeatTimeout is called when a heartbeat timeout expires.
	OnHeartbeatTimeout(view uint64, leaderID uint64)
	// Sync is called when enough heartbeat responses report that the current leader's view is outdated.
	Sync()
}

HeartbeatEventHandler defines who to call when a heartbeat timeout expires or a Sync needs to be triggered. This is implemented by the Controller.

type HeartbeatMonitor

type HeartbeatMonitor struct {
	// contains filtered or unexported fields
}

HeartbeatMonitor implements LeaderMonitor

func NewHeartbeatMonitor

func NewHeartbeatMonitor(scheduler <-chan time.Time, logger api.Logger, heartbeatTimeout time.Duration, heartbeatCount uint64, comm Comm, numberOfNodes uint64, handler HeartbeatEventHandler, viewSequences *atomic.Value, numOfTicksBehindBeforeSyncing uint64) *HeartbeatMonitor

NewHeartbeatMonitor creates a new HeartbeatMonitor

func (*HeartbeatMonitor) ChangeRole

func (hm *HeartbeatMonitor) ChangeRole(follower Role, view uint64, leaderID uint64)

ChangeRole will change the role of this HeartbeatMonitor

func (*HeartbeatMonitor) Close

func (hm *HeartbeatMonitor) Close()

Close stops following or sending heartbeats.

func (*HeartbeatMonitor) HeartbeatWasSent

func (hm *HeartbeatMonitor) HeartbeatWasSent()

HeartbeatWasSent tells the monitor to skip sending a heartbeat

func (*HeartbeatMonitor) InjectArtificialHeartbeat

func (hm *HeartbeatMonitor) InjectArtificialHeartbeat(sender uint64, msg *smartbftprotos.Message)

InjectArtificialHeartbeat injects an artificial heartbeat to the monitor

func (*HeartbeatMonitor) ProcessMsg

func (hm *HeartbeatMonitor) ProcessMsg(sender uint64, msg *smartbftprotos.Message)

ProcessMsg handles an incoming heartbeat or heartbeat-response. If the sender and msg.View equal what we expect, and the timeout had not expired yet, the timeout is extended.

type InFlightData

type InFlightData struct {
	// contains filtered or unexported fields
}

InFlightData records proposals that are in-flight, as well as their corresponding prepares.

func (*InFlightData) InFlightProposal

func (ifp *InFlightData) InFlightProposal() *types.Proposal

InFlightProposal returns an in-flight proposal or nil if there is no such.

func (*InFlightData) IsInFlightPrepared

func (ifp *InFlightData) IsInFlightPrepared() bool

IsInFlightPrepared returns true if the in-flight proposal is prepared.

func (*InFlightData) StorePrepares

func (ifp *InFlightData) StorePrepares(view, seq uint64)

StorePrepares stores alongside the already stored in-flight proposal that it is prepared.

func (*InFlightData) StoreProposal

func (ifp *InFlightData) StoreProposal(prop types.Proposal)

StoreProposal stores an in-flight proposal.

type IntDoubleByte

type IntDoubleByte struct {
	A    int64
	B, C []byte
}

type IntDoubleBytes

type IntDoubleBytes struct {
	A []IntDoubleByte
}

type LeaderMonitor

type LeaderMonitor interface {
	ChangeRole(role Role, view uint64, leaderID uint64)
	ProcessMsg(sender uint64, msg *protos.Message)
	InjectArtificialHeartbeat(sender uint64, msg *protos.Message)
	HeartbeatWasSent()
	Close()
}

LeaderMonitor monitors the heartbeat from the current leader

type MembershipNotifierMock

type MembershipNotifierMock interface {
	api.MembershipNotifier
}

MembershipNotifierMock mock for the MembershipNotifier interface

type PersistedState

type PersistedState struct {
	InFlightProposal *InFlightData
	Entries          [][]byte
	Logger           api.Logger
	WAL              api.WriteAheadLog
}

func (*PersistedState) LoadNewViewIfApplicable

func (ps *PersistedState) LoadNewViewIfApplicable() (*types.ViewAndSeq, error)

func (*PersistedState) LoadViewChangeIfApplicable

func (ps *PersistedState) LoadViewChangeIfApplicable() (*protos.ViewChange, error)

func (*PersistedState) Restore

func (ps *PersistedState) Restore(v *View) error

func (*PersistedState) Save

func (ps *PersistedState) Save(msgToSave *protos.SavedMessage) error

type Phase

type Phase uint8

Phase indicates the status of the view

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool implements requests pool, maintains pool of given size provided during construction. In case there are more incoming request than given size it will block during submit until there will be place to submit new ones.

func NewPool

func NewPool(log api.Logger, inspector api.RequestInspector, th RequestTimeoutHandler, options PoolOptions, submittedChan chan struct{}) *Pool

NewPool constructs new requests pool

func (*Pool) ChangeTimeouts

func (rp *Pool) ChangeTimeouts(th RequestTimeoutHandler, options PoolOptions)

ChangeTimeouts changes the timeout of the pool

func (*Pool) Close

func (rp *Pool) Close()

Close removes all the requests, stops all the timeout timers.

func (*Pool) NextRequests

func (rp *Pool) NextRequests(maxCount int, maxSizeBytes uint64, check bool) (batch [][]byte, full bool)

NextRequests returns the next requests to be batched. It returns at most maxCount requests, and at most maxSizeBytes, in a newly allocated slice. Return variable full indicates that the batch cannot be increased further by calling again with the same arguments.

func (*Pool) Prune

func (rp *Pool) Prune(predicate func([]byte) error)

Prune removes requests for which the given predicate returns error.

func (*Pool) RemoveRequest

func (rp *Pool) RemoveRequest(requestInfo types.RequestInfo) error

RemoveRequest removes the given request from the pool

func (*Pool) RestartTimers

func (rp *Pool) RestartTimers()

RestartTimers restarts all the timeout timers attached to the pending requests, as RequestForwardTimeout, and re-allows submission of new requests.

func (*Pool) Size

func (rp *Pool) Size() int

Size returns the number of requests currently residing the pool

func (*Pool) StopTimers

func (rp *Pool) StopTimers()

StopTimers stops all the timeout timers attached to the pending requests, and marks the pool as "stopped". This which prevents submission of new requests, and renewal of timeouts by timer go-routines that where running at the time of the call to StopTimers().

func (*Pool) Submit

func (rp *Pool) Submit(request []byte) error

Submit a request into the pool, returns an error when request is already in the pool

type PoolOptions

type PoolOptions struct {
	QueueSize         int64
	ForwardTimeout    time.Duration
	ComplainTimeout   time.Duration
	AutoRemoveTimeout time.Duration
}

PoolOptions is the pool configuration

type ProposalMaker

type ProposalMaker struct {
	DecisionsPerLeader uint64
	N                  uint64
	SelfID             uint64
	Decider            Decider
	FailureDetector    FailureDetector
	Sync               Synchronizer
	Logger             api.Logger
	Comm               Comm
	Verifier           api.Verifier
	Signer             api.Signer
	MembershipNotifier api.MembershipNotifier
	State              State
	InMsqQSize         int
	ViewSequences      *atomic.Value

	Checkpoint *types.Checkpoint
	// contains filtered or unexported fields
}

ProposalMaker implements ProposerBuilder

func (*ProposalMaker) NewProposer

func (pm *ProposalMaker) NewProposer(leader, proposalSequence, viewNum, decisionsInView uint64, quorumSize int) Proposer

NewProposer returns a new view

type Proposer

type Proposer interface {
	Propose(proposal types.Proposal)
	Start()
	Abort()
	GetMetadata() []byte
	HandleMessage(sender uint64, m *protos.Message)
}

Proposer proposes a new proposal to be agreed on

type ProposerBuilder

type ProposerBuilder interface {
	NewProposer(leader, proposalSequence, viewNum, decisionsInView uint64, quorumSize int) Proposer
}

ProposerBuilder builds a new Proposer

type Pruner

type Pruner interface {
	MaybePruneRevokedRequests()
}

Pruner prunes revoked requests

type RequestPool

type RequestPool interface {
	Prune(predicate func([]byte) error)
	Submit(request []byte) error
	Size() int
	NextRequests(maxCount int, maxSizeBytes uint64, check bool) (batch [][]byte, full bool)
	RemoveRequest(request types.RequestInfo) error
	StopTimers()
	RestartTimers()
	Close()
}

RequestPool is a pool of client's requests

type RequestTimeoutHandler

type RequestTimeoutHandler interface {

	// OnRequestTimeout is called when a request timeout expires.
	OnRequestTimeout(request []byte, requestInfo types.RequestInfo)

	// OnLeaderFwdRequestTimeout is called when a leader forwarding timeout expires.
	OnLeaderFwdRequestTimeout(request []byte, requestInfo types.RequestInfo)

	// OnAutoRemoveTimeout is called when a auto-remove timeout expires.
	OnAutoRemoveTimeout(requestInfo types.RequestInfo)
}

RequestTimeoutHandler defines the methods called by request timeout timers created by time.AfterFunc. This interface is implemented by the bft.Controller.

type RequestsTimer

type RequestsTimer interface {
	StopTimers()
	RestartTimers()
	RemoveRequest(request types.RequestInfo) error
}

RequestsTimer controls requests

type Role

type Role bool

Role indicates if this node is a follower or a leader

const (
	Leader   Role = false
	Follower Role = true
)

A node could either be a leader or a follower

type Scheduler

type Scheduler struct {
	// contains filtered or unexported fields
}

func NewScheduler

func NewScheduler(timeChan <-chan time.Time) *Scheduler

func (*Scheduler) Schedule

func (s *Scheduler) Schedule(timeout time.Duration, f func()) Stopper

func (*Scheduler) Start

func (s *Scheduler) Start()

func (*Scheduler) Stop

func (s *Scheduler) Stop()

type SignerMock

type SignerMock interface {
	api.Signer
}

SignerMock mock for the Signer interface

type State

type State interface {
	// Save saves a message.
	Save(message *protos.SavedMessage) error

	// Restore restores the given view to its latest state
	// before a crash, if applicable.
	Restore(*View) error
}

State can save and restore the state

type StateCollector

type StateCollector struct {
	SelfID uint64
	N      uint64

	Logger api.Logger

	CollectTimeout time.Duration
	// contains filtered or unexported fields
}

StateCollector collects the current state from other nodes

func (*StateCollector) ClearCollected

func (s *StateCollector) ClearCollected()

ClearCollected clears the responses collected by the state collector

func (*StateCollector) CollectStateResponses

func (s *StateCollector) CollectStateResponses() *types.ViewAndSeq

CollectStateResponses return a valid response or nil if reached timeout

func (*StateCollector) HandleMessage

func (s *StateCollector) HandleMessage(sender uint64, m *protos.Message)

HandleMessage handle messages addressed to the state collector

func (*StateCollector) Start

func (s *StateCollector) Start()

Start starts the state collector

func (*StateCollector) Stop

func (s *StateCollector) Stop()

Stop the state collector

type StateRecorder

type StateRecorder struct {
	SavedMessages []*protos.SavedMessage
}

func (*StateRecorder) Restore

func (*StateRecorder) Restore(_ *View) error

func (*StateRecorder) Save

func (sr *StateRecorder) Save(message *protos.SavedMessage) error

type Stopper

type Stopper interface {
	Stop()
}

type Synchronizer

type Synchronizer interface {
	Sync()
}

Synchronizer mock for the Synchronizer interface (no return value)

type SynchronizerMock

type SynchronizerMock interface {
	api.Synchronizer
}

SynchronizerMock mock for the Synchronizer interface

type Task

type Task struct {
	Deadline time.Time
	F        func()
	// contains filtered or unexported fields
}

func (*Task) Stop

func (t *Task) Stop()

type TaskQueue

type TaskQueue struct {
	// contains filtered or unexported fields
}

func NewTaskQueue

func NewTaskQueue() *TaskQueue

func (*TaskQueue) DeQueue

func (q *TaskQueue) DeQueue() *Task

func (*TaskQueue) Enqueue

func (q *TaskQueue) Enqueue(t *Task)

func (TaskQueue) Size

func (q TaskQueue) Size() int

func (*TaskQueue) Top

func (q *TaskQueue) Top() *Task

type VerifierMock

type VerifierMock interface {
	api.Verifier
}

VerifierMock mock for the Verifier interface

type View

type View struct {
	// Configuration
	DecisionsPerLeader uint64
	RetrieveCheckpoint CheckpointRetriever
	SelfID             uint64
	N                  uint64
	LeaderID           uint64
	Quorum             int
	Number             uint64
	Decider            Decider
	FailureDetector    FailureDetector
	Sync               Synchronizer
	Logger             api.Logger
	Comm               Comm
	Verifier           api.Verifier
	Signer             api.Signer
	MembershipNotifier api.MembershipNotifier
	ProposalSequence   uint64
	DecisionsInView    uint64
	State              State
	Phase              Phase
	InMsgQSize         int

	ViewSequences *atomic.Value
	// contains filtered or unexported fields
}

View is responsible for running the view protocol

func (*View) Abort

func (v *View) Abort()

Abort forces the view to end

func (*View) GetMetadata

func (v *View) GetMetadata() []byte

GetMetadata returns the current sequence and view number (in a marshaled ViewMetadata protobuf message)

func (*View) HandleMessage

func (v *View) HandleMessage(sender uint64, m *protos.Message)

HandleMessage handles incoming messages

func (*View) Propose

func (v *View) Propose(proposal types.Proposal)

Propose broadcasts a prePrepare message with the given proposal

func (*View) Start

func (v *View) Start()

Start starts the view

type ViewChanger

type ViewChanger struct {
	// Configuration
	SelfID    uint64
	NodesList []uint64
	N         uint64

	SpeedUpViewChange  bool
	LeaderRotation     bool
	DecisionsPerLeader uint64

	Logger       api.Logger
	Comm         Comm
	Signer       api.Signer
	Verifier     api.Verifier
	Application  api.Application
	Synchronizer Synchronizer

	Checkpoint *types.Checkpoint
	InFlight   *InFlightData
	State      State

	Controller    ViewController
	RequestsTimer RequestsTimer
	Pruner        Pruner

	// for the in flight proposal view
	ViewSequences *atomic.Value

	Ticker <-chan time.Time

	ResendTimeout time.Duration

	ViewChangeTimeout time.Duration

	// Runtime
	Restore    chan struct{}
	InMsqQSize int

	ControllerStartedWG sync.WaitGroup
	// contains filtered or unexported fields
}

ViewChanger is responsible for running the view change protocol

func (*ViewChanger) Complain

func (v *ViewChanger) Complain(viewNum uint64, stopView bool)

Complain panics when a view change is requested

func (*ViewChanger) Decide

func (v *ViewChanger) Decide(proposal types.Proposal, signatures []types.Signature, requests []types.RequestInfo)

Decide delivers to the application and informs the view changer after delivery

func (*ViewChanger) HandleMessage

func (v *ViewChanger) HandleMessage(sender uint64, m *protos.Message)

HandleMessage passes a message to the view changer

func (*ViewChanger) HandleViewMessage

func (v *ViewChanger) HandleViewMessage(sender uint64, m *protos.Message)

HandleViewMessage passes a message to the in flight proposal view if applicable

func (*ViewChanger) InformNewView

func (v *ViewChanger) InformNewView(view uint64)

InformNewView tells the view changer to advance to a new view number

func (*ViewChanger) Start

func (v *ViewChanger) Start(startViewNumber uint64)

Start the view changer

func (*ViewChanger) StartViewChange

func (v *ViewChanger) StartViewChange(view uint64, stopView bool)

StartViewChange initiates a view change

func (*ViewChanger) Stop

func (v *ViewChanger) Stop()

Stop the view changer

func (*ViewChanger) Sync

func (v *ViewChanger) Sync()

Sync calls the synchronizer and informs the view changer of the sync

type ViewController

type ViewController interface {
	ViewChanged(newViewNumber uint64, newProposalSequence uint64)
	AbortView(view uint64)
}

ViewController controls the view

type ViewSequence

type ViewSequence struct {
	ViewActive  bool
	ProposalSeq uint64
}

ViewSequence indicates if a view is currently active and its current proposal sequence

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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