[viewchange] fix InitPayload func

Signed-off-by: Leo Chen <leo@harmony.one>
pull/3379/head
Leo Chen 4 years ago
parent 5ba139fded
commit 7620fce074
  1. 10
      consensus/view_change.go
  2. 104
      consensus/view_change_construct.go

@ -138,6 +138,15 @@ func (consensus *Consensus) startViewChange(viewID uint64) {
consensus.consensusTimeout[timeoutViewChange].SetDuration(duration) consensus.consensusTimeout[timeoutViewChange].SetDuration(duration)
defer consensus.consensusTimeout[timeoutViewChange].Start() defer consensus.consensusTimeout[timeoutViewChange].Start()
// init my own payload
if err := consensus.vc.InitPayload(
consensus.FBFTLog,
viewID,
consensus.blockNum,
consensus.priKey); err != nil {
consensus.getLogger().Error().Err(err).Msg("Init Payload Error")
}
// for view change, send separate view change per public key // for view change, send separate view change per public key
// do not do multi-sign of view change message // do not do multi-sign of view change message
for _, key := range consensus.priKey { for _, key := range consensus.priKey {
@ -196,7 +205,6 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
if err := consensus.vc.InitPayload(consensus.FBFTLog, if err := consensus.vc.InitPayload(consensus.FBFTLog,
recvMsg.ViewID, recvMsg.ViewID,
recvMsg.BlockNum, recvMsg.BlockNum,
newLeaderKey.Bytes.Hex(),
consensus.priKey); err != nil { consensus.priKey); err != nil {
consensus.getLogger().Error().Err(err).Msg("Init Payload Error") consensus.getLogger().Error().Err(err).Msg("Init Payload Error")
return return

@ -51,7 +51,6 @@ type viewChange struct {
bhpBitmap map[uint64]*bls_cosi.Mask bhpBitmap map[uint64]*bls_cosi.Mask
nilBitmap map[uint64]*bls_cosi.Mask nilBitmap map[uint64]*bls_cosi.Mask
viewIDBitmap map[uint64]*bls_cosi.Mask viewIDBitmap map[uint64]*bls_cosi.Mask
viewIDCount map[uint64]map[string]int
newViewMsg map[uint64]map[string]uint64 newViewMsg map[uint64]map[string]uint64
m1Payload []byte // message payload for type m1 := |vcBlockHash|prepared_agg_sigs|prepared_bitmap|, new leader only need one m1Payload []byte // message payload for type m1 := |vcBlockHash|prepared_agg_sigs|prepared_bitmap|, new leader only need one
@ -318,74 +317,91 @@ func (vc *viewChange) VerifyViewChangeMsg(recvMsg *FBFTMessage, members multibls
} }
// InitPayload do it once when validator received view change message // InitPayload do it once when validator received view change message
// TODO: if I start the view change message, I should init my payload already
func (vc *viewChange) InitPayload( func (vc *viewChange) InitPayload(
fbftlog *FBFTLog, fbftlog *FBFTLog,
viewID uint64, viewID uint64,
blockNum uint64, blockNum uint64,
myPubKey string,
privKeys multibls.PrivateKeys, privKeys multibls.PrivateKeys,
) error { ) error {
vc.vcLock.Lock() vc.vcLock.Lock()
defer vc.vcLock.Unlock() defer vc.vcLock.Unlock()
// add my own M2 type message signature and bitmap // m1 or m2 init once per viewID/key.
_, ok := vc.nilSigs[viewID][myPubKey] // m1 and m2 are mutually exclusive.
// If the node has valid prepared block, it will add m1 signature.
// If not, the node will add m2 signature.
// Honest node should have only one kind of m1/m2 signature.
inited := false
for _, key := range privKeys {
_, ok1 := vc.bhpSigs[viewID][key.Pub.Bytes.Hex()]
_, ok2 := vc.nilSigs[viewID][key.Pub.Bytes.Hex()]
if ok1 || ok2 {
inited = true
break
}
}
if !ok { // add my own M1/M2 type message signature and bitmap
vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M2 (NIL) type messaage") if !inited {
for i, key := range privKeys { preparedMsgs := fbftlog.GetMessagesByTypeSeq(msg_pb.MessageType_PREPARED, blockNum)
if err := vc.nilBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil { preparedMsg := fbftlog.FindMessageByMaxViewID(preparedMsgs)
vc.getLogger().Warn().Int("index", i).Msg("[InitPayload] nilBitmap setkey failed") hasBlock := false
continue if preparedMsg != nil {
if preparedBlock := fbftlog.GetBlockByHash(preparedMsg.BlockHash); preparedBlock != nil {
if err := vc.blockVerifier(preparedBlock); err == nil {
vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M1 (prepared) type messaage")
msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
for _, key := range privKeys {
if err := vc.bhpBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil {
vc.getLogger().Warn().Str("key", key.Pub.Bytes.Hex()).Msg("[InitPayload] bhpBitmap setkey failed")
continue
}
vc.bhpSigs[viewID][key.Pub.Bytes.Hex()] = key.Pri.SignHash(msgToSign)
}
hasBlock = true
// if m1Payload is empty, we just add one
if vc.isM1PayloadEmpty() {
vc.m1Payload = append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
}
}
}
}
if !hasBlock {
vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M2 (NIL) type messaage")
for _, key := range privKeys {
if err := vc.nilBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil {
vc.getLogger().Warn().Str("key", key.Pub.Bytes.Hex()).Msg("[InitPayload] nilBitmap setkey failed")
continue
}
vc.nilSigs[viewID][key.Pub.Bytes.Hex()] = key.Pri.SignHash(NIL)
} }
vc.nilSigs[viewID][key.Pub.Bytes.Hex()] = key.Pri.SignHash(NIL)
} }
} }
// add my own M3 type message signature and bitmap inited = false
_, ok = vc.viewIDSigs[viewID][myPubKey] for _, key := range privKeys {
_, ok3 := vc.viewIDSigs[viewID][key.Pub.Bytes.Hex()]
if ok3 {
inited = true
break
}
}
if !ok { // add my own M3 type message signature and bitmap
if !inited {
viewIDBytes := make([]byte, 8) viewIDBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(viewIDBytes, viewID) binary.LittleEndian.PutUint64(viewIDBytes, viewID)
vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M3 (ViewID) type messaage") vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M3 (ViewID) type messaage")
for i, key := range privKeys { for _, key := range privKeys {
if err := vc.viewIDBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil { if err := vc.viewIDBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil {
vc.getLogger().Warn().Int("index", i).Msg("[InitPayload] viewIDBitmap setkey failed") vc.getLogger().Warn().Str("key", key.Pub.Bytes.Hex()).Msg("[InitPayload] viewIDBitmap setkey failed")
continue continue
} }
vc.viewIDSigs[viewID][key.Pub.Bytes.Hex()] = key.Pri.SignHash(viewIDBytes) vc.viewIDSigs[viewID][key.Pub.Bytes.Hex()] = key.Pri.SignHash(viewIDBytes)
} }
} }
// add my own M1 type message signature and bitmap
_, ok = vc.bhpSigs[viewID][myPubKey]
if !ok {
preparedMsgs := fbftlog.GetMessagesByTypeSeq(msg_pb.MessageType_PREPARED, blockNum)
preparedMsg := fbftlog.FindMessageByMaxViewID(preparedMsgs)
if preparedMsg != nil {
if preparedBlock := fbftlog.GetBlockByHash(preparedMsg.BlockHash); preparedBlock != nil {
if err := vc.blockVerifier(preparedBlock); err != nil {
return err
}
vc.getLogger().Info().Uint64("viewID", viewID).Uint64("blockNum", blockNum).Msg("[InitPayload] add my M1 (prepared) type messaage")
msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
for i, key := range privKeys {
if err := vc.bhpBitmap[viewID].SetKey(key.Pub.Bytes, true); err != nil {
vc.getLogger().Warn().Int("index", i).Msg("[InitPayload] bhpBitmap setkey failed")
continue
}
vc.bhpSigs[viewID][key.Pub.Bytes.Hex()] = key.Pri.SignHash(msgToSign)
}
// if m1Payload is empty, we just add one
if vc.isM1PayloadEmpty() {
vc.m1Payload = append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
}
}
}
}
return nil return nil
} }

Loading…
Cancel
Save