Remove expensive bls key serialization code (#3217)

pull/3224/head
Rongjian Lan 4 years ago committed by GitHub
parent 8a08da67ca
commit bdd2a58e01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      consensus/consensus_service.go
  2. 13
      consensus/double_sign.go
  3. 5
      crypto/bls/bls.go
  4. 10
      hmy/api_backend.go
  5. 22
      internal/hmyapi/apiv1/blockchain.go
  6. 22
      internal/hmyapi/apiv2/blockchain.go
  7. 9
      shard/shard_state.go
  8. 4
      staking/slash/double-sign.go
  9. 4
      staking/types/validator.go

@ -350,14 +350,14 @@ func (consensus *Consensus) getLeaderPubKeyFromCoinbase(
if isStaking { if isStaking {
// After staking the coinbase address will be the address of bls public key // After staking the coinbase address will be the address of bls public key
if utils.GetAddressFromBLSPubKeyBytes(member.BLSPublicKey[:]) == header.Coinbase() { if utils.GetAddressFromBLSPubKeyBytes(member.BLSPublicKey[:]) == header.Coinbase() {
if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil { if committerKey, err = bls.BytesToBLSPublicKey(member.BLSPublicKey[:]); err != nil {
return nil, err return nil, err
} }
return &bls.PublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil return &bls.PublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil
} }
} else { } else {
if member.EcdsaAddress == header.Coinbase() { if member.EcdsaAddress == header.Coinbase() {
if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil { if committerKey, err = bls.BytesToBLSPublicKey(member.BLSPublicKey[:]); err != nil {
return nil, err return nil, err
} }
return &bls.PublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil return &bls.PublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil

@ -2,8 +2,9 @@ package consensus
import ( import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls" bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/quorum" "github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/staking/slash" "github.com/harmony-one/harmony/staking/slash"
) )
@ -14,9 +15,11 @@ func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
if alreadyCastBallot := consensus.Decider.ReadBallot( if alreadyCastBallot := consensus.Decider.ReadBallot(
quorum.Commit, recvMsg.SenderPubkey.Bytes, quorum.Commit, recvMsg.SenderPubkey.Bytes,
); alreadyCastBallot != nil { ); alreadyCastBallot != nil {
firstPubKey := bls.PublicKey{} firstPubKey, err := bls.BytesToBLSPublicKey(alreadyCastBallot.SignerPubKey[:])
alreadyCastBallot.SignerPubKey.ToLibBLSPublicKey(&firstPubKey) if err != nil {
if recvMsg.SenderPubkey.Object.IsEqual(&firstPubKey) { return false
}
if recvMsg.SenderPubkey.Object.IsEqual(firstPubKey) {
for _, blk := range consensus.FBFTLog.GetBlocksByNumber(recvMsg.BlockNum) { for _, blk := range consensus.FBFTLog.GetBlocksByNumber(recvMsg.BlockNum) {
firstSignedBlock := blk.Header() firstSignedBlock := blk.Header()
areHeightsEqual := firstSignedBlock.Number().Uint64() == recvMsg.BlockNum areHeightsEqual := firstSignedBlock.Number().Uint64() == recvMsg.BlockNum
@ -28,7 +31,7 @@ func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
// hash, and if block hash is different, then that is a clear // hash, and if block hash is different, then that is a clear
// case of double signing // case of double signing
if areHeightsEqual && areViewIDsEqual && !areHeadersEqual { if areHeightsEqual && areViewIDsEqual && !areHeadersEqual {
var doubleSign bls.Sign var doubleSign bls_core.Sign
if err := doubleSign.Deserialize(recvMsg.Payload); err != nil { if err := doubleSign.Deserialize(recvMsg.Payload); err != nil {
consensus.getLogger().Err(err).Str("msg", recvMsg.String()). consensus.getLogger().Err(err).Str("msg", recvMsg.String()).
Msg("could not deserialize potential double signer") Msg("could not deserialize potential double signer")

@ -82,8 +82,3 @@ func (pk *SerializedPublicKey) FromLibBLSPublicKey(key *bls.PublicKey) error {
copy(pk[:], bytes) copy(pk[:], bytes)
return nil return nil
} }
// ToLibBLSPublicKey copies the key contents into the given key.
func (pk *SerializedPublicKey) ToLibBLSPublicKey(key *bls.PublicKey) error {
return key.Deserialize(pk[:])
}

@ -12,7 +12,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/bls/ffi/go/bls" bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum" "github.com/harmony-one/harmony/consensus/quorum"
@ -21,6 +21,7 @@ import (
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/bls"
internal_bls "github.com/harmony-one/harmony/crypto/bls" internal_bls "github.com/harmony-one/harmony/crypto/bls"
internal_common "github.com/harmony-one/harmony/internal/common" internal_common "github.com/harmony-one/harmony/internal/common"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
@ -874,10 +875,11 @@ func (b *APIBackend) GetBlockSigners(ctx context.Context, blockNr rpc.BlockNumbe
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
pubkeys := make([]*bls.PublicKey, len(committee.Slots)) pubkeys := make([]*bls_core.PublicKey, len(committee.Slots))
for i, validator := range committee.Slots { for i, validator := range committee.Slots {
pubkeys[i] = new(bls.PublicKey) if pubkeys[i], err = bls.BytesToBLSPublicKey(validator.BLSPublicKey[:]); err != nil {
validator.BLSPublicKey.ToLibBLSPublicKey(pubkeys[i]) return nil, nil, err
}
} }
mask, err := internal_bls.NewMask(pubkeys, nil) mask, err := internal_bls.NewMask(pubkeys, nil)
if err != nil { if err != nil {

@ -6,11 +6,13 @@ import (
"math/big" "math/big"
"time" "time"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/bls/ffi/go/bls" bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/consensus/quorum" "github.com/harmony-one/harmony/consensus/quorum"
@ -261,8 +263,10 @@ func (s *PublicBlockChainAPI) GetBlockSigners(ctx context.Context, blockNr rpc.B
if err != nil { if err != nil {
return nil, err return nil, err
} }
blsPublicKey := new(bls.PublicKey) blsPublicKey := new(bls_core.PublicKey)
validator.BLSPublicKey.ToLibBLSPublicKey(blsPublicKey) 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(blsPublicKey); err == nil && ok {
signers = append(signers, oneAddress) signers = append(signers, oneAddress)
} }
@ -284,8 +288,10 @@ func (s *PublicBlockChainAPI) GetBlockSignerKeys(ctx context.Context, blockNr rp
} }
signers := []string{} signers := []string{}
for _, validator := range slots { for _, validator := range slots {
blsPublicKey := new(bls.PublicKey) blsPublicKey := new(bls_core.PublicKey)
validator.BLSPublicKey.ToLibBLSPublicKey(blsPublicKey) 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(blsPublicKey); err == nil && ok {
signers = append(signers, validator.BLSPublicKey.Hex()) signers = append(signers, validator.BLSPublicKey.Hex())
} }
@ -313,8 +319,10 @@ func (s *PublicBlockChainAPI) IsBlockSigner(ctx context.Context, blockNr rpc.Blo
if oneAddress != address { if oneAddress != address {
continue continue
} }
blsPublicKey := new(bls.PublicKey) blsPublicKey := new(bls_core.PublicKey)
validator.BLSPublicKey.ToLibBLSPublicKey(blsPublicKey) 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(blsPublicKey); err == nil && ok {
return true, nil return true, nil
} }

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

@ -341,13 +341,12 @@ func lookupBLSPublicKeys(
key, func() (interface{}, error) { key, func() (interface{}, error) {
slice := make([]*bls_core.PublicKey, len(c.Slots)) slice := make([]*bls_core.PublicKey, len(c.Slots))
for j := range c.Slots { for j := range c.Slots {
committerKey := &bls_core.PublicKey{} pubKey, err := bls.BytesToBLSPublicKey(c.Slots[j].BLSPublicKey[:])
if err := c.Slots[j].BLSPublicKey.ToLibBLSPublicKey( if err != nil {
committerKey,
); err != nil {
return nil, err return nil, err
} }
slice[j] = committerKey
slice[j] = pubKey
} }
// Only made once // Only made once
go func() { go func() {

@ -245,10 +245,10 @@ func Verify(
if err := signature.Deserialize(ballot.Signature); err != nil { if err := signature.Deserialize(ballot.Signature); err != nil {
return err return err
} }
if err := ballot.SignerPubKey.ToLibBLSPublicKey(publicKey); err != nil {
if publicKey, err = bls.BytesToBLSPublicKey(ballot.SignerPubKey[:]); err != nil {
return err return err
} }
// slash verification only happens in staking era, therefore want commit payload for staking epoch // slash verification only happens in staking era, therefore want commit payload for staking epoch
commitPayload := consensus_sig.ConstructCommitPayload(chain, commitPayload := consensus_sig.ConstructCommitPayload(chain,
candidate.Evidence.Epoch, ballot.BlockHeaderHash, candidate.Evidence.Height, candidate.Evidence.ViewID) candidate.Evidence.Epoch, ballot.BlockHeaderHash, candidate.Evidence.Height, candidate.Evidence.ViewID)

@ -474,8 +474,8 @@ func VerifyBLSKey(pubKey *bls.SerializedPublicKey, pubKeySig *bls.SerializedSign
return errBLSKeysNotMatchSigs return errBLSKeysNotMatchSigs
} }
blsPubKey := new(bls_core.PublicKey) blsPubKey, err := bls.BytesToBLSPublicKey(pubKey[:])
if err := pubKey.ToLibBLSPublicKey(blsPubKey); err != nil { if err != nil {
return errBLSKeysNotMatchSigs return errBLSKeysNotMatchSigs
} }

Loading…
Cancel
Save