Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: store proposed chainID before voting finishes (#1289) #1338

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Add an entry to the unreleased provider section whenever merging a PR to main th
* (deps) [#1258](https://github.com/cosmos/interchain-security/pull/1258) Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.4).
* (deps!) [#1196](https://github.com/cosmos/interchain-security/pull/1196) Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0).
* `[x/ccv/provider]` (fix) [#1076](https://github.com/cosmos/interchain-security/pull/1076) Add `InitTimeoutTimestamps` and `ExportedVscSendTimestamps` to exported genesis.
* (feature) [#1282](https://github.com/cosmos/interchain-security/issues/1282) In the `ConsumerAdditionProposal`, consumer chainIDs proposed before the voting period finishes are now stored in the state. The gRPC query `/interchain_security/ccv/provider/proposed_consumer_chainids` and CLI command `query provider proposed-consumer-chains` can be used to retrieve this information.

## [Unreleased for Consumer]

Expand Down
9 changes: 7 additions & 2 deletions app/provider/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ func New(
AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
govConfig := govtypes.DefaultConfig()

app.GovKeeper = *govkeeper.NewKeeper(
govKeeper := govkeeper.NewKeeper(
appCodec,
keys[govtypes.StoreKey],
app.AccountKeeper,
Expand All @@ -455,7 +455,12 @@ func New(
)

// Set legacy router for backwards compatibility with gov v1beta1
app.GovKeeper.SetLegacyRouter(govRouter)
govKeeper.SetLegacyRouter(govRouter)

govHook := app.ProviderKeeper.GovHooks(govKeeper)
app.GovKeeper = *govKeeper.SetHooks(
govtypes.NewMultiGovHooks(govHook),
)

app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec,
Expand Down
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 @@ -81,6 +81,15 @@ service Query {
option (google.api.http).get =
"/interchain_security/ccv/provider/registered_consumer_reward_denoms";
}

// QueryProposedConsumerChainIDs query chainIDs in consumerAdditionProposals
// before voting period finishes, after voting period finishes, this chainID will be removed from the result
rpc QueryProposedConsumerChainIDs(
QueryProposedChainIDsRequest)
returns (QueryProposedChainIDsResponse) {
option (google.api.http).get =
"/interchain_security/ccv/provider/proposed_consumer_chains";
}
}

message QueryConsumerGenesisRequest { string chain_id = 1; }
Expand Down Expand Up @@ -187,3 +196,15 @@ message QueryRegisteredConsumerRewardDenomsRequest {}
message QueryRegisteredConsumerRewardDenomsResponse {
repeated string denoms = 1;
}

message QueryProposedChainIDsRequest {}

message QueryProposedChainIDsResponse {
repeated ProposedChain proposedChains = 1
[ (gogoproto.nullable) = false ];
}

message ProposedChain {
string chainID = 1;
uint64 proposalID = 2;
}
23 changes: 11 additions & 12 deletions tests/e2e/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,25 +395,25 @@
return tr
}

func (s *TestConfig) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag string) {
func (tr *TestRun) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag string) {

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 398 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun
if localSdkPath != "" {
fmt.Println("USING LOCAL SDK", localSdkPath)
}
if useGaia {
fmt.Println("USING GAIA INSTEAD OF ICS provider app", gaiaTag)
}

s.useGaia = useGaia
s.gaiaTag = gaiaTag
s.localSdkPath = localSdkPath
tr.useGaia = useGaia
tr.gaiaTag = gaiaTag
tr.localSdkPath = localSdkPath
}

func (s *TestConfig) SetCometMockConfig(useCometmock bool) {
s.useCometmock = useCometmock
func (tr *TestRun) SetCometMockConfig(useCometmock bool) {

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 411 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun
tr.useCometmock = useCometmock
}

func (s *TestConfig) SetRelayerConfig(useRly bool) {
s.useGorelayer = useRly
func (tr *TestRun) SetRelayerConfig(useRly bool) {

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 415 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun
tr.useGorelayer = useRly
}

// validateStringLiterals enforces that configs follow the constraints
Expand All @@ -423,9 +423,8 @@
// within the container will be named as "$CHAIN_ID-$VAL_ID-out" etc.
// where this name is constrained to 15 bytes or less. Therefore each string literal
// used as a validatorID or chainID needs to be 5 char or less.
func (s *TestConfig) validateStringLiterals() {
for valID, valConfig := range s.validatorConfigs {

func (tr *TestRun) validateStringLiterals() {

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 426 in tests/e2e/config.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun
for valID, valConfig := range tr.validatorConfigs {
if len(valID) > 5 {
panic("validator id string literal must be 5 char or less")
}
Expand All @@ -448,7 +447,7 @@
}
}

for chainID, chainConfig := range s.chainConfigs {
for chainID, chainConfig := range tr.chainConfigs {
if len(chainID) > 5 {
panic("chain id string literal must be 5 char or less")
}
Expand Down
28 changes: 28 additions & 0 deletions tests/e2e/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
type ChainState struct {
ValBalances *map[ValidatorID]uint
Proposals *map[uint]Proposal
ProposedConsumerChains *[]string
ValPowers *map[ValidatorID]uint
StakedTokens *map[ValidatorID]uint
Params *[]Param
Expand Down Expand Up @@ -132,6 +133,11 @@
chainState.Proposals = &proposals
}

if modelState.ProposedConsumerChains != nil {
proposedConsumerChains := tr.getProposedConsumerChains(chain)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / lint

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / lint

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / SonarCloud

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / lint

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / SonarCloud

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)

Check failure on line 137 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / SonarCloud

tr.getProposedConsumerChains undefined (type TestConfig has no field or method getProposedConsumerChains)
chainState.ProposedConsumerChains = &proposedConsumerChains
}

if modelState.ValPowers != nil {
tr.waitBlocks(chain, 1, 10*time.Second)
powers := tr.getValPowers(chain, *modelState.ValPowers)
Expand Down Expand Up @@ -772,3 +778,25 @@
verbosity := false
executeCommandWithVerbosity(cmd, "curlJsonRPCRequest", verbosity)
}

func (tr TestRun) getProposedConsumerChains(chain ChainID) []string {

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Cometmock_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Trace-Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / E2E_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / lint

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / Automated_Tests

undefined: TestRun

Check failure on line 782 in tests/e2e/state.go

View workflow job for this annotation

GitHub Actions / SonarCloud

undefined: TestRun
tr.waitBlocks(chain, 1, 10*time.Second)
//#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments.
bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName,
"query", "provider", "list-proposed-consumer-chains",
`--node`, tr.getQueryNode(chain),
`-o`, `json`,
).CombinedOutput()
if err != nil {
log.Fatal(err, "\n", string(bz))
}

arr := gjson.Get(string(bz), "proposedChains").Array()
chains := []string{}
for _, c := range arr {
cid := c.Get("chainID").String()
chains = append(chains, cid)
}

return chains
}
2 changes: 2 additions & 0 deletions tests/e2e/steps_start_chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint
Status: "PROPOSAL_STATUS_VOTING_PERIOD",
},
},
ProposedConsumerChains: &[]string{consumerName},
},
},
},
Expand Down Expand Up @@ -163,6 +164,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint
ValidatorID("bob"): 9500000000,
ValidatorID("carol"): 9500000000,
},
ProposedConsumerChains: &[]string{},
},
ChainID(consumerName): ChainState{
ValBalances: &map[ValidatorID]uint{
Expand Down
28 changes: 28 additions & 0 deletions x/ccv/provider/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func NewQueryCmd() *cobra.Command {
cmd.AddCommand(CmdThrottleState())
cmd.AddCommand(CmdThrottledConsumerPacketData())
cmd.AddCommand(CmdRegisteredConsumerRewardDenoms())
cmd.AddCommand(CmdProposedConsumerChains())

return cmd
}
Expand Down Expand Up @@ -93,6 +94,33 @@ func CmdConsumerChains() *cobra.Command {
return cmd
}

func CmdProposedConsumerChains() *cobra.Command {
cmd := &cobra.Command{
Use: "list-proposed-consumer-chains",
Short: "Query chainIDs in consumer addition proposal before voting finishes",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) (err error) {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

req := &types.QueryProposedChainIDsRequest{}
res, err := queryClient.QueryProposedConsumerChainIDs(cmd.Context(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

func CmdConsumerStartProposals() *cobra.Command {
cmd := &cobra.Command{
Use: "list-start-proposals",
Expand Down
93 changes: 93 additions & 0 deletions x/ccv/provider/keeper/gov_hook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package keeper

import (
"fmt"

"github.com/cosmos/gogoproto/proto"

sdk "github.com/cosmos/cosmos-sdk/types"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
sdkgov "github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"

"github.com/cosmos/interchain-security/v3/x/ccv/provider/types"
)

type GovHooks struct {
gk *govkeeper.Keeper
k *Keeper
}

// Implements GovHooks interface
// GovHooks exist in cosmos-sdk/x/gov/keeper/hooks.go of v0.45.16-lsm-ics and on
var _ sdkgov.GovHooks = GovHooks{}

func (k *Keeper) GovHooks(gk *govkeeper.Keeper) GovHooks {
return GovHooks{
gk: gk,
k: k,
}
}

// AfterProposalSubmission - call hook if registered
// After consumerAddition proposal submission, the consumer chainID is stored
func (gh GovHooks) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) {
p, ok := gh.gk.GetProposal(ctx, proposalID)
if !ok {
panic(fmt.Errorf("failed to get proposal %d in gov hook", proposalID))
}
msgs := p.GetMessages()

for _, msg := range msgs {
var msgLegacyContent v1.MsgExecLegacyContent
err := proto.Unmarshal(msg.Value, &msgLegacyContent)
if err != nil {
panic(fmt.Errorf("failed to unmarshal proposal content in gov hook: %w", err))
}

// if the consumer addition proposal cannot be unmarshaled, continue
var consAdditionProp types.ConsumerAdditionProposal
if err := proto.Unmarshal(msgLegacyContent.Content.Value, &consAdditionProp); err != nil {
continue
}

if consAdditionProp.ProposalType() == types.ProposalTypeConsumerAddition {
gh.k.SetProposedConsumerChain(ctx, consAdditionProp.ChainId, proposalID)
}
}
}

// AfterProposalVotingPeriodEnded - call hook if registered
// After proposal voting ends, the consumer chainID in store is deleted.
// When a proposal passes, this chainID will be available in providerKeeper.GetAllPendingConsumerAdditionProps
// or providerKeeper.GetAllConsumerChains(ctx).
func (gh GovHooks) AfterProposalVotingPeriodEnded(ctx sdk.Context, proposalID uint64) {
p, ok := gh.gk.GetProposal(ctx, proposalID)
if !ok {
panic(fmt.Errorf("failed to get proposal %d in gov hook", proposalID))
}
msgs := p.GetMessages()

for _, msg := range msgs {
var msgLegacyContent v1.MsgExecLegacyContent
err := proto.Unmarshal(msg.Value, &msgLegacyContent)
if err != nil {
panic(fmt.Errorf("failed to unmarshal proposal content in gov hook: %w", err))
}

var consAdditionProp types.ConsumerAdditionProposal
// if the proposal is not ConsumerAdditionProposal, return
if err := proto.Unmarshal(msgLegacyContent.Content.Value, &consAdditionProp); err != nil {
continue
}

if consAdditionProp.ProposalType() == types.ProposalTypeConsumerAddition {
gh.k.DeleteProposedConsumerChainInStore(ctx, proposalID)
}
}
}

func (gh GovHooks) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) {
}
func (gh GovHooks) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) {}
func (gh GovHooks) AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) {}
14 changes: 14 additions & 0 deletions x/ccv/provider/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,17 @@ func (k Keeper) QueryRegisteredConsumerRewardDenoms(goCtx context.Context, req *
Denoms: denoms,
}, nil
}

func (k Keeper) QueryProposedConsumerChainIDs(goCtx context.Context, req *types.QueryProposedChainIDsRequest) (*types.QueryProposedChainIDsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(goCtx)

chains := k.GetAllProposedConsumerChainIDs(ctx)

return &types.QueryProposedChainIDsResponse{
ProposedChains: chains,
}, nil
}
44 changes: 44 additions & 0 deletions x/ccv/provider/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,50 @@ func (k Keeper) DeleteChainToChannel(ctx sdk.Context, chainID string) {
store.Delete(types.ChainToChannelKey(chainID))
}

// SetProposedConsumerChain stores a consumer chainId corresponding to a submitted consumer addition proposal
// This consumer chainId is deleted once the voting period for the proposal ends
// does not end.
func (k Keeper) SetProposedConsumerChain(ctx sdk.Context, chainID string, proposalID uint64) {
store := ctx.KVStore(k.storeKey)
store.Set(types.ProposedConsumerChainKey(proposalID), []byte(chainID))
}

// GetProposedConsumerChain get the proposed chainID in consumerAddition proposal.
func (k Keeper) GetProposedConsumerChain(ctx sdk.Context, proposalID uint64) string {
store := ctx.KVStore(k.storeKey)
return string(store.Get(types.ProposedConsumerChainKey(proposalID)))
}

// DeleteProposedConsumerChainInStore deletes the consumer chainID from store
// which is in gov consumerAddition proposal
func (k Keeper) DeleteProposedConsumerChainInStore(ctx sdk.Context, proposalID uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.ProposedConsumerChainKey(proposalID))
}

// GetAllProposedConsumerChainIDs get consumer chainId in gov consumerAddition proposal before voting period ends.
func (k Keeper) GetAllProposedConsumerChainIDs(ctx sdk.Context) []types.ProposedChain {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, []byte{types.ProposedConsumerChainByteKey})
defer iterator.Close()

proposedChains := []types.ProposedChain{}
for ; iterator.Valid(); iterator.Next() {
proposalID, err := types.ParseProposedConsumerChainKey(types.ProposedConsumerChainByteKey, iterator.Key())
if err != nil {
panic(fmt.Errorf("proposed chains cannot be parsed: %w", err))
}

proposedChains = append(proposedChains, types.ProposedChain{
ChainID: string(iterator.Value()),
ProposalID: proposalID,
})

}

return proposedChains
}

// GetAllConsumerChains gets all of the consumer chains, for which the provider module
// created IBC clients. Consumer chains with created clients are also referred to as registered.
//
Expand Down
Loading
Loading