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

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

@ -14,6 +14,7 @@ import (
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/slash"
"github.com/pkg/errors"
)
@ -76,9 +77,9 @@ type Consensus struct {
pubKeyLock sync.Mutex
// private/public keys of current node
priKey *multibls.PrivateKey
PubKey *multibls.PublicKey
PubKey multibls.PublicKeys
// the publickey of leader
LeaderPubKey *bls.PublicKey
LeaderPubKey *shard.BLSPublicKeyWrapper
viewID uint64
// 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
func (consensus *Consensus) GetLeaderPrivateKey(leaderKey *bls.PublicKey) (*bls.SecretKey, error) {
for i, key := range consensus.PubKey.PublicKey {
if key.IsEqual(leaderKey) {
for i, key := range consensus.PubKey {
if key.Object.IsEqual(leaderKey) {
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
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

@ -84,9 +84,13 @@ func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls.PublicKey) int64 {
Str("BLSPubKey", pubKeys[i].SerializeToHexStr()).
Msg("Member")
}
consensus.LeaderPubKey = pubKeys[0]
utils.Logger().Info().
Str("info", consensus.LeaderPubKey.SerializeToHexStr()).Msg("My Leader")
allKeys := consensus.Decider.Participants()
if len(allKeys) != 0 {
consensus.LeaderPubKey = &allKeys[0]
utils.Logger().Info().
Str("info", consensus.LeaderPubKey.Bytes.Hex()).Msg("My Leader")
}
consensus.pubKeyLock.Unlock()
// reset states after update public keys
consensus.ResetState()
@ -150,8 +154,12 @@ func (consensus *Consensus) ResetState() {
consensus.block = []byte{}
consensus.Decider.ResetPrepareAndCommitVotes()
members := consensus.Decider.Participants()
prepareBitmap, _ := bls_cosi.NewMask(members, nil)
commitBitmap, _ := bls_cosi.NewMask(members, nil)
publicKeys := []*bls.PublicKey{}
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.commitBitmap = commitBitmap
consensus.aggregatedPrepareSig = nil
@ -164,12 +172,8 @@ 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
func (consensus *Consensus) IsValidatorInCommittee(pubKey shard.BLSPublicKey) bool {
return consensus.Decider.IndexOf(pubKey) != -1
}
// 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
}
func (consensus *Consensus) verifyViewChangeSenderKey(msg *msg_pb.Message) (*bls.PublicKey, error) {
func (consensus *Consensus) verifyViewChangeSenderKey(msg *msg_pb.Message) error {
vcMsg := msg.GetViewchange()
senderKey, err := bls_cosi.BytesToBLSPublicKey(vcMsg.SenderPubkey)
if err != nil {
return nil, err
}
senderKey := shard.BLSPublicKey{}
copy(senderKey[:], vcMsg.SenderPubkey)
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
@ -263,7 +265,7 @@ func (consensus *Consensus) checkViewID(msg *FBFTMessage) error {
consensus.consensusTimeout[timeoutConsensus].Start()
utils.Logger().Debug().
Uint64("viewID", consensus.viewID).
Str("leaderKey", consensus.LeaderPubKey.SerializeToHexStr()[:20]).
Str("leaderKey", consensus.LeaderPubKey.Bytes.Hex()).
Msg("viewID and leaderKey override")
utils.Logger().Debug().
Uint64("viewID", consensus.viewID).
@ -291,8 +293,15 @@ func (consensus *Consensus) ReadSignatureBitmapPayload(
return nil, nil, errors.New("payload not have enough length")
}
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(
sigAndBitmapPayload, consensus.Decider.Participants(),
sigAndBitmapPayload, publicKeys,
)
}
@ -310,7 +319,7 @@ func (consensus *Consensus) getLogger() *zerolog.Logger {
// retrieve corresponding blsPublicKey from Coinbase Address
func (consensus *Consensus) getLeaderPubKeyFromCoinbase(
header *block.Header,
) (*bls.PublicKey, error) {
) (*shard.BLSPublicKeyWrapper, error) {
shardState, err := consensus.ChainReader.ReadShardState(header.Epoch())
if err != nil {
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 {
return nil, err
}
return committerKey, nil
return &shard.BLSPublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil
}
} else {
if member.EcdsaAddress == header.Coinbase() {
if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil {
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
if isFirstTimeStaking || haventUpdatedDecider {
decider := quorum.NewDecider(quorum.SuperMajorityStake, consensus.ShardID)
decider.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) {
decider.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return consensus.PubKey, nil
})
consensus.Decider = decider
@ -487,7 +496,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
hasError = true
} else {
consensus.getLogger().Debug().
Str("leaderPubKey", leaderPubKey.SerializeToHexStr()).
Str("leaderPubKey", leaderPubKey.Bytes.Hex()).
Msg("[UpdateConsensusInformation] Most Recent LeaderPubKey Updated Based on BlockChain")
consensus.LeaderPubKey = leaderPubKey
}
@ -501,7 +510,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
}
// 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() {
utils.Logger().Debug().
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
// the node with the leader public key
func (consensus *Consensus) IsLeader() bool {
for _, key := range consensus.PubKey.PublicKey {
if key.IsEqual(consensus.LeaderPubKey) {
for _, key := range consensus.PubKey {
if key.Object.IsEqual(consensus.LeaderPubKey.Object) {
return true
}
}
@ -540,6 +549,10 @@ func (consensus *Consensus) NeedsRandomNumberGeneration(epoch *big.Int) bool {
func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) {
members := consensus.Decider.Participants()
publicKeys := []*bls.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
if _, ok := consensus.bhpSigs[viewID]; !ok {
consensus.bhpSigs[viewID] = map[string]*bls.Sign{}
}
@ -550,15 +563,15 @@ func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) {
consensus.viewIDSigs[viewID] = map[string]*bls.Sign{}
}
if _, ok := consensus.bhpBitmap[viewID]; !ok {
bhpBitmap, _ := bls_cosi.NewMask(members, nil)
bhpBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
consensus.bhpBitmap[viewID] = bhpBitmap
}
if _, ok := consensus.nilBitmap[viewID]; !ok {
nilBitmap, _ := bls_cosi.NewMask(members, nil)
nilBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
consensus.nilBitmap[viewID] = nilBitmap
}
if _, ok := consensus.viewIDBitmap[viewID]; !ok {
viewIDBitmap, _ := bls_cosi.NewMask(members, nil)
viewIDBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
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[:],
blsPriKey.GetPublicKey())
keyBytes)
if consensusMsg.ViewId != 2 {
t.Errorf("Consensus ID is not populated correctly")

@ -107,7 +107,10 @@ func (consensus *Consensus) finalizeCommits() {
return
}
// 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 {
consensus.getLogger().Warn().Err(err).
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
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
previousHeader := consensus.ChainReader.GetHeaderByNumber(
headerObj.Number().Uint64() - 1,

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

@ -3,6 +3,8 @@ package consensus
import (
"bytes"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/proto"
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.
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 {
request.ViewId = consensus.viewID
request.BlockNum = consensus.blockNum
@ -30,13 +32,13 @@ func (consensus *Consensus) populateMessageFields(
// 32 byte block hash
request.BlockHash = blockHash
// sender address
request.SenderPubkey = pubKey.Serialize()
request.SenderPubkey = pubKey[:]
return request
}
// construct is the single creation point of messages intended for the wire.
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) {
message := &msg_pb.Message{
ServiceType: msg_pb.ServiceType_CONSENSUS,

@ -32,7 +32,9 @@ func TestConstructAnnounceMessage(test *testing.T) {
test.Fatalf("Cannot create consensus: %v", err)
}
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)
}
}
@ -94,7 +96,9 @@ func TestConstructPreparedMessage(test *testing.T) {
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 {
test.Errorf("Error when creating prepared message")
}

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

@ -23,21 +23,20 @@ type FBFTLog struct {
// FBFTMessage is the record of pbft messages received by a node during FBFT process
type FBFTMessage struct {
MessageType msg_pb.MessageType
ViewID uint64
BlockNum uint64
BlockHash common.Hash
Block []byte
SenderPubkey *bls.PublicKey
SenderPubkeyBytes shard.BLSPublicKey
LeaderPubkey *bls.PublicKey
Payload []byte
ViewchangeSig *bls.Sign
ViewidSig *bls.Sign
M2AggSig *bls.Sign
M2Bitmap *bls_cosi.Mask
M3AggSig *bls.Sign
M3Bitmap *bls_cosi.Mask
MessageType msg_pb.MessageType
ViewID uint64
BlockNum uint64
BlockHash common.Hash
Block []byte
SenderPubkey *shard.BLSPublicKeyWrapper
LeaderPubkey *shard.BLSPublicKeyWrapper
Payload []byte
ViewchangeSig *bls.Sign
ViewidSig *bls.Sign
M2AggSig *bls.Sign
M2Bitmap *bls_cosi.Mask
M3AggSig *bls.Sign
M3Bitmap *bls_cosi.Mask
}
// String ..
@ -48,8 +47,8 @@ func (m *FBFTMessage) String() string {
m.ViewID,
m.BlockNum,
m.BlockHash.Hex(),
m.SenderPubkeyBytes.Hex(),
m.LeaderPubkey.SerializeToHexStr(),
m.SenderPubkey.Bytes.Hex(),
m.LeaderPubkey.Bytes.Hex(),
)
}
@ -250,8 +249,8 @@ func ParseFBFTMessage(msg *msg_pb.Message) (*FBFTMessage, error) {
if err != nil {
return nil, err
}
pbftMsg.SenderPubkey = pubKey
copy(pbftMsg.SenderPubkeyBytes[:], consensusMsg.SenderPubkey[:])
pbftMsg.SenderPubkey = &shard.BLSPublicKeyWrapper{Object: pubKey}
copy(pbftMsg.SenderPubkey.Bytes[:], consensusMsg.SenderPubkey[:])
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")
return nil, err
}
pbftMsg.SenderPubkey = pubKey
copy(pbftMsg.SenderPubkeyBytes[:], vcMsg.SenderPubkey[:])
pbftMsg.LeaderPubkey = leaderKey
pbftMsg.SenderPubkey = &shard.BLSPublicKeyWrapper{Object: pubKey}
copy(pbftMsg.SenderPubkey.Bytes[:], vcMsg.SenderPubkey[:])
pbftMsg.LeaderPubkey = &shard.BLSPublicKeyWrapper{Object: leaderKey}
copy(pbftMsg.LeaderPubkey.Bytes[:], vcMsg.LeaderPubkey[:])
pbftMsg.ViewchangeSig = &vcSig
pbftMsg.ViewidSig = &vcSig1
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")
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 {
m3Sig := bls.Sign{}
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")
return nil, err
}
m3mask, err := bls_cosi.NewMask(consensus.Decider.Participants(), nil)
m3mask, err := bls_cosi.NewMask(publicKeys, nil)
if err != nil {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature")
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")
return nil, err
}
m2mask, err := bls_cosi.NewMask(consensus.Decider.Participants(), nil)
m2mask, err := bls_cosi.NewMask(publicKeys, nil)
if err != nil {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature")
return nil, err

@ -3,6 +3,8 @@ package consensus
import (
"time"
"github.com/harmony-one/harmony/shard"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls"
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")
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 {
consensus.getLogger().Err(err).
Str("message-type", msg_pb.MessageType_ANNOUNCE.String()).
@ -56,8 +62,8 @@ func (consensus *Consensus) announce(block *types.Block) {
consensus.FBFTLog.AddBlock(block)
// Leader sign the block hash itself
for i, key := range consensus.PubKey.PublicKey {
if err := consensus.prepareBitmap.SetKey(key, true); err != nil {
for i, key := range consensus.PubKey {
if err := consensus.prepareBitmap.SetKey(key.Object, true); err != nil {
consensus.getLogger().Warn().Err(err).Msgf(
"[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(
quorum.Prepare,
consensus.PubKey.PublicKeyBytes[i],
key.Bytes,
consensus.priKey.PrivateKey[i].SignHash(consensus.blockHash[:]),
block.Hash(),
block.NumberU64(),
@ -132,10 +138,10 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
consensus.mutex.Lock()
defer consensus.mutex.Unlock()
// 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 {
consensus.getLogger().Debug().
Str("validatorPubKey", recvMsg.SenderPubkeyBytes.Hex()).
Str("validatorPubKey", recvMsg.SenderPubkey.Bytes.Hex()).
Msg("[OnPrepare] Already Received prepare message from the validator")
return
}
@ -143,7 +149,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
if consensus.Decider.IsQuorumAchieved(quorum.Prepare) {
// already have enough signatures
consensus.getLogger().Debug().
Str("validatorPubKey", recvMsg.SenderPubkeyBytes.Hex()).
Str("validatorPubKey", recvMsg.SenderPubkey.Bytes.Hex()).
Msg("[OnPrepare] Received Additional Prepare Message")
return
}
@ -156,7 +162,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
Msg("[OnPrepare] Failed to deserialize bls signature")
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")
return
}
@ -166,7 +172,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
Int64("PublicKeys", consensus.Decider.ParticipantsCount()).
Msg("[OnPrepare] Received New Prepare Signature")
if _, err := consensus.Decider.AddNewVote(
quorum.Prepare, recvMsg.SenderPubkeyBytes,
quorum.Prepare, recvMsg.SenderPubkey.Bytes,
&sign, recvMsg.BlockHash,
recvMsg.BlockNum, recvMsg.ViewID,
); err != nil {
@ -174,7 +180,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
return
}
// 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")
return
}
@ -211,7 +217,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
validatorPubKey, commitSig, commitBitmap :=
recvMsg.SenderPubkey, recvMsg.Payload, consensus.commitBitmap
logger := consensus.getLogger().With().
Str("validatorPubKey", validatorPubKey.SerializeToHexStr()).Logger()
Str("validatorPubKey", validatorPubKey.Bytes.Hex()).Logger()
// has to be called before verifying signature
quorumWasMet := consensus.Decider.IsQuorumAchieved(quorum.Commit)
@ -238,7 +244,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
Uint64("MsgBlockNum", recvMsg.BlockNum).
Logger()
if !sign.VerifyHash(recvMsg.SenderPubkey, commitPayload) {
if !sign.VerifyHash(recvMsg.SenderPubkey.Object, commitPayload) {
logger.Error().Msg("[OnCommit] Cannot verify commit message")
return
}
@ -249,14 +255,14 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
logger.Debug().Msg("[OnCommit] Received new commit message")
if _, err := consensus.Decider.AddNewVote(
quorum.Commit, recvMsg.SenderPubkeyBytes,
quorum.Commit, recvMsg.SenderPubkey.Bytes,
&sign, recvMsg.BlockHash,
recvMsg.BlockNum, recvMsg.ViewID,
); err != nil {
return
}
// 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).
Msg("[OnCommit] commitBitmap.SetKey failed")
return

@ -91,7 +91,7 @@ func (v *uniformVoteWeight) MarshalJSON() ([]byte, error) {
keysDump := v.Participants()
keys := make([]string, len(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})
@ -104,9 +104,9 @@ func (v *uniformVoteWeight) AmIMemberOfCommitee() bool {
}
identity, _ := pubKeyFunc()
everyone := v.Participants()
for _, key := range identity.PublicKey {
for _, key := range identity {
for i := range everyone {
if key.IsEqual(everyone[i]) {
if key.Object.IsEqual(everyone[i].Object) {
return true
}
}

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

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

@ -21,7 +21,7 @@ func (consensus *Consensus) didReachPrepareQuorum() error {
}
// Construct and broadcast prepared message
networkMessage, err := consensus.construct(
msg_pb.MessageType_PREPARED, nil, consensus.LeaderPubKey, leaderPriKey,
msg_pb.MessageType_PREPARED, nil, consensus.LeaderPubKey.Bytes, leaderPriKey,
)
if err != nil {
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
// in prepare and so this is the actual block.
for i, key := range consensus.PubKey.PublicKey {
if err := consensus.commitBitmap.SetKey(key, true); err != nil {
for i, key := range consensus.PubKey {
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)
continue
}
if _, err := consensus.Decider.AddNewVote(
quorum.Commit,
consensus.PubKey.PublicKeyBytes[i],
key.Bytes,
consensus.priKey.PrivateKey[i].SignHash(commitPayload),
blockObj.Hash(),
blockObj.NumberU64(),

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

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

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

@ -209,7 +209,7 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
d := quorum.NewDecider(
quorum.SuperMajorityStake, subComm.ShardID,
)
d.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) {
d.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
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
d := quorum.NewDecider(quorum.SuperMajorityStake, subComm.ShardID)
d.SetMyPublicKeyProvider(func() (*multibls.PublicKey, error) {
d.SetMyPublicKeyProvider(func() (multibls.PublicKeys, error) {
return nil, nil
})

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

@ -3,7 +3,9 @@ package nodeconfig
import (
"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"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
"github.com/pkg/errors"
@ -69,9 +71,13 @@ func TestValidateConsensusKeysForSameShard(t *testing.T) {
if err != nil {
t.Error(err)
}
keys := []*bls.PublicKey{}
keys = append(keys, pubKey1)
keys = append(keys, pubKey2)
keys := multibls.PublicKeys{}
dummyKey := shard.BLSPublicKey{}
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 {
t.Error("expected", nil, "got", err)
}
@ -82,7 +88,9 @@ func TestValidateConsensusKeysForSameShard(t *testing.T) {
if err != nil {
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 {
e := errors.New("bls keys do not belong to the same shard")
t.Error("expected", e, "got", nil)

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

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

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

@ -6,6 +6,8 @@ import (
"math/rand"
"time"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/api/proto"
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 {
count := uint32(0)
pubkeys := node.Consensus.Decider.Participants()
mask, err := internal_bls.NewMask(pubkeys, nil)
members := node.Consensus.Decider.Participants()
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 {
return count
}
@ -406,8 +413,8 @@ func (node *Node) numSignaturesIncludedInBlock(block *types.Block) uint32 {
if err != nil {
return count
}
for _, key := range node.Consensus.PubKey.PublicKey {
if ok, err := mask.KeyEnabled(key); err == nil && ok {
for _, key := range node.Consensus.PubKey {
if ok, err := mask.KeyEnabled(key.Object); err == nil && ok {
count++
}
}

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

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

Loading…
Cancel
Save