Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into refactor-voting-power-dist
Browse files Browse the repository at this point in the history
SebastianElvis committed Oct 15, 2024
2 parents ccbcf91 + 089917e commit 86fcc5d
Showing 10 changed files with 864 additions and 222 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -37,6 +37,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## Unreleased

### API Breaking

* [#194](https://github.com/babylonlabs-io/babylon/pull/194) Adjusted handling of `FinalityProviderSigningInfo` in finality keeper queries to improve API security
* Modified `QuerySigningInfosResponse` to remove direct exposure of sensitive fields
* Updated related tests in `x/finality/keeper/grpc_query_test.go`
* [#201](https://github.com/babylonlabs-io/babylon/pull/201) Adjusted handling of `ValidatorWithBlsKey` in checkpoint keeper queries to improve API security
* Modified `QueryBlsPublicKeyListResponse` to remove direct exposure of sensitive fields
* Updated related tests in `x/checkpointing/keeper/grpc_query_bls.go`

### State Machine Breaking

* [#181](https://github.com/babylonlabs-io/babylon/pull/181) Modify BTC heights
13 changes: 12 additions & 1 deletion proto/babylon/checkpointing/v1/query.proto
Original file line number Diff line number Diff line change
@@ -122,10 +122,21 @@ message QueryBlsPublicKeyListRequest {
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// BlsPublicKeyListResponse couples validator address, voting power, and its bls
// public key
message BlsPublicKeyListResponse {
// validator_address is the address of the validator
string validator_address = 1;
// bls_pub_key is the BLS public key of the validator
string bls_pub_key_hex = 2;
// voting_power is the voting power of the validator at the given epoch
uint64 voting_power = 3;
}

// QueryBlsPublicKeyListResponse is the response type for the
// Query/BlsPublicKeys RPC method.
message QueryBlsPublicKeyListResponse {
repeated ValidatorWithBlsKey validator_with_bls_keys = 1;
repeated BlsPublicKeyListResponse validator_with_bls_keys = 1;

// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
21 changes: 18 additions & 3 deletions proto/babylon/finality/v1/query.proto
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "babylon/finality/v1/params.proto";
import "babylon/finality/v1/finality.proto";
import "google/protobuf/timestamp.proto";
import "amino/amino.proto";

option go_package = "github.com/babylonlabs-io/babylon/x/finality/types";

@@ -229,11 +231,24 @@ message QuerySigningInfoRequest {
string fp_btc_pk_hex = 1;
}

// SigningInfoResponse defines the API response containing a finality provider's signing info
// for monitoring their liveness activity.
message SigningInfoResponse {
// fp_btc_pk is the BTC PK of the finality provider that casts this vote
string fp_btc_pk_hex = 1;
// start_height is the block height at which finality provider become active
int64 start_height = 2;
// missed_blocks_counter defines a counter to avoid unnecessary array reads.
// Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`.
int64 missed_blocks_counter = 3;
// Timestamp until which the validator is jailed due to liveness downtime.
google.protobuf.Timestamp jailed_until = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC
// method
message QuerySigningInfoResponse {
// fp_signing_info is the signing info of requested finality provider BTC public key
FinalityProviderSigningInfo fp_signing_info = 1 [(gogoproto.nullable) = false];
SigningInfoResponse signing_info = 1 [(gogoproto.nullable) = false];
}

// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC
@@ -246,6 +261,6 @@ message QuerySigningInfosRequest {
// method
message QuerySigningInfosResponse {
// info is the signing info of all finality providers with signing info
repeated FinalityProviderSigningInfo fp_signing_infos = 1 [(gogoproto.nullable) = false];
repeated SigningInfoResponse signing_infos = 1 [(gogoproto.nullable) = false];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
19 changes: 17 additions & 2 deletions x/checkpointing/keeper/grpc_query_bls.go
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ package keeper

import (
"context"
"encoding/hex"

"github.com/babylonlabs-io/babylon/x/checkpointing/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/jinzhu/copier"
@@ -21,7 +23,7 @@ func (k Keeper) BlsPublicKeyList(c context.Context, req *types.QueryBlsPublicKey

if req.Pagination == nil {
return &types.QueryBlsPublicKeyListResponse{
ValidatorWithBlsKeys: valBLSKeys,
ValidatorWithBlsKeys: convertToBlsPublicKeyListResponse(valBLSKeys),
}, nil
}

@@ -46,6 +48,19 @@ func (k Keeper) BlsPublicKeyList(c context.Context, req *types.QueryBlsPublicKey
}

return &types.QueryBlsPublicKeyListResponse{
ValidatorWithBlsKeys: copiedValBLSKeys,
ValidatorWithBlsKeys: convertToBlsPublicKeyListResponse(copiedValBLSKeys),
}, nil
}

func convertToBlsPublicKeyListResponse(valBLSKeys []*types.ValidatorWithBlsKey) []*types.BlsPublicKeyListResponse {
blsPublicKeyListResponse := make([]*types.BlsPublicKeyListResponse, len(valBLSKeys))

for i, valBlsKey := range valBLSKeys {
blsPublicKeyListResponse[i] = &types.BlsPublicKeyListResponse{
ValidatorAddress: valBlsKey.ValidatorAddress,
BlsPubKeyHex: hex.EncodeToString(valBlsKey.BlsPubKey),
VotingPower: valBlsKey.VotingPower,
}
}
return blsPublicKeyListResponse
}
3 changes: 2 additions & 1 deletion x/checkpointing/keeper/grpc_query_bls_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper_test

import (
"encoding/hex"
"math/rand"
"testing"

@@ -48,7 +49,7 @@ func FuzzQueryBLSKeySet(f *testing.F) {
res, err := queryClient.BlsPublicKeyList(ctx, queryRequest)
require.NoError(t, err)
require.Len(t, res.ValidatorWithBlsKeys, 1)
require.Equal(t, res.ValidatorWithBlsKeys[0].BlsPubKey, genesisBLSPubkey.Bytes())
require.Equal(t, res.ValidatorWithBlsKeys[0].BlsPubKeyHex, hex.EncodeToString(genesisBLSPubkey.Bytes()))
require.Equal(t, res.ValidatorWithBlsKeys[0].VotingPower, uint64(1000))
require.Equal(t, res.ValidatorWithBlsKeys[0].ValidatorAddress, genesisVal.GetValAddressStr())

6 changes: 4 additions & 2 deletions x/checkpointing/keeper/grpc_query_checkpoint.go
Original file line number Diff line number Diff line change
@@ -109,9 +109,11 @@ func (k Keeper) RecentEpochStatusCount(ctx context.Context, req *types.QueryRece
if err != nil {
return nil, fmt.Errorf("failed to get the last checkpointed epoch")
}
targetEpoch := tipEpoch - req.EpochCount + 1
if targetEpoch < 0 { //nolint:staticcheck // uint64 doesn't go below zero
targetEpoch := tipEpoch
if req.EpochCount > tipEpoch {
targetEpoch = 0
} else {
targetEpoch -= req.EpochCount - 1
}
// iterate epochs in the reverse order and count epoch numbers for each status
epochStatusCount := make(map[string]uint64, 0)
452 changes: 358 additions & 94 deletions x/checkpointing/types/query.pb.go

Large diffs are not rendered by default.

21 changes: 19 additions & 2 deletions x/finality/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -246,7 +246,7 @@ func (k Keeper) SigningInfo(ctx context.Context, req *types.QuerySigningInfoRequ
return nil, status.Errorf(codes.NotFound, "SigningInfo not found for the finality provider %s", req.FpBtcPkHex)
}

return &types.QuerySigningInfoResponse{FpSigningInfo: signingInfo}, nil
return &types.QuerySigningInfoResponse{SigningInfo: convertToSigningInfoResponse(signingInfo)}, nil
}

// SigningInfos returns signing-infos of all finality providers.
@@ -271,5 +271,22 @@ func (k Keeper) SigningInfos(ctx context.Context, req *types.QuerySigningInfosRe
if err != nil {
return nil, err
}
return &types.QuerySigningInfosResponse{FpSigningInfos: signInfos, Pagination: pageRes}, nil
return &types.QuerySigningInfosResponse{SigningInfos: convertToSigningInfosResponse(signInfos), Pagination: pageRes}, nil
}

func convertToSigningInfoResponse(info types.FinalityProviderSigningInfo) types.SigningInfoResponse {
return types.SigningInfoResponse{
FpBtcPkHex: info.FpBtcPk.MarshalHex(),
StartHeight: info.StartHeight,
MissedBlocksCounter: info.MissedBlocksCounter,
JailedUntil: info.JailedUntil,
}
}

func convertToSigningInfosResponse(signInfos []types.FinalityProviderSigningInfo) []types.SigningInfoResponse {
response := make([]types.SigningInfoResponse, len(signInfos))
for i, info := range signInfos {
response[i] = convertToSigningInfoResponse(info)
}
return response
}
15 changes: 7 additions & 8 deletions x/finality/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -405,9 +405,9 @@ func FuzzSigningInfo(f *testing.F) {
req := &types.QuerySigningInfoRequest{FpBtcPkHex: fpPk}
resp, err := fKeeper.SigningInfo(ctx, req)
require.NoError(t, err)
require.Equal(t, fpSigningInfos[fpPk].StartHeight, resp.FpSigningInfo.StartHeight)
require.Equal(t, fpSigningInfos[fpPk].MissedBlocksCounter, resp.FpSigningInfo.MissedBlocksCounter)
require.Equal(t, fpPk, resp.FpSigningInfo.FpBtcPk.MarshalHex())
require.Equal(t, fpSigningInfos[fpPk].StartHeight, resp.SigningInfo.StartHeight)
require.Equal(t, fpSigningInfos[fpPk].MissedBlocksCounter, resp.SigningInfo.MissedBlocksCounter)
require.Equal(t, fpPk, resp.SigningInfo.FpBtcPkHex)
}

// perform a query for signing info of non-exist finality provider
@@ -428,12 +428,11 @@ func FuzzSigningInfo(f *testing.F) {
}
resp, err := fKeeper.SigningInfos(ctx, req)
require.NoError(t, err)
require.LessOrEqual(t, len(resp.FpSigningInfos), int(limit)) // check if pagination takes effect
require.LessOrEqual(t, len(resp.SigningInfos), int(limit)) // check if pagination takes effect
require.EqualValues(t, resp.Pagination.Total, numSigningInfo) // ensure evidences before startHeight are not included
for _, si := range resp.FpSigningInfos {
require.Equal(t, fpSigningInfos[si.FpBtcPk.MarshalHex()].MissedBlocksCounter, si.MissedBlocksCounter)
require.Equal(t, fpSigningInfos[si.FpBtcPk.MarshalHex()].FpBtcPk.MarshalHex(), si.FpBtcPk.MarshalHex())
require.Equal(t, fpSigningInfos[si.FpBtcPk.MarshalHex()].StartHeight, si.StartHeight)
for _, si := range resp.SigningInfos {
require.Equal(t, fpSigningInfos[si.FpBtcPkHex].MissedBlocksCounter, si.MissedBlocksCounter)
require.Equal(t, fpSigningInfos[si.FpBtcPkHex].StartHeight, si.StartHeight)
}
})
}
527 changes: 418 additions & 109 deletions x/finality/types/query.pb.go

Large diffs are not rendered by default.

0 comments on commit 86fcc5d

Please sign in to comment.