[viewchange] rename VerifyViewChange to ProcessViewChange

Signed-off-by: Leo Chen <leo@harmony.one>
pull/3379/head
Leo Chen 4 years ago
parent 0871866848
commit 75fb354ee7
  1. 27
      consensus/view_change.go
  2. 68
      consensus/view_change_construct.go

@ -210,7 +210,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
return return
} }
msgType, preparedBlock, err := consensus.vc.VerifyViewChangeMsg(recvMsg, members) err = consensus.vc.ProcessViewChangeMsg(consensus.FBFTLog, recvMsg, members)
if err != nil { if err != nil {
consensus.getLogger().Error().Err(err). consensus.getLogger().Error().Err(err).
Uint64("viewID", recvMsg.ViewID). Uint64("viewID", recvMsg.ViewID).
@ -220,31 +220,6 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
return return
} }
if msgType == M1 {
preparedMsgs := consensus.FBFTLog.GetMessagesByTypeSeq(
msg_pb.MessageType_PREPARED, recvMsg.BlockNum,
)
// search for local prepared msg and add one if not found
preparedMsg := consensus.FBFTLog.FindMessageByViewID(preparedMsgs, recvMsg.ViewID)
if preparedMsg == nil {
// create prepared message for new leader
preparedMsg := FBFTMessage{
MessageType: msg_pb.MessageType_PREPARED,
ViewID: recvMsg.ViewID,
BlockNum: recvMsg.BlockNum,
}
preparedMsg.BlockHash = common.Hash{}
copy(preparedMsg.BlockHash[:], recvMsg.Payload[:32])
preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32)
copy(preparedMsg.Payload[:], recvMsg.Payload[32:])
preparedMsg.SenderPubkey = newLeaderKey
consensus.getLogger().Info().Msg("[onViewChange] New Leader Prepared Message Added")
consensus.FBFTLog.AddMessage(&preparedMsg)
consensus.FBFTLog.AddBlock(preparedBlock)
}
}
// received enough view change messages, change state to normal consensus // received enough view change messages, change state to normal consensus
if consensus.Decider.IsQuorumAchievedByMask(consensus.vc.GetViewIDBitmap(recvMsg.ViewID)) { if consensus.Decider.IsQuorumAchievedByMask(consensus.vc.GetViewIDBitmap(recvMsg.ViewID)) {
consensus.getLogger().Info().Msg("[onViewChange] View Change Message Quorum Reached") consensus.getLogger().Info().Msg("[onViewChange] View Change Message Quorum Reached")

@ -6,6 +6,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
@ -20,17 +21,7 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
) )
// ViewChangeMsgType defines the type of view change message
type ViewChangeMsgType byte
const ( const (
// M1 is the view change message with block
M1 ViewChangeMsgType = iota
// M2 is the view change message w/o block
M2
// ERR is the error condition when parsing the message type
ERR
// ValidPayloadLength is the valid length for viewchange payload // ValidPayloadLength is the valid length for viewchange payload
ValidPayloadLength = 32 + bls.BLSSignatureSizeInBytes ValidPayloadLength = 32 + bls.BLSSignatureSizeInBytes
) )
@ -237,8 +228,21 @@ func (vc *viewChange) VerifyNewViewMsg(recvMsg *FBFTMessage) (*types.Block, erro
return nil, nil return nil, nil
} }
// VerifyViewChangeMsg returns the type of the view change message after verification var (
func (vc *viewChange) VerifyViewChangeMsg(recvMsg *FBFTMessage, members multibls.PublicKeys) (ViewChangeMsgType, *types.Block, error) { errDupM1 = errors.New("received M1 (prepared) message already")
errDupM2 = errors.New("received M2 (NIL) message already")
errDupM3 = errors.New("received M3 (ViewID) message already")
errVerifyM1 = errors.New("failed to verfiy signature for M1 message")
errVerifyM2 = errors.New("failed to verfiy signature for M2 message")
errM1Payload = errors.New("failed to verify multi signature for M1 prepared payload")
)
// ProcessViewChangeMsg process the view change message after verification
func (vc *viewChange) ProcessViewChangeMsg(
fbftlog *FBFTLog,
recvMsg *FBFTMessage,
members multibls.PublicKeys,
) error {
vc.vcLock.Lock() vc.vcLock.Lock()
defer vc.vcLock.Unlock() defer vc.vcLock.Unlock()
@ -248,31 +252,31 @@ func (vc *viewChange) VerifyViewChangeMsg(recvMsg *FBFTMessage, members multibls
// check and add viewID (m3 type) message signature // check and add viewID (m3 type) message signature
if _, ok := vc.viewIDSigs[recvMsg.ViewID][senderKeyStr]; ok { if _, ok := vc.viewIDSigs[recvMsg.ViewID][senderKeyStr]; ok {
return ERR, nil, errors.New("[VerifyViewChangeMsg] received M3 (ViewID) message already") return errDupM3
} }
if len(recvMsg.Payload) >= ValidPayloadLength && len(recvMsg.Block) != 0 { if len(recvMsg.Payload) >= ValidPayloadLength && len(recvMsg.Block) != 0 {
if err := rlp.DecodeBytes(recvMsg.Block, preparedBlock); err != nil { if err := rlp.DecodeBytes(recvMsg.Block, preparedBlock); err != nil {
return ERR, nil, err return err
} }
if err := vc.blockVerifier(preparedBlock); err != nil { if err := vc.blockVerifier(preparedBlock); err != nil {
return ERR, nil, err return err
} }
_, ok := vc.bhpSigs[recvMsg.ViewID][senderKeyStr] _, ok := vc.bhpSigs[recvMsg.ViewID][senderKeyStr]
if ok { if ok {
return M1, nil, errors.New("[VerifyViewChangeMsg] received M1 (prepared) message already") return errDupM1
} }
if !recvMsg.ViewchangeSig.VerifyHash(senderKey.Object, recvMsg.Payload) { if !recvMsg.ViewchangeSig.VerifyHash(senderKey.Object, recvMsg.Payload) {
return ERR, nil, errors.New("[VerifyViewChangeMsg] failed to verify signature for m1 type message") return errVerifyM1
} }
blockHash := recvMsg.Payload[:32] blockHash := recvMsg.Payload[:32]
aggSig, mask, err := chain.ReadSignatureBitmapByPublicKeys(recvMsg.Payload[32:], members) aggSig, mask, err := chain.ReadSignatureBitmapByPublicKeys(recvMsg.Payload[32:], members)
if err != nil { if err != nil {
return ERR, nil, err return err
} }
if !aggSig.VerifyHash(mask.AggregatePublic, blockHash[:]) { if !aggSig.VerifyHash(mask.AggregatePublic, blockHash[:]) {
return ERR, nil, errors.New("[VerifyViewChangeMsg] failed to verify multi signature for m1 prepared payload") return errM1Payload
} }
vc.getLogger().Info().Uint64("viewID", recvMsg.ViewID). vc.getLogger().Info().Uint64("viewID", recvMsg.ViewID).
@ -289,14 +293,32 @@ func (vc *viewChange) VerifyViewChangeMsg(recvMsg *FBFTMessage, members multibls
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
vc.viewIDBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true) vc.viewIDBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true)
return M1, preparedBlock, nil if vc.isM1PayloadEmpty() {
vc.m1Payload = append(recvMsg.Payload[:0:0], recvMsg.Payload...)
// create prepared message for new leader
preparedMsg := FBFTMessage{
MessageType: msg_pb.MessageType_PREPARED,
ViewID: recvMsg.ViewID,
BlockNum: recvMsg.BlockNum,
}
preparedMsg.BlockHash = common.Hash{}
copy(preparedMsg.BlockHash[:], recvMsg.Payload[:32])
preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32)
copy(preparedMsg.Payload[:], recvMsg.Payload[32:])
preparedMsg.SenderPubkey = recvMsg.LeaderPubkey
vc.getLogger().Info().Msg("[onViewChange] New Leader Prepared Message Added")
fbftlog.AddMessage(&preparedMsg)
fbftlog.AddBlock(preparedBlock)
}
return nil
} }
_, ok := vc.nilSigs[recvMsg.ViewID][senderKeyStr] _, ok := vc.nilSigs[recvMsg.ViewID][senderKeyStr]
if ok { if ok {
return M2, nil, errors.New("[VerifyViewChangeMsg] received M2 (NIL) message already") return errDupM2
} }
if !recvMsg.ViewchangeSig.VerifyHash(senderKey.Object, NIL) { if !recvMsg.ViewchangeSig.VerifyHash(senderKey.Object, NIL) {
return ERR, nil, errors.New("[VerifyViewChangeMsg] failed to verify signature for m2 type message") return errVerifyM2
} }
vc.getLogger().Info().Uint64("viewID", recvMsg.ViewID). vc.getLogger().Info().Uint64("viewID", recvMsg.ViewID).
@ -313,7 +335,7 @@ func (vc *viewChange) VerifyViewChangeMsg(recvMsg *FBFTMessage, members multibls
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
vc.viewIDBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true) vc.viewIDBitmap[recvMsg.ViewID].SetKey(senderKey.Bytes, true)
return M2, nil, nil return nil
} }
// InitPayload do it once when validator received view change message // InitPayload do it once when validator received view change message

Loading…
Cancel
Save