Optimize bls Mask infra to avoid loops (#3243)

pull/3245/head
Rongjian Lan 4 years ago committed by GitHub
parent 109348b450
commit a354b93676
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      consensus/consensus_service.go
  2. 4
      consensus/construct_test.go
  3. 8
      consensus/fbft_log.go
  4. 6
      consensus/leader.go
  5. 11
      consensus/quorum/one-node-staked-vote.go
  6. 12
      consensus/quorum/one-node-staked-vote_test.go
  7. 7
      consensus/quorum/quorom_test.go
  8. 13
      consensus/quorum/quorum.go
  9. 2
      consensus/threshold.go
  10. 14
      consensus/view_change.go
  11. 10
      consensus/view_change_test.go
  12. 41
      crypto/bls/mask.go
  13. 100
      crypto/bls/mask_test.go
  14. 8
      hmy/api_backend.go
  15. 7
      internal/chain/engine.go
  16. 2
      internal/chain/sig.go
  17. 21
      internal/hmyapi/apiv1/blockchain.go
  18. 21
      internal/hmyapi/apiv2/blockchain.go
  19. 2
      node/node.go
  20. 10
      node/node_handler.go
  21. 7
      shard/shard_state.go

@ -76,7 +76,7 @@ func (consensus *Consensus) GetViewID() uint64 {
// UpdatePublicKeys updates the PublicKeys for
// quorum on current subcommittee, protected by a mutex
func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls_core.PublicKey) int64 {
func (consensus *Consensus) UpdatePublicKeys(pubKeys []bls_cosi.PublicKeyWrapper) int64 {
// TODO: use mutex for updating public keys pointer. No need to lock on all these logic.
consensus.pubKeyLock.Lock()
consensus.Decider.UpdateParticipants(pubKeys)
@ -84,7 +84,7 @@ func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls_core.PublicKey) int6
for i := range pubKeys {
utils.Logger().Debug().
Int("index", i).
Str("BLSPubKey", pubKeys[i].SerializeToHexStr()).
Str("BLSPubKey", pubKeys[i].Bytes.Hex()).
Msg("Member")
}
@ -155,12 +155,8 @@ func (consensus *Consensus) UpdateBitmaps() {
Str("Phase", consensus.phase.String()).
Msg("[UpdateBitmaps] Updating consensus bitmaps")
members := consensus.Decider.Participants()
publicKeys := []*bls_core.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
prepareBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
commitBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
prepareBitmap, _ := bls_cosi.NewMask(members, nil)
commitBitmap, _ := bls_cosi.NewMask(members, nil)
consensus.prepareBitmap = prepareBitmap
consensus.commitBitmap = commitBitmap
}
@ -265,12 +261,8 @@ func (consensus *Consensus) ReadSignatureBitmapPayload(
// TODO(audit): keep a Mask in the Decider so it won't be reconstructed on the fly.
members := consensus.Decider.Participants()
publicKeys := []*bls_core.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
return chain.ReadSignatureBitmapByPublicKeys(
sigAndBitmapPayload, publicKeys,
sigAndBitmapPayload, members,
)
}
@ -474,7 +466,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode {
for _, key := range pubKeys {
// in committee
myPubKeys := consensus.GetPublicKeys()
if myPubKeys.Contains(key) {
if myPubKeys.Contains(key.Object) {
if hasError {
return Syncing
}
@ -520,10 +512,6 @@ func (consensus *Consensus) NeedsRandomNumberGeneration(epoch *big.Int) bool {
func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) {
members := consensus.Decider.Participants()
publicKeys := []*bls_core.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
if _, ok := consensus.bhpSigs[viewID]; !ok {
consensus.bhpSigs[viewID] = map[string]*bls_core.Sign{}
}
@ -534,15 +522,15 @@ func (consensus *Consensus) addViewIDKeyIfNotExist(viewID uint64) {
consensus.viewIDSigs[viewID] = map[string]*bls_core.Sign{}
}
if _, ok := consensus.bhpBitmap[viewID]; !ok {
bhpBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
bhpBitmap, _ := bls_cosi.NewMask(members, nil)
consensus.bhpBitmap[viewID] = bhpBitmap
}
if _, ok := consensus.nilBitmap[viewID]; !ok {
nilBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
nilBitmap, _ := bls_cosi.NewMask(members, nil)
consensus.nilBitmap[viewID] = nilBitmap
}
if _, ok := consensus.viewIDBitmap[viewID]; !ok {
viewIDBitmap, _ := bls_cosi.NewMask(publicKeys, nil)
viewIDBitmap, _ := bls_cosi.NewMask(members, nil)
consensus.viewIDBitmap[viewID] = viewIDBitmap
}
}

@ -91,10 +91,10 @@ func TestConstructPreparedMessage(test *testing.T) {
}
// According to RJ these failures are benign.
if err := consensus.prepareBitmap.SetKey(leaderPubKey, true); err != nil {
if err := consensus.prepareBitmap.SetKey(leaderKey, true); err != nil {
test.Log(errors.New("prepareBitmap.SetKey"))
}
if err := consensus.prepareBitmap.SetKey(validatorPubKey, true); err != nil {
if err := consensus.prepareBitmap.SetKey(validatorKey, true); err != nil {
test.Log(errors.New("prepareBitmap.SetKey"))
}

@ -340,10 +340,6 @@ func (consensus *Consensus) ParseNewViewMessage(msg *msg_pb.Message) (*FBFTMessa
copy(FBFTMsg.SenderPubkey.Bytes[:], vcMsg.SenderPubkey[:])
members := consensus.Decider.Participants()
publicKeys := []*bls_core.PublicKey{}
for _, key := range members {
publicKeys = append(publicKeys, key.Object)
}
if len(vcMsg.M3Aggsigs) > 0 {
m3Sig := bls_core.Sign{}
err = m3Sig.Deserialize(vcMsg.M3Aggsigs)
@ -351,7 +347,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(publicKeys, nil)
m3mask, err := bls_cosi.NewMask(members, nil)
if err != nil {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature")
return nil, err
@ -368,7 +364,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(publicKeys, nil)
m2mask, err := bls_cosi.NewMask(members, nil)
if err != nil {
utils.Logger().Warn().Err(err).Msg("ParseViewChangeMessage failed to create mask for multi signature")
return nil, err

@ -60,7 +60,7 @@ func (consensus *Consensus) announce(block *types.Block) {
// Leader sign the block hash itself
for i, key := range consensus.priKey {
if err := consensus.prepareBitmap.SetKey(key.Pub.Object, true); err != nil {
if err := consensus.prepareBitmap.SetKey(key.Pub.Bytes, true); err != nil {
consensus.getLogger().Warn().Err(err).Msgf(
"[Announce] Leader prepareBitmap SetKey failed for key at index %d", i,
)
@ -191,7 +191,7 @@ func (consensus *Consensus) onPrepare(msg *msg_pb.Message) {
return
}
// Set the bitmap indicating that this validator signed.
if err := prepareBitmap.SetKey(recvMsg.SenderPubkey.Object, true); err != nil {
if err := prepareBitmap.SetKey(recvMsg.SenderPubkey.Bytes, true); err != nil {
consensus.prepareMutex.Unlock()
consensus.getLogger().Warn().Err(err).Msg("[OnPrepare] prepareBitmap.SetKey failed")
return
@ -295,7 +295,7 @@ func (consensus *Consensus) onCommit(msg *msg_pb.Message) {
return
}
// Set the bitmap indicating that this validator signed.
if err := commitBitmap.SetKey(recvMsg.SenderPubkey.Object, true); err != nil {
if err := commitBitmap.SetKey(recvMsg.SenderPubkey.Bytes, true); err != nil {
consensus.commitMutex.Unlock()
consensus.getLogger().Warn().Err(err).
Msg("[OnCommit] commitBitmap.SetKey failed")

@ -144,17 +144,12 @@ func (v *stakedVoteWeight) currentTotalPower(p Phase) (*numeric.Dec, error) {
// ComputeTotalPowerByMask computes the total power indicated by bitmap mask
func (v *stakedVoteWeight) computeTotalPowerByMask(mask *bls_cosi.Mask) *numeric.Dec {
pubKeys := mask.Publics
w := bls.SerializedPublicKey{}
currentTotal := numeric.ZeroDec()
for i := range pubKeys {
if err := w.FromLibBLSPublicKey(pubKeys[i]); err != nil {
return nil
}
if enabled, err := mask.KeyEnabled(pubKeys[i]); err == nil && enabled {
for key, i := range mask.PublicsIndex {
if enabled, err := mask.IndexEnabled(i); err == nil && enabled {
currentTotal = currentTotal.Add(
v.roster.Voters[w].OverallPercent,
v.roster.Voters[key].OverallPercent,
)
}
}

@ -54,7 +54,7 @@ func setupBaseCase() (Decider, *TallyResult, shard.SlotList, map[string]secretKe
sKeys := map[string]secretKeyMap{}
sKeys[hmy] = secretKeyMap{}
sKeys[reg] = secretKeyMap{}
pubKeys := []*bls_core.PublicKey{}
pubKeys := []bls.PublicKeyWrapper{}
for i := 0; i < quorumNodes; i++ {
newSlot, sKey := generateRandomSlot()
@ -65,7 +65,9 @@ func setupBaseCase() (Decider, *TallyResult, shard.SlotList, map[string]secretKe
sKeys[reg][newSlot.BLSPublicKey] = sKey
}
slotList = append(slotList, newSlot)
pubKeys = append(pubKeys, sKey.GetPublicKey())
wrapper := bls.PublicKeyWrapper{Object: sKey.GetPublicKey()}
wrapper.Bytes.FromLibBLSPublicKey(wrapper.Object)
pubKeys = append(pubKeys, wrapper)
}
decider := NewDecider(SuperMajorityStake, shard.BeaconChainShardID)
@ -83,7 +85,7 @@ func setupBaseCase() (Decider, *TallyResult, shard.SlotList, map[string]secretKe
func setupEdgeCase() (Decider, *TallyResult, shard.SlotList, secretKeyMap) {
slotList := shard.SlotList{}
sKeys := secretKeyMap{}
pubKeys := []*bls_core.PublicKey{}
pubKeys := []bls.PublicKeyWrapper{}
for i := 0; i < quorumNodes; i++ {
newSlot, sKey := generateRandomSlot()
@ -92,7 +94,9 @@ func setupEdgeCase() (Decider, *TallyResult, shard.SlotList, secretKeyMap) {
sKeys[newSlot.BLSPublicKey] = sKey
}
slotList = append(slotList, newSlot)
pubKeys = append(pubKeys, sKey.GetPublicKey())
wrapper := bls.PublicKeyWrapper{Object: sKey.GetPublicKey()}
wrapper.Bytes.FromLibBLSPublicKey(wrapper.Object)
pubKeys = append(pubKeys, wrapper)
}
decider := NewDecider(SuperMajorityStake, shard.BeaconChainShardID)

@ -3,7 +3,6 @@ package quorum
import (
"testing"
"github.com/harmony-one/bls/ffi/go/bls"
harmony_bls "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/shard"
"github.com/stretchr/testify/assert"
@ -48,11 +47,13 @@ func TestAddingQuoromParticipants(t *testing.T) {
assert.Equal(t, int64(0), decider.ParticipantsCount())
blsKeys := []*bls.PublicKey{}
blsKeys := []harmony_bls.PublicKeyWrapper{}
keyCount := int64(5)
for i := int64(0); i < keyCount; i++ {
blsKey := harmony_bls.RandPrivateKey()
blsKeys = append(blsKeys, blsKey.GetPublicKey())
wrapper := harmony_bls.PublicKeyWrapper{Object: blsKey.GetPublicKey()}
wrapper.Bytes.FromLibBLSPublicKey(wrapper.Object)
blsKeys = append(blsKeys, wrapper)
}
decider.UpdateParticipants(blsKeys)

@ -73,7 +73,7 @@ type ParticipantTracker interface {
IndexOf(bls.SerializedPublicKey) int
ParticipantsCount() int64
NextAfter(*bls.PublicKeyWrapper) (bool, *bls.PublicKeyWrapper)
UpdateParticipants(pubKeys []*bls_core.PublicKey)
UpdateParticipants(pubKeys []bls.PublicKeyWrapper)
}
// SignatoryTracker ..
@ -202,17 +202,12 @@ func (s *cIdentities) Participants() multibls.PublicKeys {
return s.publicKeys
}
func (s *cIdentities) UpdateParticipants(pubKeys []*bls_core.PublicKey) {
keys := make([]bls.PublicKeyWrapper, len(pubKeys))
func (s *cIdentities) UpdateParticipants(pubKeys []bls.PublicKeyWrapper) {
keyIndexMap := map[bls.SerializedPublicKey]int{}
for i := range pubKeys {
kBytes := bls.SerializedPublicKey{}
kBytes.FromLibBLSPublicKey(pubKeys[i])
keys[i] = bls.PublicKeyWrapper{Object: pubKeys[i], Bytes: kBytes}
keyIndexMap[kBytes] = i
keyIndexMap[pubKeys[i].Bytes] = i
}
s.publicKeys = keys
s.publicKeys = pubKeys
s.keyIndexMap = keyIndexMap
}

@ -51,7 +51,7 @@ 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.priKey {
if err := consensus.commitBitmap.SetKey(key.Pub.Object, true); err != nil {
if err := consensus.commitBitmap.SetKey(key.Pub.Bytes, true); err != nil {
consensus.getLogger().Warn().Msgf("[OnPrepare] Leader commit bitmap set failed for key at index %d", i)
continue
}

@ -216,7 +216,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
consensus.getLogger().Debug().Msg("[onViewChange] add my M1 type messaage")
msgToSign := append(preparedMsg.BlockHash[:], preparedMsg.Payload...)
for i, key := range consensus.priKey {
if err := consensus.bhpBitmap[recvMsg.ViewID].SetKey(key.Pub.Object, true); err != nil {
if err := consensus.bhpBitmap[recvMsg.ViewID].SetKey(key.Pub.Bytes, true); err != nil {
consensus.getLogger().Warn().Msgf("[onViewChange] bhpBitmap setkey failed for key at index %d", i)
continue
}
@ -229,7 +229,7 @@ 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.priKey {
if err := consensus.nilBitmap[recvMsg.ViewID].SetKey(key.Pub.Object, true); err != nil {
if err := consensus.nilBitmap[recvMsg.ViewID].SetKey(key.Pub.Bytes, true); err != nil {
consensus.getLogger().Warn().Msgf("[onViewChange] nilBitmap setkey failed for key at index %d", i)
continue
}
@ -243,7 +243,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
viewIDBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(viewIDBytes, recvMsg.ViewID)
for i, key := range consensus.priKey {
if err := consensus.viewIDBitmap[recvMsg.ViewID].SetKey(key.Pub.Object, true); err != nil {
if err := consensus.viewIDBitmap[recvMsg.ViewID].SetKey(key.Pub.Bytes, true); err != nil {
consensus.getLogger().Warn().Msgf("[onViewChange] viewIDBitmap setkey failed for key at index %d", i)
continue
}
@ -283,7 +283,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Add M2 (NIL) type message")
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.
consensus.nilBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Bytes, 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")
@ -354,7 +354,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
Str("validatorPubKey", senderKey.Bytes.Hex()).
Msg("[onViewChange] Add M1 (prepared) type message")
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.
consensus.bhpBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Bytes, true) // Set the bitmap indicating that this validator signed.
}
// check and add viewID (m3 type) message signature
@ -378,7 +378,7 @@ func (consensus *Consensus) onViewChange(msg *msg_pb.Message) {
consensus.viewIDSigs[recvMsg.ViewID][senderKey.Bytes.Hex()] = recvMsg.ViewidSig
// Set the bitmap indicating that this validator signed.
consensus.viewIDBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Object, true)
consensus.viewIDBitmap[recvMsg.ViewID].SetKey(recvMsg.SenderPubkey.Bytes, true)
consensus.getLogger().Debug().
Int("have", len(consensus.viewIDSigs[recvMsg.ViewID])).
Int64("total", consensus.Decider.ParticipantsCount()).
@ -422,7 +422,7 @@ 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.priKey {
if err := consensus.commitBitmap.SetKey(key.Pub.Object, true); err != nil {
if err := consensus.commitBitmap.SetKey(key.Pub.Bytes, true); err != nil {
consensus.getLogger().Warn().
Msgf("[OnViewChange] New Leader commit bitmap set failed for key at index %d", i)
continue

@ -125,7 +125,7 @@ func TestGetNextLeaderKeyShouldSucceed(t *testing.T) {
assert.Equal(t, int64(0), consensus.Decider.ParticipantsCount())
blsKeys := []*bls_core.PublicKey{}
wrappedBLSKeys := []*bls.PublicKeyWrapper{}
wrappedBLSKeys := []bls.PublicKeyWrapper{}
keyCount := int64(5)
for i := int64(0); i < keyCount; i++ {
@ -133,17 +133,17 @@ func TestGetNextLeaderKeyShouldSucceed(t *testing.T) {
blsPubKey := blsKey.GetPublicKey()
bytes := bls.SerializedPublicKey{}
bytes.FromLibBLSPublicKey(blsPubKey)
wrapped := &bls.PublicKeyWrapper{Object: blsPubKey, Bytes: bytes}
wrapped := bls.PublicKeyWrapper{Object: blsPubKey, Bytes: bytes}
blsKeys = append(blsKeys, blsPubKey)
wrappedBLSKeys = append(wrappedBLSKeys, wrapped)
}
consensus.Decider.UpdateParticipants(blsKeys)
consensus.Decider.UpdateParticipants(wrappedBLSKeys)
assert.Equal(t, keyCount, consensus.Decider.ParticipantsCount())
consensus.LeaderPubKey = wrappedBLSKeys[0]
consensus.LeaderPubKey = &wrappedBLSKeys[0]
nextKey := consensus.GetNextLeaderKey()
assert.Equal(t, nextKey, wrappedBLSKeys[1])
assert.Equal(t, nextKey, &wrappedBLSKeys[1])
}

@ -67,6 +67,7 @@ func AggregateSig(sigs []*bls.Sign) *bls.Sign {
type Mask struct {
Bitmap []byte
Publics []*bls.PublicKey
PublicsIndex map[SerializedPublicKey]int
AggregatePublic *bls.PublicKey
}
@ -74,20 +75,24 @@ type Mask struct {
// cosigners are disabled by default. If a public key is given it verifies that
// it is present in the list of keys and sets the corresponding index in the
// bitmask to 1 (enabled).
func NewMask(publics []*bls.PublicKey, myKey *bls.PublicKey) (*Mask, error) {
func NewMask(publics []PublicKeyWrapper, myKey *PublicKeyWrapper) (*Mask, error) {
index := map[SerializedPublicKey]int{}
publicKeys := make([]*bls.PublicKey, len(publics))
for i, key := range publics {
publicKeys[i] = key.Object
index[key.Bytes] = i
}
m := &Mask{
Publics: publics,
Publics: publicKeys,
PublicsIndex: index,
}
m.Bitmap = make([]byte, m.Len())
m.AggregatePublic = &bls.PublicKey{}
if myKey != nil {
found := false
for i, key := range publics {
if key.IsEqual(myKey) {
m.SetBit(i, true)
found = true
break
}
i, found := m.PublicsIndex[myKey.Bytes]
if found {
m.SetBit(i, true)
found = true
}
if !found {
return nil, errors.New("key not found")
@ -191,21 +196,19 @@ func (m *Mask) IndexEnabled(i int) (bool, error) {
// KeyEnabled checks whether the index, corresponding to the given key, is
// enabled in the Bitmap or not.
func (m *Mask) KeyEnabled(public *bls.PublicKey) (bool, error) {
for i, key := range m.Publics {
if key.IsEqual(public) {
return m.IndexEnabled(i)
}
func (m *Mask) KeyEnabled(public SerializedPublicKey) (bool, error) {
i, found := m.PublicsIndex[public]
if found {
return m.IndexEnabled(i)
}
return false, errors.New("key not found")
}
// SetKey set the bit in the Bitmap for the given cosigner
func (m *Mask) SetKey(public *bls.PublicKey, enable bool) error {
for i, key := range m.Publics {
if key.IsEqual(public) {
return m.SetBit(i, enable)
}
func (m *Mask) SetKey(public SerializedPublicKey, enable bool) error {
i, found := m.PublicsIndex[public]
if found {
return m.SetBit(i, enable)
}
return errors.New("key not found")
}

@ -9,11 +9,14 @@ import (
// Test the basic functionality of a BLS multi-sig mask.
func TestNewMask(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey3 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, err := NewMask([]*bls.PublicKey{pubKey1, pubKey2, pubKey3}, pubKey1)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
if err != nil {
test.Errorf("Failed to create a new Mask: %s", err)
@ -23,7 +26,7 @@ func TestNewMask(test *testing.T) {
test.Errorf("Mask created with wrong size: %d", mask.Len())
}
enabled, err := mask.KeyEnabled(pubKey1)
enabled, err := mask.KeyEnabled(pubKey1.Bytes)
if !enabled || err != nil {
test.Errorf("My key pubKey1 should have been enabled: %s", err)
}
@ -38,12 +41,17 @@ func TestNewMask(test *testing.T) {
}
func TestNewMaskWithAbsentPublicKey(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey3 := RandPrivateKey().GetPublicKey()
pubKey4 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey4 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, err := NewMask([]*bls.PublicKey{pubKey1, pubKey2, pubKey3}, pubKey4)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object)
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey4)
if err == nil {
test.Errorf("Failed to create a new Mask: %s", err)
@ -56,11 +64,14 @@ func TestNewMaskWithAbsentPublicKey(test *testing.T) {
}
func TestThreshHoldPolicy(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey3 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, err := NewMask([]*bls.PublicKey{pubKey1, pubKey2, pubKey3}, pubKey1)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
if err != nil {
test.Errorf("Failed to create a new Mask: %s", err)
@ -72,8 +83,8 @@ func TestThreshHoldPolicy(test *testing.T) {
threshHoldPolicy := *NewThresholdPolicy(1)
mask.SetKey(pubKey1, true)
mask.SetKey(pubKey2, true)
mask.SetKey(pubKey1.Bytes, true)
mask.SetKey(pubKey2.Bytes, true)
if mask.CountEnabled() != 2 {
test.Errorf("Number of enabled nodes: %d , expected count = 2 ", mask.CountEnabled())
@ -83,8 +94,8 @@ func TestThreshHoldPolicy(test *testing.T) {
test.Error("Number of enabled nodes less than threshold")
}
mask.SetKey(pubKey1, false)
mask.SetKey(pubKey2, false)
mask.SetKey(pubKey1.Bytes, false)
mask.SetKey(pubKey2.Bytes, false)
if threshHoldPolicy.Check(mask) {
test.Error("Number of enabled nodes more than equal to threshold")
@ -92,11 +103,14 @@ func TestThreshHoldPolicy(test *testing.T) {
}
func TestCompletePolicy(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey3 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, err := NewMask([]*bls.PublicKey{pubKey1, pubKey2, pubKey3}, pubKey1)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
if err != nil {
test.Errorf("Failed to create a new Mask: %s", err)
@ -108,9 +122,9 @@ func TestCompletePolicy(test *testing.T) {
completePolicy := CompletePolicy{}
mask.SetKey(pubKey1, true)
mask.SetKey(pubKey2, true)
mask.SetKey(pubKey3, true)
mask.SetKey(pubKey1.Bytes, true)
mask.SetKey(pubKey2.Bytes, true)
mask.SetKey(pubKey3.Bytes, true)
if mask.CountEnabled() != 3 {
test.Errorf("Number of enabled nodes: %d , expected count = 3 ", mask.CountEnabled())
@ -120,7 +134,7 @@ func TestCompletePolicy(test *testing.T) {
test.Error("Number of enabled nodes not equal to total count")
}
mask.SetKey(pubKey1, false)
mask.SetKey(pubKey1.Bytes, false)
if completePolicy.Check(mask) {
test.Error("Number of enabled nodes equal to total count")
@ -161,12 +175,16 @@ func TestAggregateMasks(test *testing.T) {
}
func TestEnableKeyFunctions(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey3 := RandPrivateKey().GetPublicKey()
pubKey4 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey3 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey4 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, err := NewMask([]*bls.PublicKey{pubKey1, pubKey2, pubKey3}, pubKey1)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
pubKey3.Bytes.FromLibBLSPublicKey(pubKey3.Object)
pubKey4.Bytes.FromLibBLSPublicKey(pubKey4.Object)
mask, err := NewMask([]PublicKeyWrapper{pubKey1, pubKey2, pubKey3}, &pubKey1)
if err != nil {
test.Errorf("Failed to create a new Mask: %s", err)
@ -197,7 +215,7 @@ func TestEnableKeyFunctions(test *testing.T) {
test.Error("Count of disabled keys don't match")
}
if _, error := mask.KeyEnabled(pubKey4); error == nil {
if _, error := mask.KeyEnabled(pubKey4.Bytes); error == nil {
test.Error("Expected key not found error")
}
@ -205,16 +223,18 @@ func TestEnableKeyFunctions(test *testing.T) {
test.Error("Expected index out of range error")
}
if err := mask.SetKey(pubKey4, true); err == nil {
if err := mask.SetKey(pubKey4.Bytes, true); err == nil {
test.Error("Expected key nout found error")
}
}
func TestCopyParticipatingMask(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, _ := NewMask([]*bls.PublicKey{pubKey1, pubKey2}, pubKey1)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
mask, _ := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}, &pubKey1)
clonedMask := mask.Mask()
@ -225,10 +245,12 @@ func TestCopyParticipatingMask(test *testing.T) {
}
func TestSetMask(test *testing.T) {
pubKey1 := RandPrivateKey().GetPublicKey()
pubKey2 := RandPrivateKey().GetPublicKey()
pubKey1 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
pubKey2 := PublicKeyWrapper{Object: RandPrivateKey().GetPublicKey()}
mask, _ := NewMask([]*bls.PublicKey{pubKey1, pubKey2}, pubKey1)
pubKey1.Bytes.FromLibBLSPublicKey(pubKey1.Object)
pubKey2.Bytes.FromLibBLSPublicKey(pubKey2.Object)
mask, _ := NewMask([]PublicKeyWrapper{pubKey1, pubKey2}, &pubKey1)
_ = mask
maskBytes := []byte{3}

@ -12,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/proto"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum"
@ -900,9 +899,10 @@ func (b *APIBackend) GetBlockSigners(ctx context.Context, blockNr rpc.BlockNumbe
if err != nil {
return nil, nil, err
}
pubkeys := make([]*bls_core.PublicKey, len(committee.Slots))
for i, validator := range committee.Slots {
if pubkeys[i], err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
pubkeys := make([]internal_bls.PublicKeyWrapper, len(committee.Slots))
for _, validator := range committee.Slots {
wrapper := internal_bls.PublicKeyWrapper{Bytes: validator.BLSPublicKey}
if wrapper.Object, err = bls.BytesToBLSPublicKey(wrapper.Bytes[:]); err != nil {
return nil, nil, err
}
}

@ -5,8 +5,9 @@ import (
"math/big"
"sort"
harmony_bls "github.com/harmony-one/harmony/crypto/bls"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/quorum"
@ -79,7 +80,7 @@ func (e *engineImpl) VerifyHeaders(chain engine.ChainReader, headers []*block.He
// ReadPublicKeysFromLastBlock finds the public keys of last block's committee
func ReadPublicKeysFromLastBlock(
bc engine.ChainReader, header *block.Header,
) ([]*bls.PublicKey, error) {
) ([]harmony_bls.PublicKeyWrapper, error) {
parentHeader := bc.GetHeaderByHash(header.ParentHash())
return GetPublicKeys(bc, parentHeader, false)
}
@ -516,7 +517,7 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
// GetPublicKeys finds the public keys of the committee that signed the block header
func GetPublicKeys(
chain engine.ChainReader, header *block.Header, reCalculate bool,
) ([]*bls.PublicKey, error) {
) ([]harmony_bls.PublicKeyWrapper, error) {
if header == nil {
return nil, errors.New("nil header provided")
}

@ -10,7 +10,7 @@ import (
)
// ReadSignatureBitmapByPublicKeys read the payload of signature and bitmap based on public keys
func ReadSignatureBitmapByPublicKeys(recvPayload []byte, publicKeys []*bls_core.PublicKey) (*bls_core.Sign, *bls.Mask, error) {
func ReadSignatureBitmapByPublicKeys(recvPayload []byte, publicKeys []bls.PublicKeyWrapper) (*bls_core.Sign, *bls.Mask, error) {
if len(recvPayload) < 96 {
return nil, nil, errors.New("payload not have enough length")
}

@ -6,13 +6,10 @@ import (
"math/big"
"time"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/rpc"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/consensus/quorum"
@ -268,11 +265,7 @@ func (s *PublicBlockChainAPI) GetBlockSigners(ctx context.Context, blockNr rpc.B
if err != nil {
return nil, err
}
blsPublicKey := new(bls_core.PublicKey)
if blsPublicKey, err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
return nil, err
}
if ok, err := mask.KeyEnabled(blsPublicKey); err == nil && ok {
if ok, err := mask.KeyEnabled(validator.BLSPublicKey); err == nil && ok {
signers = append(signers, oneAddress)
}
}
@ -293,11 +286,7 @@ func (s *PublicBlockChainAPI) GetBlockSignerKeys(ctx context.Context, blockNr rp
}
signers := []string{}
for _, validator := range slots {
blsPublicKey := new(bls_core.PublicKey)
if blsPublicKey, err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
return nil, err
}
if ok, err := mask.KeyEnabled(blsPublicKey); err == nil && ok {
if ok, err := mask.KeyEnabled(validator.BLSPublicKey); err == nil && ok {
signers = append(signers, validator.BLSPublicKey.Hex())
}
}
@ -324,11 +313,7 @@ func (s *PublicBlockChainAPI) IsBlockSigner(ctx context.Context, blockNr rpc.Blo
if oneAddress != address {
continue
}
blsPublicKey := new(bls_core.PublicKey)
if blsPublicKey, err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
return false, err
}
if ok, err := mask.KeyEnabled(blsPublicKey); err == nil && ok {
if ok, err := mask.KeyEnabled(validator.BLSPublicKey); err == nil && ok {
return true, nil
}
}

@ -6,13 +6,10 @@ import (
"math/big"
"time"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/rpc"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/consensus/quorum"
@ -229,11 +226,7 @@ func (s *PublicBlockChainAPI) GetBlockSigners(ctx context.Context, blockNr uint6
if err != nil {
return nil, err
}
blsPublicKey := new(bls_core.PublicKey)
if blsPublicKey, err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
return nil, err
}
if ok, err := mask.KeyEnabled(blsPublicKey); err == nil && ok {
if ok, err := mask.KeyEnabled(validator.BLSPublicKey); err == nil && ok {
signers = append(signers, oneAddress)
}
}
@ -254,11 +247,7 @@ func (s *PublicBlockChainAPI) GetBlockSignerKeys(ctx context.Context, blockNr ui
}
signers := []string{}
for _, validator := range slots {
blsPublicKey := new(bls_core.PublicKey)
if blsPublicKey, err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
return nil, err
}
if ok, err := mask.KeyEnabled(blsPublicKey); err == nil && ok {
if ok, err := mask.KeyEnabled(validator.BLSPublicKey); err == nil && ok {
signers = append(signers, validator.BLSPublicKey.Hex())
}
}
@ -285,11 +274,7 @@ func (s *PublicBlockChainAPI) IsBlockSigner(ctx context.Context, blockNr uint64,
if oneAddress != address {
continue
}
blsPublicKey := new(bls_core.PublicKey)
if blsPublicKey, err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
return false, err
}
if ok, err := mask.KeyEnabled(blsPublicKey); err == nil && ok {
if ok, err := mask.KeyEnabled(validator.BLSPublicKey); err == nil && ok {
return true, nil
}
}

@ -919,7 +919,7 @@ func (node *Node) InitConsensusWithValidators() (err error) {
}
for _, key := range pubKeys {
if node.Consensus.GetPublicKeys().Contains(key) {
if node.Consensus.GetPublicKeys().Contains(key.Object) {
utils.Logger().Info().
Uint64("blockNum", blockNum).
Int("numPubKeys", len(pubKeys)).

@ -6,8 +6,6 @@ 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"
@ -375,12 +373,8 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
func (node *Node) numSignaturesIncludedInBlock(block *types.Block) uint32 {
count := uint32(0)
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)
mask, err := internal_bls.NewMask(members, nil)
if err != nil {
return count
}
@ -389,7 +383,7 @@ func (node *Node) numSignaturesIncludedInBlock(block *types.Block) uint32 {
return count
}
for _, key := range node.Consensus.GetPublicKeys() {
if ok, err := mask.KeyEnabled(key.Object); err == nil && ok {
if ok, err := mask.KeyEnabled(key.Bytes); err == nil && ok {
count++
}
}

@ -7,7 +7,6 @@ import (
"math/big"
"sort"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/ethereum/go-ethereum/common"
@ -328,19 +327,19 @@ func (c *Committee) Hash() common.Hash {
}
// BLSPublicKeys ..
func (c *Committee) BLSPublicKeys() ([]*bls_core.PublicKey, error) {
func (c *Committee) BLSPublicKeys() ([]bls.PublicKeyWrapper, error) {
if c == nil {
return nil, ErrSubCommitteeNil
}
slice := make([]*bls_core.PublicKey, len(c.Slots))
slice := make([]bls.PublicKeyWrapper, len(c.Slots))
for j := range c.Slots {
pubKey, err := bls.BytesToBLSPublicKey(c.Slots[j].BLSPublicKey[:])
if err != nil {
return nil, err
}
slice[j] = pubKey
slice[j] = bls.PublicKeyWrapper{c.Slots[j].BLSPublicKey, pubKey}
}
return slice, nil

Loading…
Cancel
Save