Documentation ¶
Index ¶
- Constants
- Variables
- type DefaultPaceMaker
- type DefaultSaftyRules
- func (s *DefaultSaftyRules) CalVotesThreshold(input, sum int) bool
- func (s *DefaultSaftyRules) CheckPacemaker(pending int64, local int64) bool
- func (s *DefaultSaftyRules) CheckProposal(proposal, parent QuorumCertInterface, justifyValidators []string) error
- func (s *DefaultSaftyRules) CheckVote(qc QuorumCertInterface, logid string, validators []string) error
- func (s *DefaultSaftyRules) UpdatePreferredRound(round int64) bool
- func (s *DefaultSaftyRules) VoteProposal(proposalId []byte, proposalRound int64, parentQc QuorumCertInterface) bool
- type LedgerCommitInfo
- type PacemakerInterface
- type ProposalNode
- type ProposerElectionInterface
- type QCPendingTree
- func (t *QCPendingTree) DFSQueryNode(id []byte) *ProposalNode
- func (t *QCPendingTree) GetCommitQC() *ProposalNode
- func (t *QCPendingTree) GetGenericQC() *ProposalNode
- func (t *QCPendingTree) GetHighQC() *ProposalNode
- func (t *QCPendingTree) GetLockedQC() *ProposalNode
- func (t *QCPendingTree) GetRootQC() *ProposalNode
- type QuorumCert
- type QuorumCertInterface
- type Smr
- func (s *Smr) BlockToProposalNode(block cctx.BlockInterface) *ProposalNode
- func (s *Smr) EnforceUpdateHighQC(inProposalId []byte) error
- func (s *Smr) GetAddress() string
- func (s *Smr) GetCompleteHighQC() QuorumCertInterface
- func (s *Smr) GetCurrentView() int64
- func (s *Smr) GetGenericQC() QuorumCertInterface
- func (s *Smr) GetHighQC() QuorumCertInterface
- func (s *Smr) GetPacemaker() PacemakerInterface
- func (s *Smr) GetSaftyRules() saftyRulesInterface
- func (s *Smr) LoadVotes(proposalId []byte, signs []*chainedBftPb.QuorumCertSign)
- func (s *Smr) ProcessProposal(viewNumber int64, proposalID []byte, validatesIpInfo []string) error
- func (s *Smr) RegisterToNetwork() error
- func (s *Smr) Start()
- func (s *Smr) Stop()
- func (s *Smr) UnRegisterToNetwork()
- func (s *Smr) UpdateJustifyQcStatus(justify *QuorumCert)
- func (s *Smr) UpdateQcStatus(node *ProposalNode) error
- func (s *Smr) VoteMsgToQC(msg *chainedBftPb.VoteMsg) (*QuorumCert, error)
- type VoteInfo
Constants ¶
const (
// DefaultNetMsgChanSize is the default size of network msg channel
DefaultNetMsgChanSize = 1000
)
Variables ¶
var ( NoValidQC = errors.New("Target QC is empty.") NoValidParentId = errors.New("ParentId is empty.") )
var ( EmptyVoteSignErr = errors.New("No signature in vote.") InvalidVoteAddr = errors.New("Vote address is not a validator in the target validators.") InvalidVoteSign = errors.New("Vote sign is invalid compared with its publicKey") TooLowVoteView = errors.New("Vote received is lower than local lastVoteRound.") TooLowVParentView = errors.New("Vote's parent received is lower than local preferredRound.") TooLowProposalView = errors.New("Proposal received is lower than local lastVoteRound.") EmptyParentQC = errors.New("Parent qc is empty.") NoEnoughVotes = errors.New("Parent qc doesn't have enough votes.") EmptyParentNode = errors.New("Parent's node is empty.") EmptyValidators = errors.New("Justify validators are empty.") )
var ( TooLowNewView = errors.New("nextView is lower than local pacemaker's currentView.") P2PInternalErr = errors.New("Internal err in p2p module.") TooLowNewProposal = errors.New("Proposal is lower than local pacemaker's currentView.") EmptyHighQC = errors.New("No valid highQC in qcTree.") SameProposalNotify = errors.New("Same proposal has been made.") JustifyVotesEmpty = errors.New("justify qc's votes are empty.") EmptyTarget = errors.New("Target parameter is empty.") )
var (
RegisterErr = errors.New("Register to p2p error")
)
Functions ¶
This section is empty.
Types ¶
type DefaultPaceMaker ¶
type DefaultPaceMaker struct {
CurrentView int64
}
DefaultPaceMaker 是一个PacemakerInterface的默认实现,我们与PacemakerInterface放置在一起,方便查看 PacemakerInterface的新实现直接直接替代DefaultPaceMaker即可 The Pacemaker keeps track of votes and of time. TODO: the Pacemaker broadcasts a TimeoutMsg notification.
func (*DefaultPaceMaker) AdvanceView ¶
func (p *DefaultPaceMaker) AdvanceView(qc QuorumCertInterface) (bool, error)
func (*DefaultPaceMaker) GetCurrentView ¶
func (p *DefaultPaceMaker) GetCurrentView() int64
type DefaultSaftyRules ¶
type DefaultSaftyRules struct { Crypto *cCrypto.CBFTCrypto QcTree *QCPendingTree Log logs.Logger // contains filtered or unexported fields }
func (*DefaultSaftyRules) CalVotesThreshold ¶
func (s *DefaultSaftyRules) CalVotesThreshold(input, sum int) bool
func (*DefaultSaftyRules) CheckPacemaker ¶
func (s *DefaultSaftyRules) CheckPacemaker(pending int64, local int64) bool
CheckPacemaker 注意: 由于本smr支持不同节点产生同一round, 因此下述round比较和leader比较与原文(验证Proposal的Round是否和pacemaker的Round相等)并不同。 仅需proposal round不超过范围即可
func (*DefaultSaftyRules) CheckProposal ¶
func (s *DefaultSaftyRules) CheckProposal(proposal, parent QuorumCertInterface, justifyValidators []string) error
CheckProposalMsg 原IsQuorumCertValidate 判断justify,即需check的block的parentQC是否合法 需要注意的是,在上层bcs的实现中,由于共识操纵了账本回滚。因此实际上safetyrules需要proposalRound和parentRound严格相邻的 因此在此proposal和parent的QC稍微宽松检查
func (*DefaultSaftyRules) CheckVote ¶
func (s *DefaultSaftyRules) CheckVote(qc QuorumCertInterface, logid string, validators []string) error
CheckVote 检查logid、voteInfoHash是否正确
func (*DefaultSaftyRules) UpdatePreferredRound ¶
func (s *DefaultSaftyRules) UpdatePreferredRound(round int64) bool
func (*DefaultSaftyRules) VoteProposal ¶
func (s *DefaultSaftyRules) VoteProposal(proposalId []byte, proposalRound int64, parentQc QuorumCertInterface) bool
VoteProposal 返回是否需要发送voteMsg给下一个Leader DefaultSaftyRules 并没有严格比对proposalRound和parentRound的相邻自增关系 但需要注意的是,在上层bcs的实现中,由于共识操纵了账本回滚。因此实际上safetyrules需要proposalRound和parentRound严格相邻的 因此由于账本的可回滚性,因此lastVoteRound和preferredRound比对时,仅需比对新来的数据是否小于local数据-3即可 此处-3代表数据已经落盘
type LedgerCommitInfo ¶
ledgerCommitInfo 表示的是本地账本和QC存储的状态,包含一个commitStateId和一个voteInfoHash commitStateId 表示本地账本状态,TODO: = 本地账本merkel root voteInfoHash 表示本地vote的vote_info的哈希,即本地QC的最新状态
type PacemakerInterface ¶
type PacemakerInterface interface { // CurrentView return current view of this node. GetCurrentView() int64 // 原NextNewProposal,generate new proposal directly. AdvanceView(qc QuorumCertInterface) (bool, error) }
PacemakerInterface is the interface of Pacemaker. It responsible for generating a new round. We assume Pacemaker in all correct replicas will have synchronized leadership after GST. Safty is entirely decoupled from liveness by any potential instantiation of Packmaker. Different consensus have different pacemaker implement
type ProposalNode ¶
type ProposalNode struct { In QuorumCertInterface // Parent QuorumCertInterface Sons []*ProposalNode }
func DFSQuery ¶
func DFSQuery(node *ProposalNode, target []byte) *ProposalNode
type QCPendingTree ¶
type QCPendingTree struct { Genesis *ProposalNode // Tree中第一个Node Root *ProposalNode HighQC *ProposalNode // Tree中最高的QC指针 GenericQC *ProposalNode LockedQC *ProposalNode CommitQC *ProposalNode OrphanList *list.List // []*ProposalNode孤儿数组 OrphanMap map[string]bool Log logs.Logger }
PendingTree 是一个内存内的QC状态存储树,仅存放目前未commit(即可能触发账本回滚)的区块信息 当PendingTree中的某个节点有[严格连续的]三代子孙后,将出发针对该节点的账本Commit操作 本数据结构替代原有Chained-BFT的三层QC存储,即proposalQC,generateQC和lockedQC
func (*QCPendingTree) DFSQueryNode ¶
func (t *QCPendingTree) DFSQueryNode(id []byte) *ProposalNode
DFSQueryNode实现的比较简单,从root节点开始寻找,后续有更优方法可优化
func (*QCPendingTree) GetCommitQC ¶
func (t *QCPendingTree) GetCommitQC() *ProposalNode
func (*QCPendingTree) GetGenericQC ¶
func (t *QCPendingTree) GetGenericQC() *ProposalNode
func (*QCPendingTree) GetHighQC ¶
func (t *QCPendingTree) GetHighQC() *ProposalNode
func (*QCPendingTree) GetLockedQC ¶
func (t *QCPendingTree) GetLockedQC() *ProposalNode
func (*QCPendingTree) GetRootQC ¶
func (t *QCPendingTree) GetRootQC() *ProposalNode
type QuorumCert ¶
type QuorumCert struct { // 本次qc的vote对象,该对象中嵌入了上次的QCid,因此删除原有的ProposalMsg部分 VoteInfo *VoteInfo // 当前本地账本的状态 LedgerCommitInfo *LedgerCommitInfo // SignInfos is the signs of the leader gathered from replicas of a specifically certType. SignInfos []*chainedBftPb.QuorumCertSign }
quorumCert 是HotStuff的基础结构,它表示了一个节点本地状态以及其余节点对该状态的确认
func (*QuorumCert) GetParentProposalId ¶
func (qc *QuorumCert) GetParentProposalId() []byte
func (*QuorumCert) GetParentView ¶
func (qc *QuorumCert) GetParentView() int64
func (*QuorumCert) GetProposalId ¶
func (qc *QuorumCert) GetProposalId() []byte
func (*QuorumCert) GetProposalView ¶
func (qc *QuorumCert) GetProposalView() int64
func (*QuorumCert) GetSignsInfo ¶
func (qc *QuorumCert) GetSignsInfo() []*chainedBftPb.QuorumCertSign
type QuorumCertInterface ¶
type QuorumCertInterface interface { GetProposalView() int64 GetProposalId() []byte GetParentProposalId() []byte GetParentView() int64 GetSignsInfo() []*chainedBftPb.QuorumCertSign }
QuorumCertInterface 接口
type Smr ¶
type Smr struct { // quitCh stop channel QuitCh chan bool Election ProposerElectionInterface // contains filtered or unexported fields }
smr 组装了三个模块: pacemaker、saftyrules和propose election smr有自己的存储即PendingTree 原本的ChainedBft(联结smr和本地账本,在preferredVote被确认后, 触发账本commit操作) 被替代成smr和上层bcs账本的·组合实现,以减少不必要的代码,考虑到chained-bft暂无扩展性 注意:本smr的round并不是强自增唯一的,不同节点可能产生相同round(考虑到上层账本的块可回滚)
func NewSmr ¶
func NewSmr(bcName, address string, log logs.Logger, p2p cctx.P2pCtxInConsensus, cryptoClient *cCrypto.CBFTCrypto, pacemaker PacemakerInterface, saftyrules saftyRulesInterface, election ProposerElectionInterface, qcTree *QCPendingTree) *Smr
func (*Smr) BlockToProposalNode ¶
func (s *Smr) BlockToProposalNode(block cctx.BlockInterface) *ProposalNode
func (*Smr) EnforceUpdateHighQC ¶
func (*Smr) GetAddress ¶
func (*Smr) GetCompleteHighQC ¶
func (s *Smr) GetCompleteHighQC() QuorumCertInterface
GetCompleteHighQC 本地qcTree不带签名,因此smr需要重新组装完整的QC
func (*Smr) GetCurrentView ¶
func (*Smr) GetGenericQC ¶
func (s *Smr) GetGenericQC() QuorumCertInterface
func (*Smr) GetHighQC ¶
func (s *Smr) GetHighQC() QuorumCertInterface
func (*Smr) GetPacemaker ¶
func (s *Smr) GetPacemaker() PacemakerInterface
func (*Smr) GetSaftyRules ¶
func (s *Smr) GetSaftyRules() saftyRulesInterface
func (*Smr) LoadVotes ¶
func (s *Smr) LoadVotes(proposalId []byte, signs []*chainedBftPb.QuorumCertSign)
func (*Smr) ProcessProposal ¶
ProcessProposal 即Chained-HotStuff的NewView阶段,LibraBFT的process_proposal阶段 对于一个认为自己当前是Leader的节点,它试图生成一个新的提案,即一个新的QC,并广播 本节点产生一个Proposal,该proposal包含一个最新的round, 最新的proposalId,一个parentQC,并将该消息组合成一个ProposalMsg消息给所有节点 全部完成后leader更新本地localProposal
func (*Smr) RegisterToNetwork ¶
RegisterToNetwork register msg handler to p2p network
func (*Smr) UnRegisterToNetwork ¶
func (s *Smr) UnRegisterToNetwork()
UnRegisterToNetwork unregister msg handler to p2p network
func (*Smr) UpdateJustifyQcStatus ¶
func (s *Smr) UpdateJustifyQcStatus(justify *QuorumCert)
UpdateJustifyQcStatus 用于支持可回滚的账本,生成相同高度的块 为了支持生成相同round的块,需要拿到justify的full votes,因此需要在上层账本收到新块时调用,在CheckMinerMatch后 注意:为了支持回滚操作,必须调用该函数
func (*Smr) UpdateQcStatus ¶
func (s *Smr) UpdateQcStatus(node *ProposalNode) error
UpdateQcStatus 除了更新本地smr的QC之外,还更新了smr的和账本相关的状态,以此区别于smr receive proposal时的updateQcStatus
func (*Smr) VoteMsgToQC ¶
func (s *Smr) VoteMsgToQC(msg *chainedBftPb.VoteMsg) (*QuorumCert, error)
VoteMsgToQC 提供一个从VoteMsg转化为quorumCert的方法,注意,两者struct其实相仿