Skip to content

Commit

Permalink
feat: add consumer chain query (#2179)
Browse files Browse the repository at this point in the history
* feat: first iteration on Permissionless ICS (#2117)

* (partially) renamed chain ids to consumer ids

* renamed proposal messages

* removed global slash entry

* fixed unit tests

* added new messages

* introduced new state

* added functionality for the register and initialize messages

* renamed (partially) chainIds to consumerIds

* set consumerId to chainId association during registration

* added extra check in the initialization so unknokwn, launched, or stopped chains cannot re-initialize

* added initial work on traversing initialized chains that are to-be-launched

* fixed rebase issues after bringing the VSCMaturedPackets work in

* made it so we traverse initialization records instead of addition proposals (+ additional changes so the unit tests pass)

* renamed more chainIDs to consumerIds

* removed ClientIdToChainId state because chainId already resides on the registration record

* nit fixes in go docs

* removed MsgConsumerAddition

* added CLI commands for new messages

* removed consumer modification proposal

* removed (partially) consumer removal proposal

* rebased to pick up the inactive-validators work (PR #2079)

* introduced consumerId in the equivocation messages (and a useful query for Hermes to get the consumerId)

* added safeguard so that a validator cannot opt-in to two different chains with the same chain id

* renamed some chainIDs to consumerIds

* updated based on comments

Co-authored-by: bernd-m <[email protected]>

* fixed integration tests

* rebased to pick up the removal of legacy proposals (#2130) and re-introduced old messages so that existing proposals can deserialize

* changes messages to only have MsgCreateConsumer and MsgUpdateConsumer and modified protos so that we are backward-compatible

* cleaned up slightly a few things (mostly committing & pushing) so people can pick up the latest changes

* fixed the CreateConsumer and UpdateConsumer logic and made most of the fields optional

* fixed hooks and the code around proposalId to consumerId

* feat: extend consumer validator query to return commission rate (backport #2162) (#2165)

* adapt #2162 changes for permissionless ICS

* nits

---------

Co-authored-by: kirdatatjana <[email protected]>

* renamed some chainIds to consumerIds

* took into account comments and also added safeguard to reject new proposals that still use deprecated messages (e.g., MsgConsumerAddition, etc.)

* Update x/ccv/provider/types/msg.go

Co-authored-by: bernd-m <[email protected]>

* removed double-gas charge on MsgCreateConsumer and imroved the logic of MsgUpdateConsumer

* added PopulateMinimumPowerInTopN tested

* took into account comments (using protos for marshalling string slice, fixed issues in the UpdateConsumer logic, added extra check to abort spurious proposals)

* feat: add fields to consumer validators query (#2167)

* extend consumer validators query

* nit

* nits

* fix msg order

* deprecate power for consumer_power

* modified the way we verify the new owner address, as well as nit refactoring on the ConsumerIds

* fixed some rebase issues and changed a proto to be backward-compatible

---------

Co-authored-by: bernd-m <[email protected]>
Co-authored-by: Simon Noetzlin <[email protected]>
Co-authored-by: kirdatatjana <[email protected]>

* fixed bug on removing previous spawn time & added tests

* added some additional tests

* added tests on the hooks

* removed check that spawn time is in the future

* feat: refactor consumer validator set computation (#2175)

* add UT

* nits

* address comments

* Update x/ccv/provider/keeper/partial_set_security.go

Co-authored-by: insumity <[email protected]>

* fix tests

---------

Co-authored-by: insumity <[email protected]>

* add UT

* nits

* nits

* revert legacy prop funcs

* fix UT

---------

Co-authored-by: insumity <[email protected]>
Co-authored-by: bernd-m <[email protected]>
Co-authored-by: kirdatatjana <[email protected]>
  • Loading branch information
4 people authored Aug 29, 2024
1 parent 289e05c commit aec6c93
Show file tree
Hide file tree
Showing 5 changed files with 1,059 additions and 165 deletions.
21 changes: 21 additions & 0 deletions proto/interchain_security/ccv/provider/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ service Query {
option (google.api.http).get =
"/interchain_security/ccv/provider/consumer_id/{client_id}";
}

// QueryConsumerChain returns the consumer chain
// associated with the provided consumer id
rpc QueryConsumerChain(QueryConsumerChainRequest)
returns (QueryConsumerChainResponse) {
option (google.api.http).get =
"/interchain_security/ccv/provider/consumer_chain/{consumer_id}";
}
}

message QueryConsumerGenesisRequest {
Expand Down Expand Up @@ -431,3 +439,16 @@ message QueryConsumerIdFromClientIdResponse {
// the consumer id of the chain associated with this client id
string consumer_id = 1;
}

message QueryConsumerChainRequest {
string consumer_id = 1;
}

message QueryConsumerChainResponse {
string chain_id = 1;
string owner_address = 2;
string phase = 3;
ConsumerMetadata metadata = 4 [ (gogoproto.nullable) = false ];
ConsumerInitializationParameters init_params = 5;
PowerShapingParameters power_shaping_params = 6;
}
46 changes: 46 additions & 0 deletions x/ccv/provider/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,49 @@ func (k Keeper) QueryConsumerIdFromClientId(goCtx context.Context, req *types.Qu

return &types.QueryConsumerIdFromClientIdResponse{ConsumerId: consumerId}, nil
}

// QueryConsumerChain returns the consumer chain associated with the consumer id
func (k Keeper) QueryConsumerChain(goCtx context.Context, req *types.QueryConsumerChainRequest) (*types.QueryConsumerChainResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

consumerId := req.ConsumerId
if err := types.ValidateConsumerId(consumerId); err != nil {
return nil, status.Error(codes.InvalidArgument, errorsmod.Wrap(types.ErrInvalidConsumerId, consumerId).Error())
}
ctx := sdk.UnwrapSDKContext(goCtx)

chainId, err := k.GetConsumerChainId(ctx, consumerId)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "cannot retrieve chain id for consumer id: %s", consumerId)
}

ownerAddress, err := k.GetConsumerOwnerAddress(ctx, consumerId)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "cannot retrieve owner address for consumer id: %s", consumerId)
}

phase := k.GetConsumerPhase(ctx, consumerId)
if phase == types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED {
return nil, status.Errorf(codes.InvalidArgument, "cannot retrieve phase for consumer id: %s", consumerId)
}

metadata, err := k.GetConsumerMetadata(ctx, consumerId)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "cannot retrieve metadata for consumer id: %s", consumerId)
}

// neither the init nor the power shaping params are mandatory for consumers
initParams, _ := k.GetConsumerInitializationParameters(ctx, consumerId)
powerParams, _ := k.GetConsumerPowerShapingParameters(ctx, consumerId)

return &types.QueryConsumerChainResponse{
ChainId: chainId,
OwnerAddress: ownerAddress,
Phase: phase.String(),
Metadata: metadata,
InitParams: &initParams,
PowerShapingParams: &powerParams,
}, nil
}
79 changes: 70 additions & 9 deletions x/ccv/provider/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,6 @@ func TestQueryConsumerValidators(t *testing.T) {
res, err = pk.QueryConsumerValidators(ctx, &req)
require.NoError(t, err)
require.Equal(t, val1.Commission.Rate, res.Validators[0].ConsumerCommissionRate)

// set consumer to stopped phase
pk.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_STOPPED)
// expect empty valset
res, err = pk.QueryConsumerValidators(ctx, &req)
require.NoError(t, err)
require.Empty(t, res)
}

func TestQueryConsumerChainsValidatorHasToValidate(t *testing.T) {
Expand Down Expand Up @@ -444,8 +437,6 @@ func TestGetConsumerChain(t *testing.T) {
Top_N: topN,
ValidatorSetCap: validatorSetCaps[i],
ValidatorsPowerCap: validatorPowerCaps[i],
AllowInactiveVals: allowInactiveVals[i],
MinStake: minStakes[i].Uint64(),
})
pk.SetMinimumPowerInTopN(ctx, consumerID, expectedMinPowerInTopNs[i])
for _, addr := range allowlists[i] {
Expand Down Expand Up @@ -486,6 +477,76 @@ func TestGetConsumerChain(t *testing.T) {
}
}

func TestQueryConsumerChain(t *testing.T) {
providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

consumerId := "0"
chainId := "consumer-1"

req := types.QueryConsumerChainRequest{
ConsumerId: consumerId,
}

// expect error when consumer isn't associated with a chain id
_, err := providerKeeper.QueryConsumerChain(ctx, &req)
require.Error(t, err)

providerKeeper.SetConsumerChainId(ctx, consumerId, chainId)

// expect error when consumer doesn't have an owner address set
_, err = providerKeeper.QueryConsumerChain(ctx, &req)
require.Error(t, err)

providerKeeper.SetConsumerOwnerAddress(ctx, consumerId, providerKeeper.GetAuthority())

// expect error when consumer doesn't have a valid phase
_, err = providerKeeper.QueryConsumerChain(ctx, &req)
require.Error(t, err)

providerKeeper.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_REGISTERED)

// expect error when consumer doesn't have metadata
_, err = providerKeeper.QueryConsumerChain(ctx, &req)
require.Error(t, err)

providerKeeper.SetConsumerMetadata(ctx, consumerId, types.ConsumerMetadata{Name: chainId})

expRes := types.QueryConsumerChainResponse{
ChainId: chainId,
OwnerAddress: providerKeeper.GetAuthority(),
Metadata: types.ConsumerMetadata{Name: chainId},
Phase: types.ConsumerPhase_CONSUMER_PHASE_REGISTERED.String(),
InitParams: &types.ConsumerInitializationParameters{},
PowerShapingParams: &types.PowerShapingParameters{},
}

// expect no error when neither the consumer init and power shaping params are set
res, err := providerKeeper.QueryConsumerChain(ctx, &req)
require.NoError(t, err)
require.Equal(t, &expRes, res)

providerKeeper.SetConsumerInitializationParameters(
ctx,
consumerId,
types.ConsumerInitializationParameters{SpawnTime: ctx.BlockTime()},
)

providerKeeper.SetConsumerPowerShapingParameters(
ctx,
consumerId,
types.PowerShapingParameters{Top_N: uint32(50)},
)

expRes.InitParams = &types.ConsumerInitializationParameters{SpawnTime: ctx.BlockTime()}
expRes.PowerShapingParams = &types.PowerShapingParameters{Top_N: uint32(50)}

// expect no error
res, err = providerKeeper.QueryConsumerChain(ctx, &req)
require.NoError(t, err)
require.Equal(t, &expRes, res)
}

func TestQueryConsumerIdFromClientId(t *testing.T) {
providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()
Expand Down
Loading

0 comments on commit aec6c93

Please sign in to comment.