Skip to content

Commit 2aa256b

Browse files
authored
Reduce cost of BLS key serialization over gRPC (#1343)
1 parent bb4029e commit 2aa256b

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

snow/validators/gvalidators/validator_state_client.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package gvalidators
55

66
import (
77
"context"
8+
"errors"
89

910
"google.golang.org/protobuf/types/known/emptypb"
1011

@@ -15,7 +16,10 @@ import (
1516
pb "github.com/ava-labs/avalanchego/proto/pb/validatorstate"
1617
)
1718

18-
var _ validators.State = (*Client)(nil)
19+
var (
20+
_ validators.State = (*Client)(nil)
21+
errFailedPublicKeyDeserialize = errors.New("couldn't deserialize public key")
22+
)
1923

2024
type Client struct {
2125
client pb.ValidatorStateClient
@@ -72,9 +76,13 @@ func (c *Client) GetValidatorSet(
7276
}
7377
var publicKey *bls.PublicKey
7478
if len(validator.PublicKey) > 0 {
75-
publicKey, err = bls.PublicKeyFromBytes(validator.PublicKey)
76-
if err != nil {
77-
return nil, err
79+
// This is a performance optimization to avoid the cost of compression
80+
// and key re-verification with PublicKeyFromBytes. We can safely
81+
// assume that the BLS Public Keys are verified before being added
82+
// to the P-Chain and served by the gRPC server.
83+
publicKey = new(bls.PublicKey).Deserialize(validator.PublicKey)
84+
if publicKey == nil {
85+
return nil, errFailedPublicKeyDeserialize
7886
}
7987
}
8088
vdrs[nodeID] = &validators.GetValidatorOutput{

snow/validators/gvalidators/validator_state_server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"github.com/ava-labs/avalanchego/ids"
1212
"github.com/ava-labs/avalanchego/snow/validators"
13-
"github.com/ava-labs/avalanchego/utils/crypto/bls"
1413

1514
pb "github.com/ava-labs/avalanchego/proto/pb/validatorstate"
1615
)
@@ -70,7 +69,9 @@ func (s *Server) GetValidatorSet(ctx context.Context, req *pb.GetValidatorSetReq
7069
Weight: vdr.Weight,
7170
}
7271
if vdr.PublicKey != nil {
73-
vdrPB.PublicKey = bls.PublicKeyToBytes(vdr.PublicKey)
72+
// This is a performance optimization to avoid the cost of compression
73+
// from PublicKeyToBytes.
74+
vdrPB.PublicKey = vdr.PublicKey.Serialize()
7475
}
7576
resp.Validators[i] = vdrPB
7677
i++

snow/validators/gvalidators/validator_state_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ func TestGetValidatorSet(t *testing.T) {
183183
require.Error(err)
184184
}
185185

186+
func TestPublicKeyDeserialize(t *testing.T) {
187+
require := require.New(t)
188+
189+
sk, err := bls.NewSecretKey()
190+
require.NoError(err)
191+
pk := bls.PublicFromSecretKey(sk)
192+
193+
pkBytes := pk.Serialize()
194+
pkDe := new(bls.PublicKey).Deserialize(pkBytes)
195+
require.NotNil(pkDe)
196+
require.EqualValues(pk, pkDe)
197+
}
198+
186199
// BenchmarkGetValidatorSet measures the time it takes complete a gRPC client
187200
// request based on a mocked validator set.
188201
func BenchmarkGetValidatorSet(b *testing.B) {

0 commit comments

Comments
 (0)