Skip to content

Commit

Permalink
add support for "Promiscuous" mode
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiqiangxu committed Mar 2, 2022
1 parent 14cca39 commit eed19d2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 20 deletions.
14 changes: 7 additions & 7 deletions bihs_live.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ func (hs *HotStuff) loop() {
case proposal := <-hs.proposeCh:

if !hs.isLeader(hs.height, hs.view) {
hs.conf.Logger.Errorf("proposer(%s) not in turn, height(%d) view(%d)", hs.conf.ProposerID, hs.height, hs.view)
hs.conf.Logger.Errorf("proposer(%d) tried to propose when not in turn, height(%d) view(%d)", hs.idx, hs.height, hs.view)
continue
}
if hs.view != 0 {
hs.conf.Logger.Errorf("proposal(%s) Propose not in view 0", hs.conf.ProposerID)
if !hs.conf.Promiscuous && hs.view != 0 {
hs.conf.Logger.Errorf("proposer(%d) tried to propose when not in view 0 in bivalent mode", hs.idx)
continue
}
switch {
case proposal.Height() < hs.height:
hs.conf.Logger.Errorf("proposal(%s) Propose height decrease, proposal.height=%d, hs.height=%d", hs.conf.ProposerID, proposal.Height(), hs.height)
hs.conf.Logger.Errorf("proposer(%d) proposal height decrease, proposal.height=%d, hs.height=%d", hs.idx, proposal.Height(), hs.height)
continue
case proposal.Height() == hs.height:
if hs.candidateBlk != nil {
hs.conf.Logger.Errorf("proposal(%s) Propose twice in the same height, last:%v, current:%v", hs.conf.ProposerID, hs.candidateBlk.Hash(), proposal.Hash())
if hs.hasVotedPrepare {
hs.conf.Logger.Errorf("proposer(%d) has voted prepare in the current height(%d) and view(%d), last:%v, current:%v", hs.idx, hs.height, hs.view, hs.candidateBlk.Hash(), proposal.Hash())
continue
}
case proposal.Height() > hs.height:
Expand Down Expand Up @@ -208,7 +208,7 @@ func (hs *HotStuff) relayPropose() {
return
}

blk, err := hs.store.EmptyBlock(hs.height)
blk, err := hs.store.MakeBlock(hs.height, !hs.conf.Promiscuous && hs.view > 0)
if err != nil {
hs.conf.Logger.Errorf("proposer %d EmptyBlock failed:%v", hs.idx, err)
return
Expand Down
27 changes: 17 additions & 10 deletions bihs_safe.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func (hs *HotStuff) onProposal(blk Block, qc *QC) {
hs.p2p.Broadcast(prepareMsg)

hs.onRecvPrepareVote(hs.conf.ProposerID, hs.idx, prepareMsg)

if hs.relayTimer != nil {
hs.relayTimer.Stop()
hs.relayTimer = nil
}
}

func (hs *HotStuff) onRecvPrepare(sender ID, idx int, msg *Msg) {
Expand All @@ -74,6 +79,11 @@ func (hs *HotStuff) onRecvPrepare(sender ID, idx int, msg *Msg) {
return
}

if !bytes.Equal(hs.store.SelectLeader(msg.Node.Blk.Height(), hs.view), sender) {
hs.conf.Logger.Errorf("proposer %s tried to propose when not in turn", sender)
return
}

if msg.Node.Blk.Height() != msg.Height {
hs.conf.Logger.Errorf("prepare block height(%d) != msg height(%d)", msg.Node.Blk.Height(), msg.Height)
return
Expand All @@ -83,17 +93,14 @@ func (hs *HotStuff) onRecvPrepare(sender ID, idx int, msg *Msg) {
return
}

switch {
case msg.View == 0:
if !msg.Node.Blk.Empty() && !bytes.Equal(hs.store.SelectLeader(msg.Node.Blk.Height(), 0), sender) {
hs.conf.Logger.Errorf("proposer %s tried to propose when not in turn", sender)
return
}
case msg.View > 0:
if !msg.Node.Blk.Empty() && msg.Justify == nil {
hs.conf.Logger.Errorf("proposer %s tried to relay propose with no qc", sender)
return
if msg.View > 0 {
if !hs.conf.Promiscuous {
if !msg.Node.Blk.Empty() && msg.Justify == nil {
hs.conf.Logger.Errorf("proposer %s tried to relay propose with no qc when in bivalent mode", sender)
return
}
}

if msg.Justify != nil {
err := msg.Justify.validate(hs)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion bihs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (db *HappyDB) ValidatorIndex(height uint64, peer ID) int {
func (db *HappyDB) SelectLeader(height, view uint64) ID {
return ID([]byte(fmt.Sprintf("%d", (height+view)%uint64(db.validators))))
}
func (db *HappyDB) EmptyBlock(height uint64) (Block, error) {
func (db *HappyDB) MakeBlock(height uint64, mustEmpty bool) (Block, error) {
b := EmptyBlock(height)
return &b, nil
}
Expand Down
4 changes: 2 additions & 2 deletions type.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,9 @@ type StateDB interface {
Height() uint64
SubscribeHeightChange(HeightChangeSub)
UnSubscribeHeightChange(HeightChangeSub)

MakeBlock(height uint64, mustEmpty bool) (Block, error)
ValidatorIndex(height uint64, peer ID) int
SelectLeader(height, view uint64) ID
EmptyBlock(height uint64) (Block, error)
ValidatorCount(height uint64) int32
ValidatorIDs(height uint64) []ID

Expand Down Expand Up @@ -361,6 +360,7 @@ type Config struct {
BlockInterval time.Duration
ProposerID ID
DataDir string
Promiscuous bool

EcSigner EcSigner
BlsSigner BlsSigner
Expand Down

0 comments on commit eed19d2

Please sign in to comment.