Refactor bls public key into a wrapper (#3203)

* Refactor bls public key into a wrapper

* Fix build

* Fix
pull/3206/head
Rongjian Lan 4 years ago committed by GitHub
parent 0d3101bcd3
commit 67d77c3965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      cmd/harmony/main.go
  2. 22
      consensus/checks.go
  3. 11
      consensus/consensus.go
  4. 73
      consensus/consensus_service.go
  5. 4
      consensus/consensus_service_test.go
  6. 7
      consensus/consensus_v2.go
  7. 8
      consensus/consensus_viewchange_msg.go
  8. 8
      consensus/construct.go
  9. 8
      consensus/construct_test.go
  10. 26
      consensus/double_sign.go
  11. 35
      consensus/fbft_log.go
  12. 34
      consensus/leader.go
  13. 6
      consensus/quorum/one-node-one-vote.go
  14. 9
      consensus/quorum/one-node-staked-vote.go
  15. 48
      consensus/quorum/quorum.go
  16. 8
      consensus/threshold.go
  17. 12
      consensus/validator.go
  18. 100
      consensus/view_change.go
  19. 4
      hmy/api_backend.go
  20. 4
      internal/chain/engine.go
  21. 10
      internal/configs/node/config.go
  22. 18
      internal/configs/node/config_test.go
  23. 48
      multibls/multibls.go
  24. 6
      node/node.go
  25. 2
      node/node_cross_link.go
  26. 15
      node/node_handler.go
  27. 4
      node/node_newblock.go
  28. 10
      shard/shard_state.go

@ -185,9 +185,9 @@ func passphraseForBLS() {
blsPassphrase = passphrase blsPassphrase = passphrase
} }
func findAccountsByPubKeys(config shardingconfig.Instance, pubKeys []*bls.PublicKey) { func findAccountsByPubKeys(config shardingconfig.Instance, pubKeys multibls.PublicKeys) {
for _, key := range pubKeys { for _, key := range pubKeys {
keyStr := key.SerializeToHexStr() keyStr := key.Bytes.Hex()
_, account := config.FindAccount(keyStr) _, account := config.FindAccount(keyStr)
if account != nil { if account != nil {
initialAccounts = append(initialAccounts, account) initialAccounts = append(initialAccounts, account)
@ -202,13 +202,13 @@ func setupLegacyNodeAccount() error {
if len(reshardingEpoch) > 0 { if len(reshardingEpoch) > 0 {
for _, epoch := range reshardingEpoch { for _, epoch := range reshardingEpoch {
config := shard.Schedule.InstanceForEpoch(epoch) config := shard.Schedule.InstanceForEpoch(epoch)
findAccountsByPubKeys(config, multiBLSPubKey.PublicKey) findAccountsByPubKeys(config, multiBLSPubKey)
if len(initialAccounts) != 0 { if len(initialAccounts) != 0 {
break break
} }
} }
} else { } else {
findAccountsByPubKeys(genesisShardingConfig, multiBLSPubKey.PublicKey) findAccountsByPubKeys(genesisShardingConfig, multiBLSPubKey)
} }
if len(initialAccounts) == 0 { if len(initialAccounts) == 0 {
@ -233,21 +233,21 @@ func setupStakingNodeAccount() error {
return errors.Wrap(err, "cannot determine shard to join") return errors.Wrap(err, "cannot determine shard to join")
} }
if err := nodeconfig.GetDefaultConfig().ValidateConsensusKeysForSameShard( if err := nodeconfig.GetDefaultConfig().ValidateConsensusKeysForSameShard(
pubKey.PublicKey, shardID, pubKey, shardID,
); err != nil { ); err != nil {
return err return err
} }
for _, blsKey := range pubKey.PublicKey { for _, blsKey := range pubKey {
initialAccount := &genesis.DeployAccount{} initialAccount := &genesis.DeployAccount{}
initialAccount.ShardID = shardID initialAccount.ShardID = shardID
initialAccount.BLSPublicKey = blsKey.SerializeToHexStr() initialAccount.BLSPublicKey = blsKey.Bytes.Hex()
initialAccount.Address = "" initialAccount.Address = ""
initialAccounts = append(initialAccounts, initialAccount) initialAccounts = append(initialAccounts, initialAccount)
} }
return nil return nil
} }
func readMultiBLSKeys(consensusMultiBLSPriKey *multibls.PrivateKey, consensusMultiBLSPubKey *multibls.PublicKey) error { func readMultiBLSKeys(consensusMultiBLSPriKey *multibls.PrivateKey, consensusMultiBLSPubKey multibls.PublicKeys) error {
keyPasses := map[string]string{} keyPasses := map[string]string{}
blsKeyFiles := []os.FileInfo{} blsKeyFiles := []os.FileInfo{}
awsEncryptedBLSKeyFiles := []os.FileInfo{} awsEncryptedBLSKeyFiles := []os.FileInfo{}
@ -325,15 +325,15 @@ func readMultiBLSKeys(consensusMultiBLSPriKey *multibls.PrivateKey, consensusMul
} }
// TODO: assumes order between public/private key pairs // TODO: assumes order between public/private key pairs
multibls.AppendPriKey(consensusMultiBLSPriKey, consensusPriKey) multibls.AppendPriKey(consensusMultiBLSPriKey, consensusPriKey)
multibls.AppendPubKey(consensusMultiBLSPubKey, consensusPriKey.GetPublicKey()) consensusMultiBLSPubKey = append(consensusMultiBLSPubKey, multibls.GetPublicKey(consensusPriKey.GetPublicKey())...)
} }
return nil return nil
} }
func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) multibls.PublicKey { func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) multibls.PublicKeys {
consensusMultiPriKey := &multibls.PrivateKey{} consensusMultiPriKey := &multibls.PrivateKey{}
consensusMultiPubKey := &multibls.PublicKey{} consensusMultiPubKey := multibls.PublicKeys{}
if *blsKeyFile != "" { if *blsKeyFile != "" {
consensusPriKey, err := blsgen.LoadBLSKeyWithPassPhrase(*blsKeyFile, blsPassphrase) consensusPriKey, err := blsgen.LoadBLSKeyWithPassPhrase(*blsKeyFile, blsPassphrase)
@ -342,7 +342,7 @@ func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) multibls.PublicKey {
os.Exit(100) os.Exit(100)
} }
multibls.AppendPriKey(consensusMultiPriKey, consensusPriKey) multibls.AppendPriKey(consensusMultiPriKey, consensusPriKey)
multibls.AppendPubKey(consensusMultiPubKey, consensusPriKey.GetPublicKey()) consensusMultiPubKey = append(consensusMultiPubKey, multibls.GetPublicKey(consensusPriKey.GetPublicKey())...)
} else if *cmkEncryptedBLSKey != "" { } else if *cmkEncryptedBLSKey != "" {
consensusPriKey, err := blsgen.LoadAwsCMKEncryptedBLSKey(*cmkEncryptedBLSKey, awsSettingString) consensusPriKey, err := blsgen.LoadAwsCMKEncryptedBLSKey(*cmkEncryptedBLSKey, awsSettingString)
if err != nil { if err != nil {
@ -351,7 +351,7 @@ func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) multibls.PublicKey {
} }
multibls.AppendPriKey(consensusMultiPriKey, consensusPriKey) multibls.AppendPriKey(consensusMultiPriKey, consensusPriKey)
multibls.AppendPubKey(consensusMultiPubKey, consensusPriKey.GetPublicKey()) consensusMultiPubKey = append(consensusMultiPubKey, multibls.GetPublicKey(consensusPriKey.GetPublicKey())...)
} else { } else {
err := readMultiBLSKeys(consensusMultiPriKey, consensusMultiPubKey) err := readMultiBLSKeys(consensusMultiPriKey, consensusMultiPubKey)
if err != nil { if err != nil {
@ -364,7 +364,7 @@ func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) multibls.PublicKey {
nodeConfig.ConsensusPriKey = consensusMultiPriKey nodeConfig.ConsensusPriKey = consensusMultiPriKey
nodeConfig.ConsensusPubKey = consensusMultiPubKey nodeConfig.ConsensusPubKey = consensusMultiPubKey
return *consensusMultiPubKey return consensusMultiPubKey
} }
func createGlobalConfig() (*nodeconfig.ConfigType, error) { func createGlobalConfig() (*nodeconfig.ConfigType, error) {
@ -398,7 +398,7 @@ func createGlobalConfig() (*nodeconfig.ConfigType, error) {
selfPeer := p2p.Peer{ selfPeer := p2p.Peer{
IP: *ip, IP: *ip,
Port: *port, Port: *port,
ConsensusPubKey: nodeConfig.ConsensusPubKey.PublicKey[0], ConsensusPubKey: nodeConfig.ConsensusPubKey[0].Object,
} }
myHost, err = p2p.NewHost(&selfPeer, nodeConfig.P2PPriKey) myHost, err = p2p.NewHost(&selfPeer, nodeConfig.P2PPriKey)
@ -431,7 +431,7 @@ func setupConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
currentConsensus, err := consensus.New( currentConsensus, err := consensus.New(
myHost, nodeConfig.ShardID, p2p.Peer{}, nodeConfig.ConsensusPriKey, decider, myHost, nodeConfig.ShardID, p2p.Peer{}, nodeConfig.ConsensusPriKey, decider,
) )
currentConsensus.Decider.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) { currentConsensus.Decider.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return currentConsensus.PubKey, nil return currentConsensus.PubKey, nil
}) })

@ -1,6 +1,8 @@
package consensus package consensus
import ( import (
"bytes"
msg_pb "github.com/harmony-one/harmony/api/proto/message" msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/crypto/bls"
@ -37,7 +39,7 @@ func (consensus *Consensus) validatorSanityChecks(msg *msg_pb.Message) bool {
if err != nil { if err != nil {
return false return false
} }
if !senderKey.IsEqual(consensus.LeaderPubKey) && if !senderKey.IsEqual(consensus.LeaderPubKey.Object) &&
consensus.current.Mode() == Normal && !consensus.IgnoreViewIDCheck.IsSet() { consensus.current.Mode() == Normal && !consensus.IgnoreViewIDCheck.IsSet() {
consensus.getLogger().Warn().Msgf( consensus.getLogger().Warn().Msgf(
"[%s] SenderKey not match leader PubKey", "[%s] SenderKey not match leader PubKey",
@ -104,7 +106,7 @@ func (consensus *Consensus) isRightBlockNumAndViewID(recvMsg *FBFTMessage,
Uint64("MsgViewID", recvMsg.ViewID). Uint64("MsgViewID", recvMsg.ViewID).
Uint64("MsgBlockNum", recvMsg.BlockNum). Uint64("MsgBlockNum", recvMsg.BlockNum).
Uint64("blockNum", consensus.blockNum). Uint64("blockNum", consensus.blockNum).
Str("ValidatorPubKey", recvMsg.SenderPubkey.SerializeToHexStr()). Str("ValidatorPubKey", recvMsg.SenderPubkey.Bytes.Hex()).
Msg("[OnCommit] BlockNum/viewID not match") Msg("[OnCommit] BlockNum/viewID not match")
return false return false
} }
@ -117,15 +119,15 @@ func (consensus *Consensus) onAnnounceSanityChecks(recvMsg *FBFTMessage) bool {
) )
if len(logMsgs) > 0 { if len(logMsgs) > 0 {
if logMsgs[0].BlockHash != recvMsg.BlockHash && if logMsgs[0].BlockHash != recvMsg.BlockHash &&
logMsgs[0].SenderPubkey.IsEqual(recvMsg.SenderPubkey) { bytes.Equal(logMsgs[0].SenderPubkey.Bytes[:], recvMsg.SenderPubkey.Bytes[:]) {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("logMsgSenderKey", logMsgs[0].SenderPubkey.SerializeToHexStr()). Str("logMsgSenderKey", logMsgs[0].SenderPubkey.Bytes.Hex()).
Str("logMsgBlockHash", logMsgs[0].BlockHash.Hex()). Str("logMsgBlockHash", logMsgs[0].BlockHash.Hex()).
Str("recvMsg.SenderPubkey", recvMsg.SenderPubkey.SerializeToHexStr()). Str("recvMsg.SenderPubkey", recvMsg.SenderPubkey.Bytes.Hex()).
Uint64("recvMsg.BlockNum", recvMsg.BlockNum). Uint64("recvMsg.BlockNum", recvMsg.BlockNum).
Uint64("recvMsg.ViewID", recvMsg.ViewID). Uint64("recvMsg.ViewID", recvMsg.ViewID).
Str("recvMsgBlockHash", recvMsg.BlockHash.Hex()). Str("recvMsgBlockHash", recvMsg.BlockHash.Hex()).
Str("LeaderKey", consensus.LeaderPubKey.SerializeToHexStr()). Str("LeaderKey", consensus.LeaderPubKey.Bytes.Hex()).
Msg("[OnAnnounce] Leader is malicious") Msg("[OnAnnounce] Leader is malicious")
if consensus.current.Mode() == ViewChanging { if consensus.current.Mode() == ViewChanging {
consensus.getLogger().Debug().Msg( consensus.getLogger().Debug().Msg(
@ -136,7 +138,7 @@ func (consensus *Consensus) onAnnounceSanityChecks(recvMsg *FBFTMessage) bool {
} }
} }
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("leaderKey", consensus.LeaderPubKey.SerializeToHexStr()). Str("leaderKey", consensus.LeaderPubKey.Bytes.Hex()).
Msg("[OnAnnounce] Announce message received again") Msg("[OnAnnounce] Announce message received again")
} }
return consensus.isRightBlockNumCheck(recvMsg) return consensus.isRightBlockNumCheck(recvMsg)
@ -205,7 +207,7 @@ func (consensus *Consensus) viewChangeSanityCheck(msg *msg_pb.Message) bool {
} }
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Msg("[viewChangeSanityCheck] Checking new message") Msg("[viewChangeSanityCheck] Checking new message")
senderKey, err := consensus.verifyViewChangeSenderKey(msg) err := consensus.verifyViewChangeSenderKey(msg)
if err != nil { if err != nil {
if err == shard.ErrValidNotInCommittee { if err == shard.ErrValidNotInCommittee {
consensus.getLogger().Info(). consensus.getLogger().Info().
@ -221,6 +223,10 @@ func (consensus *Consensus) viewChangeSanityCheck(msg *msg_pb.Message) bool {
} }
return false return false
} }
senderKey, err := bls.BytesToBLSPublicKey(msg.GetViewchange().SenderPubkey)
if err != nil {
return false
}
if err := verifyMessageSig(senderKey, msg); err != nil { if err := verifyMessageSig(senderKey, msg); err != nil {
consensus.getLogger().Error().Err(err).Msgf( consensus.getLogger().Error().Err(err).Msgf(
"[%s] Failed To Verify Sender's Signature", "[%s] Failed To Verify Sender's Signature",

@ -14,6 +14,7 @@ import (
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls" "github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/slash" "github.com/harmony-one/harmony/staking/slash"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -76,9 +77,9 @@ type Consensus struct {
pubKeyLock sync.Mutex pubKeyLock sync.Mutex
// private/public keys of current node // private/public keys of current node
priKey *multibls.PrivateKey priKey *multibls.PrivateKey
PubKey *multibls.PublicKey PubKey multibls.PublicKeys
// the publickey of leader // the publickey of leader
LeaderPubKey *bls.PublicKey LeaderPubKey *shard.BLSPublicKeyWrapper
viewID uint64 viewID uint64
// Blockhash - 32 byte // Blockhash - 32 byte
blockHash [32]byte blockHash [32]byte
@ -153,8 +154,8 @@ func (consensus *Consensus) VdfSeedSize() int {
// GetLeaderPrivateKey returns leader private key if node is the leader // GetLeaderPrivateKey returns leader private key if node is the leader
func (consensus *Consensus) GetLeaderPrivateKey(leaderKey *bls.PublicKey) (*bls.SecretKey, error) { func (consensus *Consensus) GetLeaderPrivateKey(leaderKey *bls.PublicKey) (*bls.SecretKey, error) {
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if key.IsEqual(leaderKey) { if key.Object.IsEqual(leaderKey) {
return consensus.priKey.PrivateKey[i], nil return consensus.priKey.PrivateKey[i], nil
} }
} }
@ -163,7 +164,7 @@ func (consensus *Consensus) GetLeaderPrivateKey(leaderKey *bls.PublicKey) (*bls.
// GetConsensusLeaderPrivateKey returns consensus leader private key if node is the leader // GetConsensusLeaderPrivateKey returns consensus leader private key if node is the leader
func (consensus *Consensus) GetConsensusLeaderPrivateKey() (*bls.SecretKey, error) { func (consensus *Consensus) GetConsensusLeaderPrivateKey() (*bls.SecretKey, error) {
return consensus.GetLeaderPrivateKey(consensus.LeaderPubKey) return consensus.GetLeaderPrivateKey(consensus.LeaderPubKey.Object)
} }
// TODO: put shardId into chain reader's chain config // TODO: put shardId into chain reader's chain config

@ -84,9 +84,13 @@ func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls.PublicKey) int64 {
Str("BLSPubKey", pubKeys[i].SerializeToHexStr()). Str("BLSPubKey", pubKeys[i].SerializeToHexStr()).
Msg("Member") Msg("Member")
} }
consensus.LeaderPubKey = pubKeys[0]
allKeys := consensus.Decider.Participants()
if len(allKeys) != 0 {
consensus.LeaderPubKey = &allKeys[0]
utils.Logger().Info(). utils.Logger().Info().
Str("info", consensus.LeaderPubKey.SerializeToHexStr()).Msg("My Leader") Str("info", consensus.LeaderPubKey.Bytes.Hex()).Msg("My Leader")
}
consensus.pubKeyLock.Unlock() consensus.pubKeyLock.Unlock()
// reset states after update public keys // reset states after update public keys
consensus.ResetState() consensus.ResetState()
@ -150,8 +154,12 @@ func (consensus *Consensus) ResetState() {
consensus.block = []byte{} consensus.block = []byte{}
consensus.Decider.ResetPrepareAndCommitVotes() consensus.Decider.ResetPrepareAndCommitVotes()
members := consensus.Decider.Participants() members := consensus.Decider.Participants()
prepareBitmap, _ := bls_cosi.NewMask(members, nil) publicKeys := []*bls.PublicKey{}
commitBitmap, _ := bls_cosi.NewMask(members, nil) for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
prepareBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
commitBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
consensus.prepareBitmap = prepareBitmap consensus.prepareBitmap = prepareBitmap
consensus.commitBitmap = commitBitmap consensus.commitBitmap = commitBitmap
consensus.aggregatedPrepareSig = nil consensus.aggregatedPrepareSig = nil
@ -164,12 +172,8 @@ func (consensus *Consensus) ToggleConsensusCheck() {
} }
// IsValidatorInCommittee returns whether the given validator BLS address is part of my committee // IsValidatorInCommittee returns whether the given validator BLS address is part of my committee
func (consensus *Consensus) IsValidatorInCommittee(pubKey *bls.PublicKey) bool { func (consensus *Consensus) IsValidatorInCommittee(pubKey shard.BLSPublicKey) bool {
pubKeyBytes := shard.FromLibBLSPublicKeyUnsafe(pubKey) return consensus.Decider.IndexOf(pubKey) != -1
if pubKeyBytes == nil {
return false
}
return consensus.Decider.IndexOf(*pubKeyBytes) != -1
} }
// IsValidatorInCommitteeBytes returns whether the given validator BLS address is part of my committee // IsValidatorInCommitteeBytes returns whether the given validator BLS address is part of my committee
@ -210,17 +214,15 @@ func (consensus *Consensus) verifySenderKey(msg *msg_pb.Message) error {
return nil return nil
} }
func (consensus *Consensus) verifyViewChangeSenderKey(msg *msg_pb.Message) (*bls.PublicKey, error) { func (consensus *Consensus) verifyViewChangeSenderKey(msg *msg_pb.Message) error {
vcMsg := msg.GetViewchange() vcMsg := msg.GetViewchange()
senderKey, err := bls_cosi.BytesToBLSPublicKey(vcMsg.SenderPubkey) senderKey := shard.BLSPublicKey{}
if err != nil { copy(senderKey[:], vcMsg.SenderPubkey)
return nil, err
}
if !consensus.IsValidatorInCommittee(senderKey) { if !consensus.IsValidatorInCommittee(senderKey) {
return nil, shard.ErrValidNotInCommittee return shard.ErrValidNotInCommittee
} }
return senderKey, nil return nil
} }
// SetViewID set the viewID to the height of the blockchain // SetViewID set the viewID to the height of the blockchain
@ -263,7 +265,7 @@ func (consensus *Consensus) checkViewID(msg *FBFTMessage) error {
consensus.consensusTimeout[timeoutConsensus].Start() consensus.consensusTimeout[timeoutConsensus].Start()
utils.Logger().Debug(). utils.Logger().Debug().
Uint64("viewID", consensus.viewID). Uint64("viewID", consensus.viewID).
Str("leaderKey", consensus.LeaderPubKey.SerializeToHexStr()[:20]). Str("leaderKey", consensus.LeaderPubKey.Bytes.Hex()).
Msg("viewID and leaderKey override") Msg("viewID and leaderKey override")
utils.Logger().Debug(). utils.Logger().Debug().
Uint64("viewID", consensus.viewID). Uint64("viewID", consensus.viewID).
@ -291,8 +293,15 @@ func (consensus *Consensus) ReadSignatureBitmapPayload(
return nil, nil, errors.New("payload not have enough length") return nil, nil, errors.New("payload not have enough length")
} }
sigAndBitmapPayload := recvPayload[offset:] sigAndBitmapPayload := recvPayload[offset:]
// TODO(audit): keep a Mask in the Decider so it won't be reconstructed on the fly.
members := consensus.Decider.Participants()
publicKeys := []*bls.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
return chain.ReadSignatureBitmapByPublicKeys( return chain.ReadSignatureBitmapByPublicKeys(
sigAndBitmapPayload, consensus.Decider.Participants(), sigAndBitmapPayload, publicKeys,
) )
} }
@ -310,7 +319,7 @@ func (consensus *Consensus) getLogger() *zerolog.Logger {
// retrieve corresponding blsPublicKey from Coinbase Address // retrieve corresponding blsPublicKey from Coinbase Address
func (consensus *Consensus) getLeaderPubKeyFromCoinbase( func (consensus *Consensus) getLeaderPubKeyFromCoinbase(
header *block.Header, header *block.Header,
) (*bls.PublicKey, error) { ) (*shard.BLSPublicKeyWrapper, error) {
shardState, err := consensus.ChainReader.ReadShardState(header.Epoch()) shardState, err := consensus.ChainReader.ReadShardState(header.Epoch())
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "cannot read shard state %v %s", return nil, errors.Wrapf(err, "cannot read shard state %v %s",
@ -333,14 +342,14 @@ func (consensus *Consensus) getLeaderPubKeyFromCoinbase(
if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil { if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil {
return nil, err return nil, err
} }
return committerKey, nil return &shard.BLSPublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil
} }
} else { } else {
if member.EcdsaAddress == header.Coinbase() { if member.EcdsaAddress == header.Coinbase() {
if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil { if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil {
return nil, err return nil, err
} }
return committerKey, nil return &shard.BLSPublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil
} }
} }
} }
@ -385,7 +394,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
// Only happens once, the flip-over to a new Decider policy // Only happens once, the flip-over to a new Decider policy
if isFirstTimeStaking || haventUpdatedDecider { if isFirstTimeStaking || haventUpdatedDecider {
decider := quorum.NewDecider(quorum.SuperMajorityStake, consensus.ShardID) decider := quorum.NewDecider(quorum.SuperMajorityStake, consensus.ShardID)
decider.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) { decider.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return consensus.PubKey, nil return consensus.PubKey, nil
}) })
consensus.Decider = decider consensus.Decider = decider
@ -487,7 +496,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
hasError = true hasError = true
} else { } else {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("leaderPubKey", leaderPubKey.SerializeToHexStr()). Str("leaderPubKey", leaderPubKey.Bytes.Hex()).
Msg("[UpdateConsensusInformation] Most Recent LeaderPubKey Updated Based on BlockChain") Msg("[UpdateConsensusInformation] Most Recent LeaderPubKey Updated Based on BlockChain")
consensus.LeaderPubKey = leaderPubKey consensus.LeaderPubKey = leaderPubKey
} }
@ -501,7 +510,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
} }
// If the leader changed and I myself become the leader // If the leader changed and I myself become the leader
if !consensus.LeaderPubKey.IsEqual(oldLeader) && consensus.IsLeader() { if !consensus.LeaderPubKey.Object.IsEqual(oldLeader.Object) && consensus.IsLeader() {
go func() { go func() {
utils.Logger().Debug(). utils.Logger().Debug().
Str("myKey", consensus.PubKey.SerializeToHexStr()). Str("myKey", consensus.PubKey.SerializeToHexStr()).
@ -521,8 +530,8 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
// IsLeader check if the node is a leader or not by comparing the public key of // IsLeader check if the node is a leader or not by comparing the public key of
// the node with the leader public key // the node with the leader public key
func (consensus *Consensus) IsLeader() bool { func (consensus *Consensus) IsLeader() bool {
for _, key := range consensus.PubKey.PublicKey { for _, key := range consensus.PubKey {
if key.IsEqual(consensus.LeaderPubKey) { if key.Object.IsEqual(consensus.LeaderPubKey.Object) {
return true return true
} }
} }
@ -540,6 +549,10 @@ func (consensus *Consensus) NeedsRandomNumberGeneration(epoch *big.Int) bool {
func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) { func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) {
members := consensus.Decider.Participants() members := consensus.Decider.Participants()
publicKeys := []*bls.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
if _, ok := consensus.bhpSigs[viewID]; !ok { if _, ok := consensus.bhpSigs[viewID]; !ok {
consensus.bhpSigs[viewID] = map[string]*bls.Sign{} consensus.bhpSigs[viewID] = map[string]*bls.Sign{}
} }
@ -550,15 +563,15 @@ func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) {
consensus.viewIDSigs[viewID] = map[string]*bls.Sign{} consensus.viewIDSigs[viewID] = map[string]*bls.Sign{}
} }
if _, ok := consensus.bhpBitmap[viewID]; !ok { if _, ok := consensus.bhpBitmap[viewID]; !ok {
bhpBitmap, _ := bls_cosi.NewMask(members, nil) bhpBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
consensus.bhpBitmap[viewID] = bhpBitmap consensus.bhpBitmap[viewID] = bhpBitmap
} }
if _, ok := consensus.nilBitmap[viewID]; !ok { if _, ok := consensus.nilBitmap[viewID]; !ok {
nilBitmap, _ := bls_cosi.NewMask(members, nil) nilBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
consensus.nilBitmap[viewID] = nilBitmap consensus.nilBitmap[viewID] = nilBitmap
} }
if _, ok := consensus.viewIDBitmap[viewID]; !ok { if _, ok := consensus.viewIDBitmap[viewID]; !ok {
viewIDBitmap, _ := bls_cosi.NewMask(members, nil) viewIDBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
consensus.viewIDBitmap[viewID] = viewIDBitmap consensus.viewIDBitmap[viewID] = viewIDBitmap
} }
} }

@ -40,8 +40,10 @@ func TestPopulateMessageFields(t *testing.T) {
}, },
} }
keyBytes := shard.BLSPublicKey{}
keyBytes.FromLibBLSPublicKey(blsPriKey.GetPublicKey())
consensusMsg := consensus.populateMessageFields(msg.GetConsensus(), consensus.blockHash[:], consensusMsg := consensus.populateMessageFields(msg.GetConsensus(), consensus.blockHash[:],
blsPriKey.GetPublicKey()) keyBytes)
if consensusMsg.ViewId != 2 { if consensusMsg.ViewId != 2 {
t.Errorf("Consensus ID is not populated correctly") t.Errorf("Consensus ID is not populated correctly")

@ -107,7 +107,10 @@ func (consensus *Consensus) finalizeCommits() {
return return
} }
// Construct committed message // Construct committed message
network, err := consensus.construct(msg_pb.MessageType_COMMITTED, nil, leaderPriKey.GetPublicKey(), leaderPriKey) // TODO(audit): wrap bls private key with public key
leaderPubKeyBytes := shard.BLSPublicKey{}
leaderPubKeyBytes.FromLibBLSPublicKey(leaderPriKey.GetPublicKey())
network, err := consensus.construct(msg_pb.MessageType_COMMITTED, nil, leaderPubKeyBytes, leaderPriKey)
if err != nil { if err != nil {
consensus.getLogger().Warn().Err(err). consensus.getLogger().Warn().Err(err).
Msg("[FinalizeCommits] Unable to construct Committed message") Msg("[FinalizeCommits] Unable to construct Committed message")
@ -544,7 +547,7 @@ func (consensus *Consensus) GenerateVrfAndProof(newBlock *types.Block, vrfBlockN
// ValidateVrfAndProof validates a VRF/Proof from hash of previous block // ValidateVrfAndProof validates a VRF/Proof from hash of previous block
func (consensus *Consensus) ValidateVrfAndProof(headerObj *block.Header) bool { func (consensus *Consensus) ValidateVrfAndProof(headerObj *block.Header) bool {
vrfPk := vrf_bls.NewVRFVerifier(consensus.LeaderPubKey) vrfPk := vrf_bls.NewVRFVerifier(consensus.LeaderPubKey.Object)
var blockHash [32]byte var blockHash [32]byte
previousHeader := consensus.ChainReader.GetHeaderByNumber( previousHeader := consensus.ChainReader.GetHeaderByNumber(
headerObj.Number().Uint64() - 1, headerObj.Number().Uint64() - 1,

@ -3,6 +3,8 @@ package consensus
import ( import (
"encoding/binary" "encoding/binary"
"github.com/harmony-one/harmony/shard"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
@ -30,7 +32,7 @@ func (consensus *Consensus) constructViewChangeMessage(pubKey *bls.PublicKey, pr
vcMsg.SenderPubkey = pubKey.Serialize() vcMsg.SenderPubkey = pubKey.Serialize()
// next leader key already updated // next leader key already updated
vcMsg.LeaderPubkey = consensus.LeaderPubKey.Serialize() vcMsg.LeaderPubkey = consensus.LeaderPubKey.Bytes[:]
preparedMsgs := consensus.FBFTLog.GetMessagesByTypeSeq( preparedMsgs := consensus.FBFTLog.GetMessagesByTypeSeq(
msg_pb.MessageType_PREPARED, consensus.blockNum, msg_pb.MessageType_PREPARED, consensus.blockNum,
@ -98,7 +100,7 @@ func (consensus *Consensus) constructViewChangeMessage(pubKey *bls.PublicKey, pr
} }
// new leader construct newview message // new leader construct newview message
func (consensus *Consensus) constructNewViewMessage(viewID uint64, pubKey *bls.PublicKey, priKey *bls.SecretKey) []byte { func (consensus *Consensus) constructNewViewMessage(viewID uint64, pubKey shard.BLSPublicKey, priKey *bls.SecretKey) []byte {
message := &msg_pb.Message{ message := &msg_pb.Message{
ServiceType: msg_pb.ServiceType_CONSENSUS, ServiceType: msg_pb.ServiceType_CONSENSUS,
Type: msg_pb.MessageType_NEWVIEW, Type: msg_pb.MessageType_NEWVIEW,
@ -112,7 +114,7 @@ func (consensus *Consensus) constructNewViewMessage(viewID uint64, pubKey *bls.P
vcMsg.BlockNum = consensus.blockNum vcMsg.BlockNum = consensus.blockNum
vcMsg.ShardId = consensus.ShardID vcMsg.ShardId = consensus.ShardID
// sender address // sender address
vcMsg.SenderPubkey = pubKey.Serialize() vcMsg.SenderPubkey = pubKey[:]
vcMsg.Payload = consensus.m1Payload vcMsg.Payload = consensus.m1Payload
if len(consensus.m1Payload) != 0 { if len(consensus.m1Payload) != 0 {
block := consensus.FBFTLog.GetBlockByHash(consensus.blockHash) block := consensus.FBFTLog.GetBlockByHash(consensus.blockHash)

@ -3,6 +3,8 @@ package consensus
import ( import (
"bytes" "bytes"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
msg_pb "github.com/harmony-one/harmony/api/proto/message" msg_pb "github.com/harmony-one/harmony/api/proto/message"
@ -22,7 +24,7 @@ type NetworkMessage struct {
// Populates the common basic fields for all consensus message. // Populates the common basic fields for all consensus message.
func (consensus *Consensus) populateMessageFields( func (consensus *Consensus) populateMessageFields(
request *msg_pb.ConsensusRequest, blockHash []byte, pubKey *bls.PublicKey, request *msg_pb.ConsensusRequest, blockHash []byte, pubKey shard.BLSPublicKey,
) *msg_pb.ConsensusRequest { ) *msg_pb.ConsensusRequest {
request.ViewId = consensus.viewID request.ViewId = consensus.viewID
request.BlockNum = consensus.blockNum request.BlockNum = consensus.blockNum
@ -30,13 +32,13 @@ func (consensus *Consensus) populateMessageFields(
// 32 byte block hash // 32 byte block hash
request.BlockHash = blockHash request.BlockHash = blockHash
// sender address // sender address
request.SenderPubkey = pubKey.Serialize() request.SenderPubkey = pubKey[:]
return request return request
} }
// construct is the single creation point of messages intended for the wire. // construct is the single creation point of messages intended for the wire.
func (consensus *Consensus) construct( func (consensus *Consensus) construct(
p msg_pb.MessageType, payloadForSign []byte, pubKey *bls.PublicKey, priKey *bls.SecretKey, p msg_pb.MessageType, payloadForSign []byte, pubKey shard.BLSPublicKey, priKey *bls.SecretKey,
) (*NetworkMessage, error) { ) (*NetworkMessage, error) {
message := &msg_pb.Message{ message := &msg_pb.Message{
ServiceType: msg_pb.ServiceType_CONSENSUS, ServiceType: msg_pb.ServiceType_CONSENSUS,

@ -32,7 +32,9 @@ func TestConstructAnnounceMessage(test *testing.T) {
test.Fatalf("Cannot create consensus: %v", err) test.Fatalf("Cannot create consensus: %v", err)
} }
consensus.blockHash = [32]byte{} consensus.blockHash = [32]byte{}
if _, err = consensus.construct(msg_pb.MessageType_ANNOUNCE, nil, blsPriKey.GetPublicKey(), blsPriKey); err != nil { keyBytes := shard.BLSPublicKey{}
keyBytes.FromLibBLSPublicKey(blsPriKey.GetPublicKey())
if _, err = consensus.construct(msg_pb.MessageType_ANNOUNCE, nil, keyBytes, blsPriKey); err != nil {
test.Fatalf("could not construct announce: %v", err) test.Fatalf("could not construct announce: %v", err)
} }
} }
@ -94,7 +96,9 @@ func TestConstructPreparedMessage(test *testing.T) {
test.Log(errors.New("prepareBitmap.SetKey")) test.Log(errors.New("prepareBitmap.SetKey"))
} }
network, err := consensus.construct(msg_pb.MessageType_PREPARED, nil, blsPriKey.GetPublicKey(), blsPriKey) keyBytes := shard.BLSPublicKey{}
keyBytes.FromLibBLSPublicKey(blsPriKey.GetPublicKey())
network, err := consensus.construct(msg_pb.MessageType_PREPARED, nil, keyBytes, blsPriKey)
if err != nil { if err != nil {
test.Errorf("Error when creating prepared message") test.Errorf("Error when creating prepared message")
} }

@ -4,7 +4,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/quorum" "github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/slash" "github.com/harmony-one/harmony/staking/slash"
) )
@ -13,11 +12,11 @@ import (
func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool { func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
if consensus.couldThisBeADoubleSigner(recvMsg) { if consensus.couldThisBeADoubleSigner(recvMsg) {
if alreadyCastBallot := consensus.Decider.ReadBallot( if alreadyCastBallot := consensus.Decider.ReadBallot(
quorum.Commit, recvMsg.SenderPubkeyBytes, quorum.Commit, recvMsg.SenderPubkey.Bytes,
); alreadyCastBallot != nil { ); alreadyCastBallot != nil {
firstPubKey := bls.PublicKey{} firstPubKey := bls.PublicKey{}
alreadyCastBallot.SignerPubKey.ToLibBLSPublicKey(&firstPubKey) alreadyCastBallot.SignerPubKey.ToLibBLSPublicKey(&firstPubKey)
if recvMsg.SenderPubkey.IsEqual(&firstPubKey) { if recvMsg.SenderPubkey.Object.IsEqual(&firstPubKey) {
for _, blk := range consensus.FBFTLog.GetBlocksByNumber(recvMsg.BlockNum) { for _, blk := range consensus.FBFTLog.GetBlocksByNumber(recvMsg.BlockNum) {
firstSignedBlock := blk.Header() firstSignedBlock := blk.Header()
areHeightsEqual := firstSignedBlock.Number().Uint64() == recvMsg.BlockNum areHeightsEqual := firstSignedBlock.Number().Uint64() == recvMsg.BlockNum
@ -45,13 +44,7 @@ func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
Msg("could not read shard state") Msg("could not read shard state")
return true return true
} }
offender := shard.FromLibBLSPublicKeyUnsafe(recvMsg.SenderPubkey)
if offender == nil {
consensus.getLogger().Error().
Str("msg", recvMsg.String()).
Msg("could not get shard key from sender's key")
return true
}
subComm, err := committee.FindCommitteeByID( subComm, err := committee.FindCommitteeByID(
consensus.ShardID, consensus.ShardID,
) )
@ -62,21 +55,14 @@ func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
return true return true
} }
addr, err := subComm.AddressForBLSKey(*offender) addr, err := subComm.AddressForBLSKey(recvMsg.SenderPubkey.Bytes)
if err != nil { if err != nil {
consensus.getLogger().Err(err).Str("msg", recvMsg.String()). consensus.getLogger().Err(err).Str("msg", recvMsg.String()).
Msg("could not find address for bls key") Msg("could not find address for bls key")
return true return true
} }
leaderShardKey := shard.FromLibBLSPublicKeyUnsafe(consensus.LeaderPubKey) leaderAddr, err := subComm.AddressForBLSKey(consensus.LeaderPubKey.Bytes)
if leaderShardKey == nil {
consensus.getLogger().Error().
Str("msg", recvMsg.String()).
Msg("could not get shard key from leader's key")
return true
}
leaderAddr, err := subComm.AddressForBLSKey(*leaderShardKey)
if err != nil { if err != nil {
consensus.getLogger().Err(err).Str("msg", recvMsg.String()). consensus.getLogger().Err(err).Str("msg", recvMsg.String()).
Msg("could not find address for leader bls key") Msg("could not find address for leader bls key")
@ -92,7 +78,7 @@ func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
alreadyCastBallot.Signature, alreadyCastBallot.Signature,
}, },
SecondVote: slash.Vote{ SecondVote: slash.Vote{
*offender, recvMsg.SenderPubkey.Bytes,
recvMsg.BlockHash, recvMsg.BlockHash,
common.Hex2Bytes(doubleSign.SerializeToHexStr()), common.Hex2Bytes(doubleSign.SerializeToHexStr()),
}}, }},

@ -28,9 +28,8 @@ type FBFTMessage struct {
BlockNum uint64 BlockNum uint64
BlockHash common.Hash BlockHash common.Hash
Block []byte Block []byte
SenderPubkey *bls.PublicKey SenderPubkey *shard.BLSPublicKeyWrapper
SenderPubkeyBytes shard.BLSPublicKey LeaderPubkey *shard.BLSPublicKeyWrapper
LeaderPubkey *bls.PublicKey
Payload []byte Payload []byte
ViewchangeSig *bls.Sign ViewchangeSig *bls.Sign
ViewidSig *bls.Sign ViewidSig *bls.Sign
@ -48,8 +47,8 @@ func (m *FBFTMessage) String() string {
m.ViewID, m.ViewID,
m.BlockNum, m.BlockNum,
m.BlockHash.Hex(), m.BlockHash.Hex(),
m.SenderPubkeyBytes.Hex(), m.SenderPubkey.Bytes.Hex(),
m.LeaderPubkey.SerializeToHexStr(), m.LeaderPubkey.Bytes.Hex(),
) )
} }
@ -250,8 +249,8 @@ func ParseFBFTMessage(msg *msg_pb.Message) (*FBFTMessage, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
pbftMsg.SenderPubkey = pubKey pbftMsg.SenderPubkey = &shard.BLSPublicKeyWrapper{Object: pubKey}
copy(pbftMsg.SenderPubkeyBytes[:], consensusMsg.SenderPubkey[:]) copy(pbftMsg.SenderPubkey.Bytes[:], consensusMsg.SenderPubkey[:])
return &pbftMsg, nil return &pbftMsg, nil
} }
@ -296,9 +295,11 @@ func ParseViewChangeMessage(msg *msg_pb.Message) (*FBFTMessage, error) {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to deserialize the viewid signature") utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to deserialize the viewid signature")
return nil, err return nil, err
} }
pbftMsg.SenderPubkey = pubKey
copy(pbftMsg.SenderPubkeyBytes[:], vcMsg.SenderPubkey[:]) pbftMsg.SenderPubkey = &shard.BLSPublicKeyWrapper{Object: pubKey}
pbftMsg.LeaderPubkey = leaderKey copy(pbftMsg.SenderPubkey.Bytes[:], vcMsg.SenderPubkey[:])
pbftMsg.LeaderPubkey = &shard.BLSPublicKeyWrapper{Object: leaderKey}
copy(pbftMsg.LeaderPubkey.Bytes[:], vcMsg.LeaderPubkey[:])
pbftMsg.ViewchangeSig = &vcSig pbftMsg.ViewchangeSig = &vcSig
pbftMsg.ViewidSig = &vcSig1 pbftMsg.ViewidSig = &vcSig1
return &pbftMsg, nil return &pbftMsg, nil
@ -326,9 +327,15 @@ func (consensus *Consensus) ParseNewViewMessage(msg *msg_pb.Message) (*FBFTMessa
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to parse senderpubkey") utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to parse senderpubkey")
return nil, err return nil, err
} }
FBFTMsg.SenderPubkey = pubKey
copy(FBFTMsg.SenderPubkeyBytes[:], vcMsg.SenderPubkey[:])
FBFTMsg.SenderPubkey = &shard.BLSPublicKeyWrapper{Object: pubKey}
copy(FBFTMsg.SenderPubkey.Bytes[:], vcMsg.SenderPubkey[:])
members := consensus.Decider.Participants()
publicKeys := []*bls.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
if len(vcMsg.M3Aggsigs) > 0 { if len(vcMsg.M3Aggsigs) > 0 {
m3Sig := bls.Sign{} m3Sig := bls.Sign{}
err = m3Sig.Deserialize(vcMsg.M3Aggsigs) err = m3Sig.Deserialize(vcMsg.M3Aggsigs)
@ -336,7 +343,7 @@ func (consensus *Consensus) ParseNewViewMessage(msg *msg_pb.Message) (*FBFTMessa
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to deserialize the multi signature for M3 viewID signature") utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to deserialize the multi signature for M3 viewID signature")
return nil, err return nil, err
} }
m3mask, err := bls_cosi.NewMask(consensus.Decider.Participants(), nil) m3mask, err := bls_cosi.NewMask(publicKeys, nil)
if err != nil { if err != nil {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature") utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature")
return nil, err return nil, err
@ -353,7 +360,7 @@ func (consensus *Consensus) ParseNewViewMessage(msg *msg_pb.Message) (*FBFTMessa
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to deserialize the multi signature for M2 aggregated signature") utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to deserialize the multi signature for M2 aggregated signature")
return nil, err return nil, err
} }
m2mask, err := bls_cosi.NewMask(consensus.Decider.Participants(), nil) m2mask, err := bls_cosi.NewMask(publicKeys, nil)
if err != nil { if err != nil {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature") utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature")
return nil, err return nil, err

@ -3,6 +3,8 @@ package consensus
import ( import (
"time" "time"
"github.com/harmony-one/harmony/shard"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
msg_pb "github.com/harmony-one/harmony/api/proto/message" msg_pb "github.com/harmony-one/harmony/api/proto/message"
@ -37,7 +39,11 @@ func (consensus *Consensus) announce(block *types.Block) {
consensus.getLogger().Warn().Err(err).Msg("[Announce] Node not a leader") consensus.getLogger().Warn().Err(err).Msg("[Announce] Node not a leader")
return return
} }
networkMessage, err := consensus.construct(msg_pb.MessageType_ANNOUNCE, nil, key.GetPublicKey(), key)
// TODO(audit): wrap bls private key with public key
leaderPubKeyBytes := shard.BLSPublicKey{}
leaderPubKeyBytes.FromLibBLSPublicKey(key.GetPublicKey())
networkMessage, err := consensus.construct(msg_pb.MessageType_ANNOUNCE, nil, leaderPubKeyBytes, key)
if err != nil { if err != nil {
consensus.getLogger().Err(err). consensus.getLogger().Err(err).
Str("message-type", msg_pb.MessageType_ANNOUNCE.String()). Str("message-type", msg_pb.MessageType_ANNOUNCE.String()).
@ -56,8 +62,8 @@ func (consensus *Consensus) announce(block *types.Block) {
consensus.FBFTLog.AddBlock(block) consensus.FBFTLog.AddBlock(block)
// Leader sign the block hash itself // Leader sign the block hash itself
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if err := consensus.prepareBitmap.SetKey(key, true); err != nil { if err := consensus.prepareBitmap.SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn().Err(err).Msgf( consensus.getLogger().Warn().Err(err).Msgf(
"[Announce] Leader prepareBitmap SetKey failed for key at index %d", i, "[Announce] Leader prepareBitmap SetKey failed for key at index %d", i,
) )
@ -66,7 +72,7 @@ func (consensus *Consensus) announce(block *types.Block) {
if _, err := consensus.Decider.AddNewVote( if _, err := consensus.Decider.AddNewVote(
quorum.Prepare, quorum.Prepare,
consensus.PubKey.PublicKeyBytes[i], key.Bytes,
consensus.priKey.PrivateKey[i].SignHash(consensus.blockHash[:]), consensus.priKey.PrivateKey[i].SignHash(consensus.blockHash[:]),
block.Hash(), block.Hash(),
block.NumberU64(), block.NumberU64(),
@ -132,10 +138,10 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
consensus.mutex.Lock() consensus.mutex.Lock()
defer consensus.mutex.Unlock() defer consensus.mutex.Unlock()
// proceed only when the message is not received before // proceed only when the message is not received before
signed := consensus.Decider.ReadBallot(quorum.Prepare, recvMsg.SenderPubkeyBytes) signed := consensus.Decider.ReadBallot(quorum.Prepare, recvMsg.SenderPubkey.Bytes)
if signed != nil { if signed != nil {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", recvMsg.SenderPubkeyBytes.Hex()). Str("validatorPubKey", recvMsg.SenderPubkey.Bytes.Hex()).
Msg("[OnPrepare] Already Received prepare message from the validator") Msg("[OnPrepare] Already Received prepare message from the validator")
return return
} }
@ -143,7 +149,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
if consensus.Decider.IsQuorumAchieved(quorum.Prepare) { if consensus.Decider.IsQuorumAchieved(quorum.Prepare) {
// already have enough signatures // already have enough signatures
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", recvMsg.SenderPubkeyBytes.Hex()). Str("validatorPubKey", recvMsg.SenderPubkey.Bytes.Hex()).
Msg("[OnPrepare] Received Additional Prepare Message") Msg("[OnPrepare] Received Additional Prepare Message")
return return
} }
@ -156,7 +162,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
Msg("[OnPrepare] Failed to deserialize bls signature") Msg("[OnPrepare] Failed to deserialize bls signature")
return return
} }
if !sign.VerifyHash(recvMsg.SenderPubkey, consensus.blockHash[:]) { if !sign.VerifyHash(recvMsg.SenderPubkey.Object, consensus.blockHash[:]) {
consensus.getLogger().Error().Msg("[OnPrepare] Received invalid BLS signature") consensus.getLogger().Error().Msg("[OnPrepare] Received invalid BLS signature")
return return
} }
@ -166,7 +172,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
Int64("PublicKeys", consensus.Decider.ParticipantsCount()). Int64("PublicKeys", consensus.Decider.ParticipantsCount()).
Msg("[OnPrepare] Received New Prepare Signature") Msg("[OnPrepare] Received New Prepare Signature")
if _, err := consensus.Decider.AddNewVote( if _, err := consensus.Decider.AddNewVote(
quorum.Prepare, recvMsg.SenderPubkeyBytes, quorum.Prepare, recvMsg.SenderPubkey.Bytes,
&sign, recvMsg.BlockHash, &sign, recvMsg.BlockHash,
recvMsg.BlockNum, recvMsg.ViewID, recvMsg.BlockNum, recvMsg.ViewID,
); err != nil { ); err != nil {
@ -174,7 +180,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
return return
} }
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
if err := prepareBitmap.SetKey(recvMsg.SenderPubkey, true); err != nil { if err := prepareBitmap.SetKey(recvMsg.SenderPubkey.Object, true); err != nil {
consensus.getLogger().Warn().Err(err).Msg("[OnPrepare] prepareBitmap.SetKey failed") consensus.getLogger().Warn().Err(err).Msg("[OnPrepare] prepareBitmap.SetKey failed")
return return
} }
@ -211,7 +217,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
validatorPubKey, commitSig, commitBitmap := validatorPubKey, commitSig, commitBitmap :=
recvMsg.SenderPubkey, recvMsg.Payload, consensus.commitBitmap recvMsg.SenderPubkey, recvMsg.Payload, consensus.commitBitmap
logger := consensus.getLogger().With(). logger := consensus.getLogger().With().
Str("validatorPubKey", validatorPubKey.SerializeToHexStr()).Logger() Str("validatorPubKey", validatorPubKey.Bytes.Hex()).Logger()
// has to be called before verifying signature // has to be called before verifying signature
quorumWasMet := consensus.Decider.IsQuorumAchieved(quorum.Commit) quorumWasMet := consensus.Decider.IsQuorumAchieved(quorum.Commit)
@ -238,7 +244,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
Uint64("MsgBlockNum", recvMsg.BlockNum). Uint64("MsgBlockNum", recvMsg.BlockNum).
Logger() Logger()
if !sign.VerifyHash(recvMsg.SenderPubkey, commitPayload) { if !sign.VerifyHash(recvMsg.SenderPubkey.Object, commitPayload) {
logger.Error().Msg("[OnCommit] Cannot verify commit message") logger.Error().Msg("[OnCommit] Cannot verify commit message")
return return
} }
@ -249,14 +255,14 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
logger.Debug().Msg("[OnCommit] Received new commit message") logger.Debug().Msg("[OnCommit] Received new commit message")
if _, err := consensus.Decider.AddNewVote( if _, err := consensus.Decider.AddNewVote(
quorum.Commit, recvMsg.SenderPubkeyBytes, quorum.Commit, recvMsg.SenderPubkey.Bytes,
&sign, recvMsg.BlockHash, &sign, recvMsg.BlockHash,
recvMsg.BlockNum, recvMsg.ViewID, recvMsg.BlockNum, recvMsg.ViewID,
); err != nil { ); err != nil {
return return
} }
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
if err := commitBitmap.SetKey(recvMsg.SenderPubkey, true); err != nil { if err := commitBitmap.SetKey(recvMsg.SenderPubkey.Object, true); err != nil {
consensus.getLogger().Warn().Err(err). consensus.getLogger().Warn().Err(err).
Msg("[OnCommit] commitBitmap.SetKey failed") Msg("[OnCommit] commitBitmap.SetKey failed")
return return

@ -91,7 +91,7 @@ func (v *uniformVoteWeight) MarshalJSON() ([]byte, error) {
keysDump := v.Participants() keysDump := v.Participants()
keys := make([]string, len(keysDump)) keys := make([]string, len(keysDump))
for i := range keysDump { for i := range keysDump {
keys[i] = keysDump[i].SerializeToHexStr() keys[i] = keysDump[i].Bytes.Hex()
} }
return json.Marshal(t{v.Policy().String(), len(keys), keys}) return json.Marshal(t{v.Policy().String(), len(keys), keys})
@ -104,9 +104,9 @@ func (v *uniformVoteWeight) AmIMemberOfCommitee() bool {
} }
identity, _ := pubKeyFunc() identity, _ := pubKeyFunc()
everyone := v.Participants() everyone := v.Participants()
for _, key := range identity.PublicKey { for _, key := range identity {
for i := range everyone { for i := range everyone {
if key.IsEqual(everyone[i]) { if key.Object.IsEqual(everyone[i].Object) {
return true return true
} }
} }

@ -84,6 +84,8 @@ func (v *stakedVoteWeight) AddNewVote(
tallyQuorum.tally = tallyQuorum.tally.Add(additionalVotePower) tallyQuorum.tally = tallyQuorum.tally.Add(additionalVotePower)
t := v.QuorumThreshold() t := v.QuorumThreshold()
if !tallyQuorum.quorumAchieved {
tallyQuorum.quorumAchieved = tallyQuorum.tally.GT(t) tallyQuorum.quorumAchieved = tallyQuorum.tally.GT(t)
msg := "Attempt to reach quorum" msg := "Attempt to reach quorum"
@ -94,6 +96,7 @@ func (v *stakedVoteWeight) AddNewVote(
Str("phase", p.String()). Str("phase", p.String()).
Str("total-power-of-signers", tallyQuorum.tally.String()). Str("total-power-of-signers", tallyQuorum.tally.String()).
Msg(msg) Msg(msg)
}
return ballet, nil return ballet, nil
} }
@ -262,14 +265,12 @@ func (v *stakedVoteWeight) AmIMemberOfCommitee() bool {
return false return false
} }
identity, _ := pubKeyFunc() identity, _ := pubKeyFunc()
for _, key := range identity.PublicKey { for _, key := range identity {
if w := (shard.BLSPublicKey{}); w.FromLibBLSPublicKey(key) != nil { _, ok := v.roster.Voters[key.Bytes]
_, ok := v.roster.Voters[w]
if ok { if ok {
return true return true
} }
} }
}
return false return false
} }

@ -67,11 +67,10 @@ func (p Policy) String() string {
// ParticipantTracker .. // ParticipantTracker ..
type ParticipantTracker interface { type ParticipantTracker interface {
Participants() []*bls.PublicKey Participants() multibls.PublicKeys
ParticipantsKeyBytes() []shard.BLSPublicKey
IndexOf(shard.BLSPublicKey) int IndexOf(shard.BLSPublicKey) int
ParticipantsCount() int64 ParticipantsCount() int64
NextAfter(*bls.PublicKey) (bool, *bls.PublicKey) NextAfter(*shard.BLSPublicKeyWrapper) (bool, *shard.BLSPublicKeyWrapper)
UpdateParticipants(pubKeys []*bls.PublicKey) UpdateParticipants(pubKeys []*bls.PublicKey)
} }
@ -100,12 +99,12 @@ type SignatureReader interface {
// DependencyInjectionWriter .. // DependencyInjectionWriter ..
type DependencyInjectionWriter interface { type DependencyInjectionWriter interface {
SetMyPublicKeyProvider(func() (*multibls.PublicKey, error)) SetMyPublicKeyProvider(func() (multibls.PublicKeys, error))
} }
// DependencyInjectionReader .. // DependencyInjectionReader ..
type DependencyInjectionReader interface { type DependencyInjectionReader interface {
MyPublicKey() func() (*multibls.PublicKey, error) MyPublicKey() func() (multibls.PublicKeys, error)
} }
// Decider .. // Decider ..
@ -151,8 +150,7 @@ type Transition struct {
// and values are BLS private key signed signatures // and values are BLS private key signed signatures
type cIdentities struct { type cIdentities struct {
// Public keys of the committee including leader and validators // Public keys of the committee including leader and validators
publicKeys []*bls.PublicKey publicKeys []shard.BLSPublicKeyWrapper
publicKeysByte []shard.BLSPublicKey
keyIndexMap map[shard.BLSPublicKey]int keyIndexMap map[shard.BLSPublicKey]int
prepare *votepower.Round prepare *votepower.Round
commit *votepower.Round commit *votepower.Round
@ -162,7 +160,7 @@ type cIdentities struct {
} }
type depInject struct { type depInject struct {
publicKeyProvider func() (*multibls.PublicKey, error) publicKeyProvider func() (multibls.PublicKeys, error)
} }
func (s *cIdentities) AggregateVotes(p Phase) *bls.Sign { func (s *cIdentities) AggregateVotes(p Phase) *bls.Sign {
@ -187,39 +185,32 @@ func (s *cIdentities) IndexOf(pubKey shard.BLSPublicKey) int {
return -1 return -1
} }
func (s *cIdentities) NextAfter(pubKey *bls.PublicKey) (bool, *bls.PublicKey) { func (s *cIdentities) NextAfter(pubKey *shard.BLSPublicKeyWrapper) (bool, *shard.BLSPublicKeyWrapper) {
found := false found := false
pubKeyByte := shard.BLSPublicKey{}
pubKeyByte.FromLibBLSPublicKey(pubKey)
idx := s.IndexOf(pubKeyByte) idx := s.IndexOf(pubKey.Bytes)
if idx != -1 { if idx != -1 {
found = true found = true
} }
idx = (idx + 1) % int(s.ParticipantsCount()) idx = (idx + 1) % int(s.ParticipantsCount())
return found, s.publicKeys[idx] return found, &s.publicKeys[idx]
} }
func (s *cIdentities) Participants() []*bls.PublicKey { func (s *cIdentities) Participants() multibls.PublicKeys {
return s.publicKeys return s.publicKeys
} }
func (s *cIdentities) ParticipantsKeyBytes() []shard.BLSPublicKey {
return s.publicKeysByte
}
func (s *cIdentities) UpdateParticipants(pubKeys []*bls.PublicKey) { func (s *cIdentities) UpdateParticipants(pubKeys []*bls.PublicKey) {
keyBytes := []shard.BLSPublicKey{} keys := make([]shard.BLSPublicKeyWrapper, len(pubKeys))
keyIndexMap := map[shard.BLSPublicKey]int{} keyIndexMap := map[shard.BLSPublicKey]int{}
for i := range pubKeys { for i := range pubKeys {
k := shard.BLSPublicKey{} kBytes := shard.BLSPublicKey{}
k.FromLibBLSPublicKey(pubKeys[i]) kBytes.FromLibBLSPublicKey(pubKeys[i])
keyBytes = append(keyBytes, k) keys[i] = shard.BLSPublicKeyWrapper{Object: pubKeys[i], Bytes: kBytes}
keyIndexMap[k] = i keyIndexMap[kBytes] = i
} }
s.publicKeys = append(pubKeys[:0:0], pubKeys...) s.publicKeys = keys
s.publicKeysByte = keyBytes
s.keyIndexMap = keyIndexMap s.keyIndexMap = keyIndexMap
} }
@ -325,8 +316,7 @@ func (s *cIdentities) ReadAllBallots(p Phase) []*votepower.Ballot {
func newBallotsBackedSignatureReader() *cIdentities { func newBallotsBackedSignatureReader() *cIdentities {
return &cIdentities{ return &cIdentities{
publicKeys: []*bls.PublicKey{}, publicKeys: []shard.BLSPublicKeyWrapper{},
publicKeysByte: []shard.BLSPublicKey{},
keyIndexMap: map[shard.BLSPublicKey]int{}, keyIndexMap: map[shard.BLSPublicKey]int{},
prepare: votepower.NewRound(), prepare: votepower.NewRound(),
commit: votepower.NewRound(), commit: votepower.NewRound(),
@ -340,11 +330,11 @@ type composite struct {
SignatureReader SignatureReader
} }
func (d *depInject) SetMyPublicKeyProvider(p func() (*multibls.PublicKey, error)) { func (d *depInject) SetMyPublicKeyProvider(p func() (multibls.PublicKeys, error)) {
d.publicKeyProvider = p d.publicKeyProvider = p
} }
func (d *depInject) MyPublicKey() func() (*multibls.PublicKey, error) { func (d *depInject) MyPublicKey() func() (multibls.PublicKeys, error) {
return d.publicKeyProvider return d.publicKeyProvider
} }

@ -21,7 +21,7 @@ func (consensus *Consensus) didReachPrepareQuorum() error {
} }
// Construct and broadcast prepared message // Construct and broadcast prepared message
networkMessage, err := consensus.construct( networkMessage, err := consensus.construct(
msg_pb.MessageType_PREPARED, nil, consensus.LeaderPubKey, leaderPriKey, msg_pb.MessageType_PREPARED, nil, consensus.LeaderPubKey.Bytes, leaderPriKey,
) )
if err != nil { if err != nil {
consensus.getLogger().Err(err). consensus.getLogger().Err(err).
@ -50,15 +50,15 @@ func (consensus *Consensus) didReachPrepareQuorum() error {
// so by this point, everyone has committed to the blockhash of this block // so by this point, everyone has committed to the blockhash of this block
// in prepare and so this is the actual block. // in prepare and so this is the actual block.
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if err := consensus.commitBitmap.SetKey(key, true); err != nil { if err := consensus.commitBitmap.SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn().Msgf("[OnPrepare] Leader commit bitmap set failed for key at index %d", i) consensus.getLogger().Warn().Msgf("[OnPrepare] Leader commit bitmap set failed for key at index %d", i)
continue continue
} }
if _, err := consensus.Decider.AddNewVote( if _, err := consensus.Decider.AddNewVote(
quorum.Commit, quorum.Commit,
consensus.PubKey.PublicKeyBytes[i], key.Bytes,
consensus.priKey.PrivateKey[i].SignHash(commitPayload), consensus.priKey.PrivateKey[i].SignHash(commitPayload),
blockObj.Hash(), blockObj.Hash(),
blockObj.NumberU64(), blockObj.NumberU64(),

@ -59,11 +59,11 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
func (consensus *Consensus) prepare() { func (consensus *Consensus) prepare() {
groupID := []nodeconfig.GroupID{nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID))} groupID := []nodeconfig.GroupID{nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID))}
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if !consensus.IsValidatorInCommittee(key) { if !consensus.IsValidatorInCommittee(key.Bytes) {
continue continue
} }
networkMessage, err := consensus.construct(msg_pb.MessageType_PREPARE, nil, key, consensus.priKey.PrivateKey[i]) networkMessage, err := consensus.construct(msg_pb.MessageType_PREPARE, nil, key.Bytes, consensus.priKey.PrivateKey[i])
if err != nil { if err != nil {
consensus.getLogger().Err(err). consensus.getLogger().Err(err).
Str("message-type", msg_pb.MessageType_PREPARE.String()). Str("message-type", msg_pb.MessageType_PREPARE.String()).
@ -210,15 +210,15 @@ func (consensus *Consensus) onPrepared(msg *msg_pb.Message) {
groupID := []nodeconfig.GroupID{ groupID := []nodeconfig.GroupID{
nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID)), nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID)),
} }
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if !consensus.IsValidatorInCommittee(key) { if !consensus.IsValidatorInCommittee(key.Bytes) {
continue continue
} }
networkMessage, _ := consensus.construct( networkMessage, _ := consensus.construct(
msg_pb.MessageType_COMMIT, msg_pb.MessageType_COMMIT,
commitPayload, commitPayload,
key, consensus.priKey.PrivateKey[i], key.Bytes, consensus.priKey.PrivateKey[i],
) )
if consensus.current.Mode() != Listening { if consensus.current.Mode() != Listening {

@ -7,6 +7,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/harmony-one/harmony/shard"
"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"
@ -82,11 +84,11 @@ func (consensus *Consensus) switchPhase(desired FBFTPhase, override bool) {
} }
// GetNextLeaderKey uniquely determine who is the leader for given viewID // GetNextLeaderKey uniquely determine who is the leader for given viewID
func (consensus *Consensus) GetNextLeaderKey() *bls.PublicKey { func (consensus *Consensus) GetNextLeaderKey() *shard.BLSPublicKeyWrapper {
wasFound, next := consensus.Decider.NextAfter(consensus.LeaderPubKey) wasFound, next := consensus.Decider.NextAfter(consensus.LeaderPubKey)
if !wasFound { if !wasFound {
consensus.getLogger().Warn(). consensus.getLogger().Warn().
Str("key", consensus.LeaderPubKey.SerializeToHexStr()). Str("key", consensus.LeaderPubKey.Bytes.Hex()).
Msg("GetNextLeaderKey: currentLeaderKey not found") Msg("GetNextLeaderKey: currentLeaderKey not found")
} }
return next return next
@ -132,14 +134,14 @@ func (consensus *Consensus) startViewChange(viewID uint64) {
consensus.getLogger().Info(). consensus.getLogger().Info().
Uint64("ViewChangingID", viewID). Uint64("ViewChangingID", viewID).
Dur("timeoutDuration", duration). Dur("timeoutDuration", duration).
Str("NextLeader", consensus.LeaderPubKey.SerializeToHexStr()). Str("NextLeader", consensus.LeaderPubKey.Bytes.Hex()).
Msg("[startViewChange]") Msg("[startViewChange]")
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if !consensus.IsValidatorInCommittee(key) { if !consensus.IsValidatorInCommittee(key.Bytes) {
continue continue
} }
msgToSend := consensus.constructViewChangeMessage(key, consensus.priKey.PrivateKey[i]) msgToSend := consensus.constructViewChangeMessage(key.Object, consensus.priKey.PrivateKey[i])
consensus.host.SendMessageToGroups([]nodeconfig.GroupID{ consensus.host.SendMessageToGroups([]nodeconfig.GroupID{
nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID)), nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID)),
}, },
@ -162,7 +164,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
} }
// if not leader, noop // if not leader, noop
newLeaderKey := recvMsg.LeaderPubkey newLeaderKey := recvMsg.LeaderPubkey
newLeaderPriKey, err := consensus.GetLeaderPrivateKey(newLeaderKey) newLeaderPriKey, err := consensus.GetLeaderPrivateKey(newLeaderKey.Object)
if err != nil { if err != nil {
return return
} }
@ -171,7 +173,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Int64("have", consensus.Decider.SignersCount(quorum.ViewChange)). Int64("have", consensus.Decider.SignersCount(quorum.ViewChange)).
Int64("need", consensus.Decider.TwoThirdsSignersCount()). Int64("need", consensus.Decider.TwoThirdsSignersCount()).
Str("validatorPubKey", recvMsg.SenderPubkey.SerializeToHexStr()). Str("validatorPubKey", recvMsg.SenderPubkey.Bytes.Hex()).
Msg("[onViewChange] Received Enough View Change Messages") Msg("[onViewChange] Received Enough View Change Messages")
return return
} }
@ -190,8 +192,8 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
// TODO: remove NIL type message // TODO: remove NIL type message
// add self m1 or m2 type message signature and bitmap // add self m1 or m2 type message signature and bitmap
_, ok1 := consensus.nilSigs[recvMsg.ViewID][newLeaderKey.SerializeToHexStr()] _, ok1 := consensus.nilSigs[recvMsg.ViewID][newLeaderKey.Bytes.Hex()]
_, ok2 := consensus.bhpSigs[recvMsg.ViewID][newLeaderKey.SerializeToHexStr()] _, ok2 := consensus.bhpSigs[recvMsg.ViewID][newLeaderKey.Bytes.Hex()]
if !(ok1 || ok2) { if !(ok1 || ok2) {
// add own signature for newview message // add own signature for newview message
preparedMsgs := consensus.FBFTLog.GetMessagesByTypeSeq( preparedMsgs := consensus.FBFTLog.GetMessagesByTypeSeq(
@ -213,13 +215,13 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
if hasBlock { if hasBlock {
consensus.getLogger().Debug().Msg("[onViewChange] add my M1 type messaage") consensus.getLogger().Debug().Msg("[onViewChange] add my M1 type messaage")
msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...) msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if err := consensus.bhpBitmap[recvMsg.ViewID].SetKey(key, true); err != nil { if err := consensus.bhpBitmap[recvMsg.ViewID].SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn().Msgf("[onViewChange] bhpBitmap setkey failed for key at index %d", i) consensus.getLogger().Warn().Msgf("[onViewChange] bhpBitmap setkey failed for key at index %d", i)
continue continue
} }
priKey := consensus.priKey.PrivateKey[i] priKey := consensus.priKey.PrivateKey[i]
consensus.bhpSigs[recvMsg.ViewID][key.SerializeToHexStr()] = priKey.SignHash(msgToSign) consensus.bhpSigs[recvMsg.ViewID][key.Bytes.Hex()] = priKey.SignHash(msgToSign)
} }
// if m1Payload is empty, we just add one // if m1Payload is empty, we just add one
if len(consensus.m1Payload) == 0 { if len(consensus.m1Payload) == 0 {
@ -227,28 +229,28 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
} }
} else { } else {
consensus.getLogger().Debug().Msg("[onViewChange] add my M2(NIL) type messaage") consensus.getLogger().Debug().Msg("[onViewChange] add my M2(NIL) type messaage")
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if err := consensus.nilBitmap[recvMsg.ViewID].SetKey(key, true); err != nil { if err := consensus.nilBitmap[recvMsg.ViewID].SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn().Msgf("[onViewChange] nilBitmap setkey failed for key at index %d", i) consensus.getLogger().Warn().Msgf("[onViewChange] nilBitmap setkey failed for key at index %d", i)
continue continue
} }
priKey := consensus.priKey.PrivateKey[i] priKey := consensus.priKey.PrivateKey[i]
consensus.nilSigs[recvMsg.ViewID][key.SerializeToHexStr()] = priKey.SignHash(NIL) consensus.nilSigs[recvMsg.ViewID][key.Bytes.Hex()] = priKey.SignHash(NIL)
} }
} }
} }
// add self m3 type message signature and bitmap // add self m3 type message signature and bitmap
_, ok3 := consensus.viewIDSigs[recvMsg.ViewID][newLeaderKey.SerializeToHexStr()] _, ok3 := consensus.viewIDSigs[recvMsg.ViewID][newLeaderKey.Bytes.Hex()]
if !ok3 { if !ok3 {
viewIDBytes := make([]byte, 8) viewIDBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(viewIDBytes, recvMsg.ViewID) binary.LittleEndian.PutUint64(viewIDBytes, recvMsg.ViewID)
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if err := consensus.viewIDBitmap[recvMsg.ViewID].SetKey(key, true); err != nil { if err := consensus.viewIDBitmap[recvMsg.ViewID].SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn().Msgf("[onViewChange] viewIDBitmap setkey failed for key at index %d", i) consensus.getLogger().Warn().Msgf("[onViewChange] viewIDBitmap setkey failed for key at index %d", i)
continue continue
} }
priKey := consensus.priKey.PrivateKey[i] priKey := consensus.priKey.PrivateKey[i]
consensus.viewIDSigs[recvMsg.ViewID][key.SerializeToHexStr()] = priKey.SignHash(viewIDBytes) consensus.viewIDSigs[recvMsg.ViewID][key.Bytes.Hex()] = priKey.SignHash(viewIDBytes)
} }
} }
@ -267,37 +269,37 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
// m2 type message // m2 type message
if !hasBlock { if !hasBlock {
_, ok := consensus.nilSigs[recvMsg.ViewID][senderKey.SerializeToHexStr()] _, ok := consensus.nilSigs[recvMsg.ViewID][senderKey.Bytes.Hex()]
if ok { if ok {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", senderKey.SerializeToHexStr()). Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Already Received M2 message from validator") Msg("[onViewChange] Already Received M2 message from validator")
return return
} }
if !recvMsg.ViewchangeSig.VerifyHash(senderKey, NIL) { if !recvMsg.ViewchangeSig.VerifyHash(senderKey.Object, NIL) {
consensus.getLogger().Warn().Msg("[onViewChange] Failed To Verify Signature For M2 Type Viewchange Message") consensus.getLogger().Warn().Msg("[onViewChange] Failed To Verify Signature For M2 Type Viewchange Message")
return return
} }
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", senderKey.SerializeToHexStr()). Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Add M2 (NIL) type message") Msg("[onViewChange] Add M2 (NIL) type message")
consensus.nilSigs[recvMsg.ViewID][senderKey.SerializeToHexStr()] = recvMsg.ViewchangeSig consensus.nilSigs[recvMsg.ViewID][senderKey.Bytes.Hex()] = recvMsg.ViewchangeSig
consensus.nilBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed. consensus.nilBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Object, true) // Set the bitmap indicating that this validator signed.
} else { // m1 type message } else { // m1 type message
if consensus.BlockVerifier(preparedBlock); err != nil { if consensus.BlockVerifier(preparedBlock); err != nil {
consensus.getLogger().Error().Err(err).Msg("[onViewChange] Prepared block verification failed") consensus.getLogger().Error().Err(err).Msg("[onViewChange] Prepared block verification failed")
return return
} }
_, ok := consensus.bhpSigs[recvMsg.ViewID][senderKey.SerializeToHexStr()] _, ok := consensus.bhpSigs[recvMsg.ViewID][senderKey.Bytes.Hex()]
if ok { if ok {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", senderKey.SerializeToHexStr()). Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Already Received M1 Message From the Validator") Msg("[onViewChange] Already Received M1 Message From the Validator")
return return
} }
if !recvMsg.ViewchangeSig.VerifyHash(recvMsg.SenderPubkey, recvMsg.Payload) { if !recvMsg.ViewchangeSig.VerifyHash(recvMsg.SenderPubkey.Object, recvMsg.Payload) {
consensus.getLogger().Warn().Msg("[onViewChange] Failed to Verify Signature for M1 Type Viewchange Message") consensus.getLogger().Warn().Msg("[onViewChange] Failed to Verify Signature for M1 Type Viewchange Message")
return return
} }
@ -345,7 +347,6 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32) preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32)
copy(preparedMsg.Payload[:], recvMsg.Payload[32:]) copy(preparedMsg.Payload[:], recvMsg.Payload[32:])
preparedMsg.SenderPubkey = newLeaderKey preparedMsg.SenderPubkey = newLeaderKey
copy(preparedMsg.SenderPubkeyBytes[:], newLeaderKey.Serialize())
consensus.getLogger().Info().Msg("[onViewChange] New Leader Prepared Message Added") consensus.getLogger().Info().Msg("[onViewChange] New Leader Prepared Message Added")
consensus.FBFTLog.AddMessage(&preparedMsg) consensus.FBFTLog.AddMessage(&preparedMsg)
@ -353,34 +354,34 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
} }
} }
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", senderKey.SerializeToHexStr()). Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Add M1 (prepared) type message") Msg("[onViewChange] Add M1 (prepared) type message")
consensus.bhpSigs[recvMsg.ViewID][senderKey.SerializeToHexStr()] = recvMsg.ViewchangeSig consensus.bhpSigs[recvMsg.ViewID][senderKey.Bytes.Hex()] = recvMsg.ViewchangeSig
consensus.bhpBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey, true) // Set the bitmap indicating that this validator signed. consensus.bhpBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Object, true) // Set the bitmap indicating that this validator signed.
} }
// check and add viewID (m3 type) message signature // check and add viewID (m3 type) message signature
if _, ok := consensus.viewIDSigs[recvMsg.ViewID][senderKey.SerializeToHexStr()]; ok { if _, ok := consensus.viewIDSigs[recvMsg.ViewID][senderKey.Bytes.Hex()]; ok {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", senderKey.SerializeToHexStr()). Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Already Received M3(ViewID) message from the validator") Msg("[onViewChange] Already Received M3(ViewID) message from the validator")
return return
} }
viewIDHash := make([]byte, 8) viewIDHash := make([]byte, 8)
binary.LittleEndian.PutUint64(viewIDHash, recvMsg.ViewID) binary.LittleEndian.PutUint64(viewIDHash, recvMsg.ViewID)
if !recvMsg.ViewidSig.VerifyHash(recvMsg.SenderPubkey, viewIDHash) { if !recvMsg.ViewidSig.VerifyHash(recvMsg.SenderPubkey.Object, viewIDHash) {
consensus.getLogger().Warn(). consensus.getLogger().Warn().
Uint64("MsgViewID", recvMsg.ViewID). Uint64("MsgViewID", recvMsg.ViewID).
Msg("[onViewChange] Failed to Verify M3 Message Signature") Msg("[onViewChange] Failed to Verify M3 Message Signature")
return return
} }
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("validatorPubKey", senderKey.SerializeToHexStr()). Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Add M3 (ViewID) type message") Msg("[onViewChange] Add M3 (ViewID) type message")
consensus.viewIDSigs[recvMsg.ViewID][senderKey.SerializeToHexStr()] = recvMsg.ViewidSig consensus.viewIDSigs[recvMsg.ViewID][senderKey.Bytes.Hex()] = recvMsg.ViewidSig
// Set the bitmap indicating that this validator signed. // Set the bitmap indicating that this validator signed.
consensus.viewIDBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey, true) consensus.viewIDBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Object, true)
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Int("have", len(consensus.viewIDSigs[recvMsg.ViewID])). Int("have", len(consensus.viewIDSigs[recvMsg.ViewID])).
Int64("total", consensus.Decider.ParticipantsCount()). Int64("total", consensus.Decider.ParticipantsCount()).
@ -423,8 +424,8 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
} }
commitPayload := signature.ConstructCommitPayload(consensus.ChainReader, commitPayload := signature.ConstructCommitPayload(consensus.ChainReader,
block.Epoch(), block.Hash(), block.NumberU64(), block.Header().ViewID().Uint64()) block.Epoch(), block.Hash(), block.NumberU64(), block.Header().ViewID().Uint64())
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if err := consensus.commitBitmap.SetKey(key, true); err != nil { if err := consensus.commitBitmap.SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn(). consensus.getLogger().Warn().
Msgf("[OnViewChange] New Leader commit bitmap set failed for key at index %d", i) Msgf("[OnViewChange] New Leader commit bitmap set failed for key at index %d", i)
continue continue
@ -433,7 +434,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
priKey := consensus.priKey.PrivateKey[i] priKey := consensus.priKey.PrivateKey[i]
if _, err := consensus.Decider.SubmitVote( if _, err := consensus.Decider.SubmitVote(
quorum.Commit, quorum.Commit,
consensus.PubKey.PublicKeyBytes[i], consensus.PubKey[i].Bytes,
priKey.SignHash(commitPayload), priKey.SignHash(commitPayload),
common.BytesToHash(consensus.blockHash[:]), common.BytesToHash(consensus.blockHash[:]),
block.NumberU64(), block.NumberU64(),
@ -448,7 +449,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
consensus.current.SetViewID(recvMsg.ViewID) consensus.current.SetViewID(recvMsg.ViewID)
msgToSend := consensus.constructNewViewMessage( msgToSend := consensus.constructNewViewMessage(
recvMsg.ViewID, newLeaderKey, newLeaderPriKey, recvMsg.ViewID, newLeaderKey.Bytes, newLeaderPriKey,
) )
consensus.getLogger().Warn(). consensus.getLogger().Warn().
@ -474,7 +475,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
Uint64("viewChangingID", consensus.current.ViewID()). Uint64("viewChangingID", consensus.current.ViewID()).
Msg("[onViewChange] New Leader Start Consensus Timer and Stop View Change Timer") Msg("[onViewChange] New Leader Start Consensus Timer and Stop View Change Timer")
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("myKey", newLeaderKey.SerializeToHexStr()). Str("myKey", newLeaderKey.Bytes.Hex()).
Uint64("viewID", consensus.viewID). Uint64("viewID", consensus.viewID).
Uint64("block", consensus.blockNum). Uint64("block", consensus.blockNum).
Msg("[onViewChange] I am the New Leader") Msg("[onViewChange] I am the New Leader")
@ -598,7 +599,6 @@ func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32) preparedMsg.Payload = make([]byte, len(recvMsg.Payload)-32)
copy(preparedMsg.Payload[:], recvMsg.Payload[32:]) copy(preparedMsg.Payload[:], recvMsg.Payload[32:])
preparedMsg.SenderPubkey = senderKey preparedMsg.SenderPubkey = senderKey
preparedMsg.SenderPubkeyBytes = recvMsg.SenderPubkeyBytes
consensus.FBFTLog.AddMessage(&preparedMsg) consensus.FBFTLog.AddMessage(&preparedMsg)
if hasBlock { if hasBlock {
@ -615,7 +615,7 @@ func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
// change view and leaderKey to keep in sync with network // change view and leaderKey to keep in sync with network
if consensus.blockNum != recvMsg.BlockNum { if consensus.blockNum != recvMsg.BlockNum {
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("newLeaderKey", consensus.LeaderPubKey.SerializeToHexStr()). Str("newLeaderKey", consensus.LeaderPubKey.Bytes.Hex()).
Uint64("MsgBlockNum", recvMsg.BlockNum). Uint64("MsgBlockNum", recvMsg.BlockNum).
Msg("[onNewView] New Leader Changed") Msg("[onNewView] New Leader Changed")
return return
@ -628,14 +628,14 @@ func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
preparedBlock.Epoch(), preparedBlock.Hash(), preparedBlock.NumberU64(), preparedBlock.Header().ViewID().Uint64()) preparedBlock.Epoch(), preparedBlock.Hash(), preparedBlock.NumberU64(), preparedBlock.Header().ViewID().Uint64())
groupID := []nodeconfig.GroupID{ groupID := []nodeconfig.GroupID{
nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID))} nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(consensus.ShardID))}
for i, key := range consensus.PubKey.PublicKey { for i, key := range consensus.PubKey {
if !consensus.IsValidatorInCommittee(key) { if !consensus.IsValidatorInCommittee(key.Bytes) {
continue continue
} }
network, err := consensus.construct( network, err := consensus.construct(
msg_pb.MessageType_COMMIT, msg_pb.MessageType_COMMIT,
commitPayload, commitPayload,
key, consensus.priKey.PrivateKey[i], key.Bytes, consensus.priKey.PrivateKey[i],
) )
if err != nil { if err != nil {
consensus.getLogger().Err(err).Msg("could not create commit message") consensus.getLogger().Err(err).Msg("could not create commit message")
@ -658,7 +658,7 @@ func (consensus *Consensus) onNewView(msg *msg_pb.Message) {
consensus.getLogger().Info().Msg("onNewView === announce") consensus.getLogger().Info().Msg("onNewView === announce")
} }
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Str("newLeaderKey", consensus.LeaderPubKey.SerializeToHexStr()). Str("newLeaderKey", consensus.LeaderPubKey.Bytes.Hex()).
Msg("new leader changed") Msg("new leader changed")
consensus.getLogger().Debug(). consensus.getLogger().Debug().
Msg("validator start consensus timer and stop view change timer") Msg("validator start consensus timer and stop view change timer")

@ -836,8 +836,8 @@ func (b *APIBackend) GetNodeMetadata() commonRPC.NodeMetadata {
blsKeys := []string{} blsKeys := []string{}
if cfg.ConsensusPubKey != nil { if cfg.ConsensusPubKey != nil {
for _, key := range cfg.ConsensusPubKey.PublicKey { for _, key := range cfg.ConsensusPubKey {
blsKeys = append(blsKeys, key.SerializeToHexStr()) blsKeys = append(blsKeys, key.Bytes.Hex())
} }
} }
c := commonRPC.C{} c := commonRPC.C{}

@ -209,7 +209,7 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
d := quorum.NewDecider( d := quorum.NewDecider(
quorum.SuperMajorityStake, subComm.ShardID, quorum.SuperMajorityStake, subComm.ShardID,
) )
d.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) { d.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return nil, nil return nil, nil
}) })
@ -524,7 +524,7 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
} }
// TODO(audit): reuse a singleton decider and not recreate it for every single block // TODO(audit): reuse a singleton decider and not recreate it for every single block
d := quorum.NewDecider(quorum.SuperMajorityStake, subComm.ShardID) d := quorum.NewDecider(quorum.SuperMajorityStake, subComm.ShardID)
d.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) { d.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return nil, nil return nil, nil
}) })

@ -77,7 +77,7 @@ type ConfigType struct {
StringRole string StringRole string
P2PPriKey p2p_crypto.PrivKey P2PPriKey p2p_crypto.PrivKey
ConsensusPriKey *multibls.PrivateKey ConsensusPriKey *multibls.PrivateKey
ConsensusPubKey *multibls.PublicKey ConsensusPubKey multibls.PublicKeys
// Database directory // Database directory
DBDir string DBDir string
networkType NetworkType networkType NetworkType
@ -268,15 +268,15 @@ func (conf *ConfigType) ShardIDFromKey(key *bls.PublicKey) (uint32, error) {
// ShardIDFromConsensusKey returns the shard ID statically determined from the // ShardIDFromConsensusKey returns the shard ID statically determined from the
// consensus key. // consensus key.
func (conf *ConfigType) ShardIDFromConsensusKey() (uint32, error) { func (conf *ConfigType) ShardIDFromConsensusKey() (uint32, error) {
return conf.ShardIDFromKey(conf.ConsensusPubKey.PublicKey[0]) return conf.ShardIDFromKey(conf.ConsensusPubKey[0].Object)
} }
// ValidateConsensusKeysForSameShard checks if all consensus public keys belong to the same shard // ValidateConsensusKeysForSameShard checks if all consensus public keys belong to the same shard
func (conf *ConfigType) ValidateConsensusKeysForSameShard(pubkeys []*bls.PublicKey, sID uint32) error { func (conf *ConfigType) ValidateConsensusKeysForSameShard(pubkeys multibls.PublicKeys, sID uint32) error {
keyShardStrs := []string{} keyShardStrs := []string{}
isSameShard := true isSameShard := true
for _, key := range pubkeys { for _, key := range pubkeys {
shardID, err := conf.ShardIDFromKey(key) shardID, err := conf.ShardIDFromKey(key.Object)
if err != nil { if err != nil {
return err return err
} }
@ -285,7 +285,7 @@ func (conf *ConfigType) ValidateConsensusKeysForSameShard(pubkeys []*bls.PublicK
} }
keyShardStrs = append( keyShardStrs = append(
keyShardStrs, keyShardStrs,
fmt.Sprintf("key: %s, shard id: %d", key.SerializeToHexStr(), shardID), fmt.Sprintf("key: %s, shard id: %d", key.Bytes.Hex(), shardID),
) )
} }
if !isSameShard { if !isSameShard {

@ -3,7 +3,9 @@ package nodeconfig
import ( import (
"testing" "testing"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/internal/blsgen" "github.com/harmony-one/harmony/internal/blsgen"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -69,9 +71,13 @@ func TestValidateConsensusKeysForSameShard(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
keys := []*bls.PublicKey{} keys := multibls.PublicKeys{}
keys = append(keys, pubKey1) dummyKey := shard.BLSPublicKey{}
keys = append(keys, pubKey2) dummyKey.FromLibBLSPublicKey(pubKey1)
keys = append(keys, shard.BLSPublicKeyWrapper{Object: pubKey1, Bytes: dummyKey})
dummyKey = shard.BLSPublicKey{}
dummyKey.FromLibBLSPublicKey(pubKey2)
keys = append(keys, shard.BLSPublicKeyWrapper{Object: pubKey2, Bytes: dummyKey})
if err := GetDefaultConfig().ValidateConsensusKeysForSameShard(keys, 0); err != nil { if err := GetDefaultConfig().ValidateConsensusKeysForSameShard(keys, 0); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -82,7 +88,9 @@ func TestValidateConsensusKeysForSameShard(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
keys = append(keys, pubKey3) dummyKey = shard.BLSPublicKey{}
dummyKey.FromLibBLSPublicKey(pubKey3)
keys = append(keys, shard.BLSPublicKeyWrapper{Object: pubKey3, Bytes: dummyKey})
if err := GetDefaultConfig().ValidateConsensusKeysForSameShard(keys, 0); err == nil { if err := GetDefaultConfig().ValidateConsensusKeysForSameShard(keys, 0); err == nil {
e := errors.New("bls keys do not belong to the same shard") e := errors.New("bls keys do not belong to the same shard")
t.Error("expected", e, "got", nil) t.Error("expected", e, "got", nil)

@ -13,28 +13,25 @@ type PrivateKey struct {
PrivateKey []*bls.SecretKey PrivateKey []*bls.SecretKey
} }
// PublicKey stores the bls public keys that belongs to the node // PublicKeys stores the bls public keys that belongs to the node
type PublicKey struct { type PublicKeys []shard.BLSPublicKeyWrapper
PublicKey []*bls.PublicKey
PublicKeyBytes []shard.BLSPublicKey
}
// SerializeToHexStr wrapper // SerializeToHexStr wrapper
func (multiKey *PublicKey) SerializeToHexStr() string { func (multiKey PublicKeys) SerializeToHexStr() string {
if multiKey == nil { if multiKey == nil {
return "" return ""
} }
var builder strings.Builder var builder strings.Builder
for _, pubKey := range multiKey.PublicKey { for _, pubKey := range multiKey {
builder.WriteString(pubKey.SerializeToHexStr() + ";") builder.WriteString(pubKey.Bytes.Hex() + ";")
} }
return builder.String() return builder.String()
} }
// Contains wrapper // Contains wrapper
func (multiKey PublicKey) Contains(pubKey *bls.PublicKey) bool { func (multiKey PublicKeys) Contains(pubKey *bls.PublicKey) bool {
for _, key := range multiKey.PublicKey { for _, key := range multiKey {
if key.IsEqual(pubKey) { if key.Object.IsEqual(pubKey) {
return true return true
} }
} }
@ -42,15 +39,15 @@ func (multiKey PublicKey) Contains(pubKey *bls.PublicKey) bool {
} }
// GetPublicKey wrapper // GetPublicKey wrapper
func (multiKey PrivateKey) GetPublicKey() *PublicKey { func (multiKey PrivateKey) GetPublicKey() PublicKeys {
pubKeys := make([]*bls.PublicKey, len(multiKey.PrivateKey)) pubKeys := make([]shard.BLSPublicKeyWrapper, len(multiKey.PrivateKey))
pubKeysBytes := make([]shard.BLSPublicKey, len(multiKey.PrivateKey))
for i, key := range multiKey.PrivateKey { for i, key := range multiKey.PrivateKey {
pubKeys[i] = key.GetPublicKey() wrapper := shard.BLSPublicKeyWrapper{Object: key.GetPublicKey()}
pubKeysBytes[i].FromLibBLSPublicKey(pubKeys[i]) wrapper.Bytes.FromLibBLSPublicKey(wrapper.Object)
pubKeys[i] = wrapper
} }
return &PublicKey{PublicKey: pubKeys, PublicKeyBytes: pubKeysBytes} return pubKeys
} }
// GetPrivateKey creates a multibls PrivateKey using bls.SecretKey // GetPrivateKey creates a multibls PrivateKey using bls.SecretKey
@ -58,18 +55,11 @@ func GetPrivateKey(key *bls.SecretKey) *PrivateKey {
return &PrivateKey{PrivateKey: []*bls.SecretKey{key}} return &PrivateKey{PrivateKey: []*bls.SecretKey{key}}
} }
// GetPublicKey creates a multibls PublicKey using bls.PublicKey // GetPublicKey creates a multibls PublicKeys using bls.PublicKeys
func GetPublicKey(key *bls.PublicKey) *PublicKey { func GetPublicKey(key *bls.PublicKey) PublicKeys {
return &PublicKey{PublicKey: []*bls.PublicKey{key}} keyBytes := shard.BLSPublicKey{}
} keyBytes.FromLibBLSPublicKey(key)
return PublicKeys{shard.BLSPublicKeyWrapper{Object: key, Bytes: keyBytes}}
// AppendPubKey appends a PublicKey to multibls PublicKey
func AppendPubKey(multiKey *PublicKey, key *bls.PublicKey) {
if multiKey != nil {
multiKey.PublicKey = append(multiKey.PublicKey, key)
} else {
multiKey = &PublicKey{PublicKey: []*bls.PublicKey{key}}
}
} }
// AppendPriKey appends a SecretKey to multibls PrivateKey // AppendPriKey appends a SecretKey to multibls PrivateKey

@ -683,9 +683,9 @@ func (node *Node) populateSelfAddresses(epoch *big.Int) {
return return
} }
for _, blskey := range node.Consensus.PubKey.PublicKey { for _, blskey := range node.Consensus.PubKey {
blsStr := blskey.SerializeToHexStr() blsStr := blskey.Bytes.Hex()
shardkey := shard.FromLibBLSPublicKeyUnsafe(blskey) shardkey := shard.FromLibBLSPublicKeyUnsafe(blskey.Object)
if shardkey == nil { if shardkey == nil {
utils.Logger().Error(). utils.Logger().Error().
Int64("epoch", epoch.Int64()). Int64("epoch", epoch.Int64()).

@ -185,7 +185,7 @@ func (node *Node) lookupDecider(
quorum.SuperMajorityStake, committee.ShardID, quorum.SuperMajorityStake, committee.ShardID,
) )
decider.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) { decider.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return nil, nil return nil, nil
}) })

@ -6,6 +6,8 @@ import (
"math/rand" "math/rand"
"time" "time"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
proto_node "github.com/harmony-one/harmony/api/proto/node" proto_node "github.com/harmony-one/harmony/api/proto/node"
@ -397,8 +399,13 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
func (node *Node) numSignaturesIncludedInBlock(block *types.Block) uint32 { func (node *Node) numSignaturesIncludedInBlock(block *types.Block) uint32 {
count := uint32(0) count := uint32(0)
pubkeys := node.Consensus.Decider.Participants() members := node.Consensus.Decider.Participants()
mask, err := internal_bls.NewMask(pubkeys, nil) publicKeys := []*bls.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
// TODO(audit): do not reconstruct the Mask
mask, err := internal_bls.NewMask(publicKeys, nil)
if err != nil { if err != nil {
return count return count
} }
@ -406,8 +413,8 @@ func (node *Node) numSignaturesIncludedInBlock(block *types.Block) uint32 {
if err != nil { if err != nil {
return count return count
} }
for _, key := range node.Consensus.PubKey.PublicKey { for _, key := range node.Consensus.PubKey {
if ok, err := mask.KeyEnabled(key); err == nil && ok { if ok, err := mask.KeyEnabled(key.Object); err == nil && ok {
count++ count++
} }
} }

@ -89,14 +89,14 @@ func (node *Node) proposeNewBlock() (*types.Block, error) {
// Update worker's current header and // Update worker's current header and
// state data in preparation to propose/process new transactions // state data in preparation to propose/process new transactions
var ( var (
coinbase = node.GetAddressForBLSKey(node.Consensus.LeaderPubKey, header.Epoch()) coinbase = node.GetAddressForBLSKey(node.Consensus.LeaderPubKey.Object, header.Epoch())
beneficiary = coinbase beneficiary = coinbase
err error err error
) )
// After staking, all coinbase will be the address of bls pub key // After staking, all coinbase will be the address of bls pub key
if node.Blockchain().Config().IsStaking(header.Epoch()) { if node.Blockchain().Config().IsStaking(header.Epoch()) {
blsPubKeyBytes := node.Consensus.LeaderPubKey.GetAddress() blsPubKeyBytes := node.Consensus.LeaderPubKey.Object.GetAddress()
coinbase.SetBytes(blsPubKeyBytes[:]) coinbase.SetBytes(blsPubKeyBytes[:])
} }

@ -37,8 +37,14 @@ type State struct {
Shards []Committee `json:"shards"` Shards []Committee `json:"shards"`
} }
// BLSPublicKey defines the bls public key // BLSPublicKeyWrapper defines the bls public key in both serialized and
// TODO(audit): wrap c bls key object with the raw bytes // deserialized form.
type BLSPublicKeyWrapper struct {
Bytes BLSPublicKey
Object *bls.PublicKey
}
// BLSPublicKey defines the serialized bls public key
type BLSPublicKey [PublicKeySizeInBytes]byte type BLSPublicKey [PublicKeySizeInBytes]byte
// BLSSignature defines the bls signature // BLSSignature defines the bls signature

Loading…
Cancel
Save