Add cache to validator membership check

pull/3186/head
Rongjian Lan 4 years ago
parent ef5ca8aa4c
commit b403baa35c
  1. 21
      consensus/checks.go
  2. 24
      consensus/consensus_service.go
  3. 1
      consensus/consensus_v2.go
  4. 31
      consensus/quorum/quorum.go

@ -3,6 +3,7 @@ package consensus
import (
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/chain"
"github.com/harmony-one/harmony/shard"
)
@ -20,17 +21,21 @@ func (consensus *Consensus) validatorSanityChecks(msg *msg_pb.Message) bool {
Uint64("viewID", msg.GetConsensus().ViewId).
Str("msgType", msg.Type.String()).
Msg("[validatorSanityChecks] Checking new message")
senderKey, err := consensus.verifySenderKey(msg)
err := consensus.verifySenderKey(msg)
if err != nil {
if err == shard.ErrValidNotInCommittee {
consensus.getLogger().Info().
Hex("senderKey", msg.GetConsensus().SenderPubkey).
Msg("sender key not in this slot's subcommittee")
} else {
consensus.getLogger().Error().Err(err).Msg("VerifySenderKey failed")
}
return false
}
senderKey, err := bls.BytesToBLSPublicKey(msg.GetConsensus().SenderPubkey)
if err != nil {
return false
}
if !senderKey.IsEqual(consensus.LeaderPubKey) &&
consensus.current.Mode() == Normal && !consensus.ignoreViewIDCheck {
consensus.getLogger().Warn().Msgf(
@ -60,10 +65,11 @@ func (consensus *Consensus) leaderSanityChecks(msg *msg_pb.Message) bool {
Uint64("viewID", msg.GetConsensus().ViewId).
Str("msgType", msg.Type.String()).
Msg("[leaderSanityChecks] Checking new message")
senderKey, err := consensus.verifySenderKey(msg)
err := consensus.verifySenderKey(msg)
if err != nil {
if err == shard.ErrValidNotInCommittee {
consensus.getLogger().Info().Msgf(
consensus.getLogger().Info().
Hex("senderKey", msg.GetConsensus().SenderPubkey).Msgf(
"[%s] sender key not in this slot's subcommittee",
msg.GetType().String(),
)
@ -75,6 +81,10 @@ func (consensus *Consensus) leaderSanityChecks(msg *msg_pb.Message) bool {
}
return false
}
senderKey, err := bls.BytesToBLSPublicKey(msg.GetConsensus().SenderPubkey)
if err != nil {
return false
}
if err = verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Error().Err(err).Msgf(
"[%s] Failed to verify sender's signature",
@ -197,7 +207,8 @@ func (consensus *Consensus) viewChangeSanityCheck(msg *msg_pb.Message) bool {
senderKey, err := consensus.verifyViewChangeSenderKey(msg)
if err != nil {
if err == shard.ErrValidNotInCommittee {
consensus.getLogger().Info().Msgf(
consensus.getLogger().Info().
Hex("senderKey", msg.GetConsensus().SenderPubkey).Msgf(
"[%s] sender key not in this slot's subcommittee",
msg.GetType().String(),
)

@ -167,6 +167,15 @@ func (consensus *Consensus) ToggleConsensusCheck() {
// IsValidatorInCommittee returns whether the given validator BLS address is part of my committee
func (consensus *Consensus) IsValidatorInCommittee(pubKey *bls.PublicKey) bool {
pubKeyBytes := shard.FromLibBLSPublicKeyUnsafe(pubKey)
if pubKeyBytes == nil {
return false
}
return consensus.Decider.IndexOf(*pubKeyBytes) != -1
}
// IsValidatorInCommitteeBytes returns whether the given validator BLS address is part of my committee
func (consensus *Consensus) IsValidatorInCommitteeBytes(pubKey shard.BLSPublicKey) bool {
return consensus.Decider.IndexOf(pubKey) != -1
}
@ -193,17 +202,14 @@ func verifyMessageSig(signerPubKey *bls.PublicKey, message *msg_pb.Message) erro
}
// verifySenderKey verifys the message senderKey is properly signed and senderAddr is valid
func (consensus *Consensus) verifySenderKey(msg *msg_pb.Message) (*bls.PublicKey, error) {
consensusMsg := msg.GetConsensus()
senderKey, err := bls_cosi.BytesToBLSPublicKey(consensusMsg.SenderPubkey)
if err != nil {
return nil, err
}
func (consensus *Consensus) verifySenderKey(msg *msg_pb.Message) error {
senderKey := shard.BLSPublicKey{}
if !consensus.IsValidatorInCommittee(senderKey) {
return nil, shard.ErrValidNotInCommittee
copy(senderKey[:], msg.GetConsensus().SenderPubkey[:])
if !consensus.IsValidatorInCommitteeBytes(senderKey) {
return shard.ErrValidNotInCommittee
}
return senderKey, nil
return nil
}
func (consensus *Consensus) verifyViewChangeSenderKey(msg *msg_pb.Message) (*bls.PublicKey, error) {

@ -175,7 +175,6 @@ func (consensus *Consensus) finalizeCommits() {
Uint64("epochNum", block.Epoch().Uint64()).
Uint64("ViewId", block.Header().ViewID().Uint64()).
Str("blockHash", block.Hash().String()).
Int("index", consensus.Decider.IndexOf(consensus.LeaderPubKey)).
Int("numTxns", len(block.Transactions())).
Int("numStakingTxns", len(block.StakingTransactions())).
Msg("HOORAY!!!!!!! CONSENSUS REACHED!!!!!!!")

@ -3,6 +3,7 @@ package quorum
import (
"fmt"
"math/big"
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls"
@ -69,7 +70,7 @@ func (p Policy) String() string {
type ParticipantTracker interface {
Participants() []*bls.PublicKey
ParticipantsKeyBytes() []shard.BLSPublicKey
IndexOf(*bls.PublicKey) int
IndexOf(shard.BLSPublicKey) int
ParticipantsCount() int64
NextAfter(*bls.PublicKey) (bool, *bls.PublicKey)
UpdateParticipants(pubKeys []*bls.PublicKey)
@ -148,6 +149,7 @@ type cIdentities struct {
// Public keys of the committee including leader and validators
publicKeys []*bls.PublicKey
publicKeysByte []shard.BLSPublicKey
keyIndexMap sync.Map
prepare *votepower.Round
commit *votepower.Round
// viewIDSigs: every validator
@ -174,20 +176,19 @@ func (s *cIdentities) AggregateVotes(p Phase) *bls.Sign {
return bls_cosi.AggregateSig(sigs)
}
func (s *cIdentities) IndexOf(pubKey *bls.PublicKey) int {
idx := -1
for k, v := range s.publicKeys {
if v.IsEqual(pubKey) {
idx = k
break
func (s *cIdentities) IndexOf(pubKey shard.BLSPublicKey) int {
if index, ok := s.keyIndexMap.Load(pubKey); ok {
return index.(int)
}
}
return idx
return -1
}
func (s *cIdentities) NextAfter(pubKey *bls.PublicKey) (bool, *bls.PublicKey) {
found := false
idx := s.IndexOf(pubKey)
pubKeyByte := shard.BLSPublicKey{}
pubKeyByte.FromLibBLSPublicKey(pubKey)
idx := s.IndexOf(pubKeyByte)
if idx != -1 {
found = true
}
@ -205,14 +206,23 @@ func (s *cIdentities) ParticipantsKeyBytes() []shard.BLSPublicKey {
func (s *cIdentities) UpdateParticipants(pubKeys []*bls.PublicKey) {
keyBytes := []shard.BLSPublicKey{}
keyIndexMap := map[shard.BLSPublicKey]int{}
for i := range pubKeys {
k := shard.BLSPublicKey{}
k.FromLibBLSPublicKey(pubKeys[i])
keyBytes = append(keyBytes, k)
keyIndexMap[k] = i
}
s.publicKeys = append(pubKeys[:0:0], pubKeys...)
for _, pubKey := range s.publicKeysByte {
s.keyIndexMap.Delete(pubKey)
}
s.publicKeysByte = keyBytes
for i, pubKey := range s.publicKeysByte {
s.keyIndexMap.Store(pubKey, i)
}
}
func (s *cIdentities) ParticipantsCount() int64 {
@ -319,6 +329,7 @@ func newBallotsBackedSignatureReader() *cIdentities {
return &cIdentities{
publicKeys: []*bls.PublicKey{},
publicKeysByte: []shard.BLSPublicKey{},
keyIndexMap: sync.Map{},
prepare: votepower.NewRound(),
commit: votepower.NewRound(),
viewChange: votepower.NewRound(),

Loading…
Cancel
Save