Refactor basic consensus message checking

pull/359/head
Rongjian Lan 6 years ago
parent 69fa85536c
commit 073efb6776
  1. 41
      consensus/consensus.go
  2. 47
      consensus/consensus_leader.go
  3. 71
      consensus/consensus_validator.go

@ -2,6 +2,7 @@
package consensus // consensus package consensus // consensus
import ( import (
"bytes"
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
@ -195,6 +196,46 @@ func New(host p2p.Host, ShardID string, peers []p2p.Peer, leader p2p.Peer) *Cons
return &consensus return &consensus
} }
// Checks the basic meta of a consensus message.
func (consensus *Consensus) checkConsensusMessage(message consensus_proto.Message, publicKey *bls.PublicKey) bool {
consensusID := message.ConsensusId
blockHash := message.BlockHash
// Verify message signature
err := verifyMessageSig(publicKey, message)
if err != nil {
utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err)
return false
}
// check consensus Id
if consensusID != consensus.consensusID {
utils.GetLogInstance().Warn("Wrong consensus Id", "myConsensusId", consensus.consensusID, "theirConsensusId", consensusID, "consensus", consensus)
return false
}
if !bytes.Equal(blockHash, consensus.blockHash[:]) {
utils.GetLogInstance().Warn("Wrong blockHash", "consensus", consensus)
return false
}
return true
}
// Gets the validator peer based on validator ID.
func (consensus *Consensus) getValidatorPeerByID(validatorID uint32) *p2p.Peer {
v, ok := consensus.validators.Load(validatorID)
if !ok {
utils.GetLogInstance().Warn("Unrecognized validator", "validatorID", validatorID, "consensus", consensus)
return nil
}
value, ok := v.(p2p.Peer)
if !ok {
utils.GetLogInstance().Warn("Invalid validator", "validatorID", validatorID, "consensus", consensus)
return nil
}
return &value
}
// Verify the signature of the message are valid from the signer's public key. // Verify the signature of the message are valid from the signer's public key.
func verifyMessageSig(signerPubKey *bls.PublicKey, message consensus_proto.Message) error { func verifyMessageSig(signerPubKey *bls.PublicKey, message consensus_proto.Message) error {
signature := message.Signature signature := message.Signature

@ -1,7 +1,6 @@
package consensus package consensus
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"strconv" "strconv"
"time" "time"
@ -15,7 +14,6 @@ import (
bls_cosi "github.com/harmony-one/harmony/crypto/bls" bls_cosi "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/profiler" "github.com/harmony-one/harmony/internal/profiler"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/p2p/host" "github.com/harmony-one/harmony/p2p/host"
) )
@ -116,7 +114,7 @@ func (consensus *Consensus) processPrepareMessage(message consensus_proto.Messag
validatorPeer := consensus.getValidatorPeerByID(validatorID) validatorPeer := consensus.getValidatorPeerByID(validatorID)
if !consensus.checkValidatorMessage(message, validatorPeer.PubKey) { if !consensus.checkConsensusMessage(message, validatorPeer.PubKey) {
utils.GetLogInstance().Debug("Failed to check the validator message", "validatorID", validatorID) utils.GetLogInstance().Debug("Failed to check the validator message", "validatorID", validatorID)
return return
} }
@ -172,47 +170,6 @@ func (consensus *Consensus) processPrepareMessage(message consensus_proto.Messag
} }
} }
// Checks the basic meta of a message from validator.
func (consensus *Consensus) checkValidatorMessage(message consensus_proto.Message, publicKey *bls.PublicKey) bool {
consensusID := message.ConsensusId
blockHash := message.BlockHash
validatorID := message.SenderId
// Verify message signature
err := verifyMessageSig(publicKey, message)
if err != nil {
utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err, "validatorID", validatorID)
return false
}
// check consensus Id
if consensusID != consensus.consensusID {
utils.GetLogInstance().Warn("Received Commit with wrong consensus Id", "myConsensusId", consensus.consensusID, "theirConsensusId", consensusID, "consensus", consensus)
return false
}
if !bytes.Equal(blockHash, consensus.blockHash[:]) {
utils.GetLogInstance().Warn("Received Commit with wrong blockHash", "myConsensusId", consensus.consensusID, "theirConsensusId", consensusID, "consensus", consensus)
return false
}
return true
}
// Gets the validator peer based on validator ID.
func (consensus *Consensus) getValidatorPeerByID(validatorID uint32) *p2p.Peer {
v, ok := consensus.validators.Load(validatorID)
if !ok {
utils.GetLogInstance().Warn("Unrecognized validator", "validatorID", validatorID, "consensus", consensus)
return nil
}
value, ok := v.(p2p.Peer)
if !ok {
utils.GetLogInstance().Warn("Invalid validator", "validatorID", validatorID, "consensus", consensus)
return nil
}
return &value
}
// Processes the commit message sent from validators // Processes the commit message sent from validators
func (consensus *Consensus) processCommitMessage(message consensus_proto.Message) { func (consensus *Consensus) processCommitMessage(message consensus_proto.Message) {
validatorID := message.SenderId validatorID := message.SenderId
@ -223,7 +180,7 @@ func (consensus *Consensus) processCommitMessage(message consensus_proto.Message
validatorPeer := consensus.getValidatorPeerByID(validatorID) validatorPeer := consensus.getValidatorPeerByID(validatorID)
if !consensus.checkValidatorMessage(message, validatorPeer.PubKey) { if !consensus.checkConsensusMessage(message, validatorPeer.PubKey) {
utils.GetLogInstance().Debug("Failed to check the validator message", "validatorID", validatorID) utils.GetLogInstance().Debug("Failed to check the validator message", "validatorID", validatorID)
return return
} }

@ -1,8 +1,6 @@
package consensus package consensus
import ( import (
"bytes"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
bls_cosi "github.com/harmony-one/harmony/crypto/bls" bls_cosi "github.com/harmony-one/harmony/crypto/bls"
@ -40,29 +38,18 @@ func (consensus *Consensus) processAnnounceMessage(message consensus_proto.Messa
consensusID := message.ConsensusId consensusID := message.ConsensusId
blockHash := message.BlockHash blockHash := message.BlockHash
leaderID := message.SenderId
block := message.Payload block := message.Payload
copy(consensus.blockHash[:], blockHash[:]) copy(consensus.blockHash[:], blockHash[:])
// Verify block data if !consensus.checkConsensusMessage(message, consensus.leader.PubKey) {
// check leader Id utils.GetLogInstance().Debug("Failed to check the leader message")
myLeaderID := utils.GetUniqueIDFromPeer(consensus.leader)
if leaderID != myLeaderID {
utils.GetLogInstance().Warn("Received message from wrong leader", "myLeaderID", myLeaderID, "receivedLeaderId", leaderID, "consensus", consensus)
return
}
// Verify message signature
err := verifyMessageSig(consensus.leader.PubKey, message)
if err != nil {
utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err, "leader ID", leaderID)
return return
} }
// check block header is valid // check block header is valid
var blockObj types.Block var blockObj types.Block
err = rlp.DecodeBytes(block, &blockObj) err := rlp.DecodeBytes(block, &blockObj)
if err != nil { if err != nil {
utils.GetLogInstance().Warn("Unparseable block header data", "error", err) utils.GetLogInstance().Warn("Unparseable block header data", "error", err)
return return
@ -81,13 +68,6 @@ func (consensus *Consensus) processAnnounceMessage(message consensus_proto.Messa
return return
} }
// check block hash
hash := blockObj.Hash()
if !bytes.Equal(blockHash[:], hash[:]) {
utils.GetLogInstance().Warn("Block hash doesn't match", "consensus", consensus)
return
}
// check block data (transactions // check block data (transactions
if !consensus.BlockVerifier(&blockObj) { if !consensus.BlockVerifier(&blockObj) {
utils.GetLogInstance().Warn("Block content is not verified successfully", "consensus", consensus) utils.GetLogInstance().Warn("Block content is not verified successfully", "consensus", consensus)
@ -125,18 +105,8 @@ func (consensus *Consensus) processPreparedMessage(message consensus_proto.Messa
// Update readyByConsensus for attack. // Update readyByConsensus for attack.
attack.GetInstance().UpdateConsensusReady(consensusID) attack.GetInstance().UpdateConsensusReady(consensusID)
// Verify block data and the aggregated signatures if !consensus.checkConsensusMessage(message, consensus.leader.PubKey) {
// check leader Id utils.GetLogInstance().Debug("Failed to check the leader message")
myLeaderID := utils.GetUniqueIDFromPeer(consensus.leader)
if uint32(leaderID) != myLeaderID {
utils.GetLogInstance().Warn("Received message from wrong leader", "myLeaderID", myLeaderID, "receivedLeaderId", leaderID, "consensus", consensus)
return
}
// Verify message signature
err := verifyMessageSig(consensus.leader.PubKey, message)
if err != nil {
utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err, "leader ID", leaderID)
return return
} }
@ -149,14 +119,8 @@ func (consensus *Consensus) processPreparedMessage(message consensus_proto.Messa
consensus.mutex.Lock() consensus.mutex.Lock()
defer consensus.mutex.Unlock() defer consensus.mutex.Unlock()
// check block hash
if !bytes.Equal(blockHash[:], consensus.blockHash[:]) {
utils.GetLogInstance().Warn("Block hash doesn't match", "consensus", consensus)
return
}
deserializedMultiSig := bls.Sign{} deserializedMultiSig := bls.Sign{}
err = deserializedMultiSig.Deserialize(multiSig) err := deserializedMultiSig.Deserialize(multiSig)
if err != nil { if err != nil {
utils.GetLogInstance().Warn("Failed to deserialize the multi signature for prepare phase", "Error", err, "leader ID", leaderID) utils.GetLogInstance().Warn("Failed to deserialize the multi signature for prepare phase", "Error", err, "leader ID", leaderID)
return return
@ -185,7 +149,6 @@ func (consensus *Consensus) processCommittedMessage(message consensus_proto.Mess
utils.GetLogInstance().Warn("Received Prepared Message", "nodeID", consensus.nodeID) utils.GetLogInstance().Warn("Received Prepared Message", "nodeID", consensus.nodeID)
consensusID := message.ConsensusId consensusID := message.ConsensusId
blockHash := message.BlockHash
leaderID := message.SenderId leaderID := message.SenderId
messagePayload := message.Payload messagePayload := message.Payload
@ -201,18 +164,8 @@ func (consensus *Consensus) processCommittedMessage(message consensus_proto.Mess
// Update readyByConsensus for attack. // Update readyByConsensus for attack.
attack.GetInstance().UpdateConsensusReady(consensusID) attack.GetInstance().UpdateConsensusReady(consensusID)
// Verify block data and the aggregated signatures if !consensus.checkConsensusMessage(message, consensus.leader.PubKey) {
// check leader Id utils.GetLogInstance().Debug("Failed to check the leader message")
myLeaderID := utils.GetUniqueIDFromPeer(consensus.leader)
if uint32(leaderID) != myLeaderID {
utils.GetLogInstance().Warn("Received message from wrong leader", "myLeaderID", myLeaderID, "receivedLeaderId", leaderID, "consensus", consensus)
return
}
// Verify message signature
err := verifyMessageSig(consensus.leader.PubKey, message)
if err != nil {
utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err, "leader ID", leaderID)
return return
} }
@ -232,14 +185,8 @@ func (consensus *Consensus) processCommittedMessage(message consensus_proto.Mess
return return
} }
// check block hash
if !bytes.Equal(blockHash[:], consensus.blockHash[:]) {
utils.GetLogInstance().Warn("Block hash doesn't match", "consensus", consensus)
return
}
deserializedMultiSig := bls.Sign{} deserializedMultiSig := bls.Sign{}
err = deserializedMultiSig.Deserialize(multiSig) err := deserializedMultiSig.Deserialize(multiSig)
if err != nil { if err != nil {
utils.GetLogInstance().Warn("Failed to deserialize the multi signature for commit phase", "Error", err, "leader ID", leaderID) utils.GetLogInstance().Warn("Failed to deserialize the multi signature for commit phase", "Error", err, "leader ID", leaderID)
return return

Loading…
Cancel
Save